{"id":"8be2191d-cf73-4d41-a3dd-daec022acc5c","slug":"nightowl","kind":"mcp","name":"nightowl","summary":"A tool for testing DICOM services","owner":"aurabx","repoUrl":"https://github.com/aurabx/nightowl","license":"MIT","licenseTier":"permissive","trust":"community","stars":3,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-05-26T22:20:34.000Z","addedAt":"2026-10-21T17:26:56.817Z","logoUrl":"https://avatars.githubusercontent.com/u/88016457?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools"],"tags":[],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T03:39:10.367Z","sample":false,"url":"https://conduits.dev/tools/nightowl","language":"Rust","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# NightOwl\n\nNightOwl is a desktop tool for exercising the DICOM network protocol in\nboth directions. It listens for inbound DICOM associations, sends DIMSE\nrequests to remote peers from a GUI, and exposes the same surface as\nModel Context Protocol (MCP) tools and a command-line driver so external\nclients — including LLMs — can drive it programmatically.\n\nNightOwl is a developer and integration-testing tool. It is not a\nclinical product, makes no compliance claims, and ships without\ntransport security or authentication. Use it on a trusted local network\nor behind a firewall.\n\nProduct page: <https://aurabox.cloud/nightowl>.\n\n## What you can do with it\n\nNightOwl combines five capabilities behind a single sidebar UI:\n\n1. A **DICOM SCP** that accepts inbound associations on a configurable\n   TCP port and AE Title.\n2. A **DICOM SCU** UI for sending C-ECHO, C-FIND, C-MOVE, and C-STORE to\n   configured peers.\n3. A **local SOP Instance store** — a directory on disk indexed in\n   SQLite — that behaves like a tiny PACS: received instances are\n   written there, and inbound C-FIND, C-MOVE, and C-GET are answered\n   from the same index.\n4. A **Modality Worklist (DMWL) provider** with CRUD over scheduled\n   procedure steps and a C-FIND responder on the DMWL information\n   model.\n5. A **persistent activity log** that records every association and\n   every DIMSE message, streamed live to the UI.\n\n## Install and launch\n\nNightOwl is built and released for macOS, Windows, and Linux from\nGitHub. Download the installer for your platform from the latest\nrelease:\n\n- **macOS** — `.dmg` (minimum macOS 12.0). Drag NightOwl into\n  Applications and launch it like any other desktop app.\n- **Windows** — `.msi` or `.exe` installer. Run it and launch NightOwl\n  from the Start menu.\n- **Linux** — `.AppImage` or `.deb`. Make the AppImage executable and\n  run it, or install the `.deb` with `apt`.\n\nOn first launch, NightOwl creates its configuration directory in the\nplatform's standard app-data location and a default store directory at\n`~/dicom-store` (or the equivalent on Windows). The defaults are:\n\n- Local AE Title: `NIGHTOWL`\n- DICOM listen port: `11112`\n- Store directory: `~/dicom-store`\n- MCP server: disabled\n\nOpen the **Settings** page to change the AE Title, listen port, or\nstore directory. Changes apply immediately — the DICOM listener is\nrebound in place, with a test bind first so a bad port surfaces as an\nerror rather than leaving the app without a listener.\n\n## Using the UI\n\nThe sidebar has eight pages:\n\n- **Peers** — Add, edit, and remove remote DICOM nodes. Each peer has\n  a Name, AE Title, Host, and Port. Peers are referenced by name on\n  the SCU page and by id from the CLI and MCP tools.\n- **SCU** — Pick a peer, pick an operation (Echo, Find, Move, Store),\n  fill in the form, and run. The result panel shows status, elapsed\n  time, and per-operation details (matched rows for Find, per-file\n  outcomes for Store, and so on).\n- **Activity** — Live, paginated, filterable view of every DIMSE\n  event. Filter by direction (inbound / outbound / info), status,\n  peer AE Title, command, association id, free-text, or\n  since-timestamp. New events appear without polling.\n- **Store** — Browse the local SOP Instance index as Patient → Study →\n  Series → SOP Instance. Refreshes automatically when a background\n  scan finishes; a manual rescan button is also available.\n- **Worklist** — CRUD for Modality Worklist scheduled procedure step\n  entries served by the DMWL C-FIND responder.\n- **MCP** — Enable or disable the local MCP server, set its port, see\n  the live runtime status, and copy a ready-made configuration\n  snippet (including a `claude mcp add` one-liner for Claude Code).\n- **Settings** — Local AE Title, listen port, store directory.\n- **About** — Version and a link to the product page.\n\n### DICOM capabilities\n\nAs an SCP, NightOwl negotiates Verification, Patient Root and Study\nRoot Query/Retrieve (Find, Move, Get), Modality Worklist Find, and the\nfollowing storage SOP classes: CT, MR, Secondary Capture, Ultrasound,\nComputed Radiography, Digital X-Ray (For Presentation), and\nEncapsulated PDF. Transfer syntaxes offered on every association are\nImplicit VR Little Endian, Explicit VR Little Endian, and JPEG\nBaseline 8-bit.\n\nAs an SCU, NightOwl can send C-ECHO, C-FIND (Patient Root or Study\nRoot at Patient / Study / Series / Image level, with wildcard, UID\nlist, and date-range matching), C-MOVE, and C-STORE. C-GET as SCU is\nnot implemented in the current iteration.\n\n## MCP server\n\nNightOwl can expose a curated subset of its capabilities as MCP tools\nover HTTP on the loopback interface. The MCP server is disabled by\ndefault. Enable it from the **MCP** page, set a port (default `7300`),\nand the server starts immediately on `http://127.0.0.1:<port>/mcp`\nusing the streamable HTTP transport.\n\nThe MCP server binds only to `127.0.0.1` and has no authentication;\nit is intended for local use by a client running on the same machine.\n\n### Connecting Claude Code\n\nThe MCP page shows a ready-to-copy `claude mcp add` command. Run it\nin a terminal and Claude Code will connect to NightOwl as a tool\nprovider.\n\n### Tools exposed\n\nRead tools:\n\n| Tool                        | Purpose                                         |\n|-----------------------------|-------------------------------------------------|\n| `get_config`                | Local AE Title, listen port, store directory.   |\n| `list_peers`                | Configured remote DICOM peers.                  |\n| `list_studies`              | Studies in the local store.                     |\n| `list_series_for_study`     | Series within a study.                          |\n| `list_instances_for_series` | SOP Instances within a series.                  |\n| `count_instances`           | Instance count across the store.                |\n| `rescan_store`              | Trigger a background rescan of the store dir.   |\n| `read_dicom_file`           | Read a DICOM Part-10 file's full element set.   |\n| `list_worklist`             | Scheduled procedure step entries.               |\n| `list_activity`             | Filterable, paginated activity log.             |\n| `count_activity`            | Activity row count.                             |\n\nPeer management tools:\n\n| Tool           | Purpose                                               |\n|----------------|--------------------------------------------------------|\n| `create_peer`  | Add a new configured remote DICOM peer.                |\n| `update_peer`  | Edit an existing peer's name, AE Title, host or port.  |\n| `delete_peer`  | Remove a configured peer.                              |\n\nActive SCU tools:\n\n| Tool         | Purpose                                                 |\n|--------------|---------------------------------------------------------|\n| `scu_echo`   | Verification ping against a configured peer.            |\n| `scu_find`   | C-FIND against a peer at the chosen query level.        |\n| `scu_move`   | Ask a peer to forward matching instances elsewhere.     |\n| `scu_store`  | Send one or more local DICOM files to a peer.           |\n\nEvery tool input is declared as JSON Schema, so any spec-compliant MCP\nclient sees a typed surface.\n\n## Command-line driver\n\n`nightowl-cli` mirrors the MCP tool set as a local command-line driver.\nIt opens the same SQLite databases and `config.json` the desktop app\nuses (SQLite runs in WAL mode, so concurrent access from the app and\nthe CLI is safe) and calls the same business-logic functions\nin-process. There is no IPC step.\n\nThe desktop binary *is* the CLI: when it is invoked under the name\n`nightowl-cli` it dispatches to the command surface instead of opening a\nwindow. There is no separate download — installing NightOwl installs the\nCLI too.\n\n### Installing the CLI\n\nOpen NightOwl and go to the **Command Line** tab in the sidebar, then\nclick **Install**. This is the only step.\n\n- **macOS / Linux** — NightOwl creates a `nightowl-cli` symlink in\n  `/usr/local/bin` (when writable) or `~/.local/bin`, pointing at the\n  app binary. If it lands in `~/.local/bin` and that directory is not on\n  your `PATH`, the tab tells you the one line to add to your shell\n  profile. Open a new terminal and run `nightowl-cli --help` to confirm.\n- **Windows** — NightOwl ships a console `nightowl-cli.exe` next to the\n  desktop binary. **Install** copies it into\n  `%LOCALAPPDATA%\\Programs\\NightOwl\\bin\\` and prepends that directory to\n  your user `PATH` (no admin rights needed). Open a *new* terminal\n  afterwards — already-open shells keep the `PATH` they started with.\n\nTo remove the command, click **Uninstall** on the same tab. It only\nremoves a `nightowl-cli` entry that points at the NightOwl binary; a\n`nightowl-cli` that resolves elsewhere is left untouched.\n\n### Global flags\n\n- `--data-dir <path>` — Override the data directory. Defaults to the\n  platform's app config directory for the NightOwl bundle (the same\n  path the desktop app uses).\n- `--json` — Emit results as pretty-printed JSON, matching the shape\n  the MCP server returns. Without it, results are human-readable.\n- `-v` / `--verbose` — Raise log verbosity. `-v` for info, `-vv` for\n  debug. Default is errors only.\n\n### Exit codes\n\n- `0` — success.\n- `1` — runtime failure (IO, database, DICOM).\n- `2` — validation failure (bad arguments, unknown peer id).\n\n### Top-level commands\n\n| Command                | Effect                                              |\n|------------------------|-----------------------------------------------------|\n| `config show`          | Print the effective NightOwl configuration.         |\n| `peers list`           | List configured remote DICOM peers.                 |\n| `studies list`         | List studies in the local store.                    |\n| `studies series <uid>` | List series for a study.                            |\n| `series instances <uid>` | List instances for a series.                      |\n| `instances count`      | Count instances across the store.                   |\n| `store rescan`         | Trigger a rescan of the store directory.            |\n| `worklist list`        | List scheduled procedure step entries.              |\n| `activity list`        | Read the activity log (filters available).          |\n| `activity count`       | Count rows in the activity log.                     |\n| `scu echo <peer-id>`   | Verification ping against a peer.                   |\n| `scu find …`           | C-FIND against a peer.                              |\n| `scu move …`           | C-MOVE against a peer.                              |\n| `scu store …`          | C-STORE one or more local DICOM files to a peer.    |\n\nRun `nightowl-cli --help` or `nightowl-cli <command> --help` for the\nfull flag set on each subcommand.\n\n### Examples\n\nPing a peer by id:\n\n```\nnightowl-cli scu echo my-pacs\n```\n\nList studies as JSON for piping into `jq`:\n\n```\nnightowl-cli --json studies list\n```\n\nSearch the activity log for outbound C-STORE attempts in the last hour:\n\n```\nnightowl-cli activity list --direction outbound --command C-STORE\n```\n\nSend a directory of DICOM files to a peer:\n\n```\nnightowl-cli scu store --peer my-pacs --path ~/scans/study-001\n```\n\n## Where state lives\n\nAll persistent state lives in the platform-specific app config\ndirectory:\n\n- **macOS** — `~/Library/Application Support/cloud.aurabox.nightowl/`\n- **Linux** — `~/.config/cloud.aurabox.nightowl/` (or\n  `$XDG_CONFIG_HOME` if set)\n- **Windows** — `%APPDATA%\\cloud.aurabox.nightowl\\`\n\n| File              | Purpose                                              |\n|-------------------|------------------------------------------------------|\n| `config.json`     | AE Title, listen port, store directory, MCP block.   |\n| `peers.json`      | List of remote DICOM peers.                          |\n| `store.sqlite`    | SOP Instance index and activity log.                 |\n| `worklist.sqlite` | Modality Worklist scheduled procedure step entries.  |\n\nThe store directory itself defaults to `~/dicom-store`. NightOwl\nscans, writes to, and answers Q/R requests from that directory.\n\n## Limitations\n\n- No TLS and no authentication on the DICOM listener or the MCP\n  server. The SCP listens on every interface; use only on a trusted\n  local network or behind a firewall.\n- Not a clinical product. NightOwl makes no regulatory or compliance\n  claims.\n- C-GET as SCU is not implemented. C-GET as SCP is.\n- Storage SOP classes are limited to the set listed above.\n\n## License\n\nSee [LICENSE](LICENSE).\n"}