# DICOM MCP Server — TODO Two remaining items. The original four-item enhancement plan (2026-02-11) has been completed — `dicom_query` and `dicom_search` were implemented, along with four additional tools (`dicom_dump_tree`, `dicom_compare_uids`, `dicom_verify_segmentations`, `dicom_analyze_ti`). The items below are follow-on improvements identified during testing. --- ## 1. Private Tag Exploration Tool (`dicom_private_tags`) **Priority:** High — this is the trickiest to get right but the most valuable for cross-manufacturer QA. ### Problem Manufacturers store critical acquisition parameters in private (vendor-specific) DICOM tags rather than standard public tags. This causes real issues in multi-vendor QA workflows: - **Philips TE=0 quirk:** The Erasmus Achieva 1.5T dataset shows `EchoTime = 0` for several Dixon series (Body mDixon THRIVE, Thigh Dixon Volume). The actual multi-point Dixon echo times are stored in Philips private tags, not the standard `(0018,0081)` EchoTime field. This was confirmed via `dicom_query` grouped by SeriesDescription on the Erasmus dataset — 328 of 648 Thigh Dixon files and 100 of 157 mDixon THRIVE files report TE=0. - **Manufacturer encoding differences:** Siemens stores echo times in public tags normally (e.g. MOST series TEs of 2.38–19.06 ms on Avanto_fit). Philips MOST TEs (2.371–18.961 ms) are in public tags too, but Dixon TEs are hidden in private tags. GE embeds Dixon image type info in `ImageType` fields rather than series descriptions. - **Nested sequences and binary blobs:** Philips private tags frequently contain nested DICOM sequences, and some values are only interpretable if you know the specific software version. Binary data needs special handling to avoid dumping unreadable content. ### Discussion Notes From our initial conversation, we decided **not** to implement this tool immediately because: 1. Deciphering some private tags requires conditional logic based on the contents of certain public tags (or other private tags). The exact rules are manufacturer-specific and need to be rediscovered through hands-on exploration. 2. Building the wrong abstraction would be worse than no abstraction — we need to tinker with real data first before committing to a tool design. ### Proposed Design (Single tool with three modes) **`discover` mode** — Scan a file and list all private tag blocks with their creator strings. Answers "what vendor modules are present?" Output: group number, creator string, tag count per block. **`dump` mode** — Show all private tags within a specific creator block (or all private tags in a file). For each tag: hex address, creator, VR, value. Binary values show first N bytes as hex + length. Nested sequences show item count with optional one-level-deep recursion. **`search` mode** — Scan across a directory looking for private tags matching a keyword in either the creator string or the tag value. Useful for hunting down where manufacturers hide specific parameters (e.g. "find any private tag with 'echo' in the creator or value"). ### Additional Considerations - **Creator filtering:** Filter by creator substring, e.g. `creator="Philips"` to only see Philips blocks. - **Known tag dictionaries:** Embed a small lookup table for commonly useful private tags (e.g. Philips `(2005,xx10)` for actual echo times). Start without this and add later. - **Binary value display:** Show first 64 bytes as hex + total length, rather than full dumps. ### Suggested Next Steps 1. Start by exploring the Erasmus Philips data with `dicom_get_metadata` using custom hex tags to see what private blocks exist and specifically chase down the TE=0 mystery. 2. Do the same on Siemens and GE data to understand the differences. 3. Once the patterns and conditional logic are clear, design the tool around real use cases. --- ## 2. `dicom_compare_headers` Directory Mode **Priority:** Medium — useful for cross-series protocol checks but less urgent than private tags. ### Problem `dicom_compare_headers` currently requires 2–10 explicit file paths. For cross-series protocol validation (e.g. "are all MOST series using the same TR/FA across a study?"), you have to manually pick representative files from each series first. ### Proposed Enhancement Add a **directory mode** that automatically picks one representative file per series and compares them. This would enable single-call cross-series protocol checks. ### Design Ideas - New parameter: `directory` as an alternative to `file_paths` - Auto-select one file per unique SeriesInstanceUID (first file encountered, or configurable) - Reuse existing comparison logic - Show series description in output to identify which series each column represents - Optionally filter which series to include (by description pattern or sequence type) --- *Last updated: 2026-02-25 — after adding 4 new tools (dicom_dump_tree, dicom_compare_uids, dicom_verify_segmentations, dicom_analyze_ti) and smoke testing against Philips, Siemens, and GE MOLLI/NOLLI data.*