Skip to main content

dicom-mcp: A DICOM Model Context Protocol Server

This repo is part of a blog post: Agentic Healthcare LLMs

Overview

A Model Context Protocol server for DICOM (Digital Imaging and Communications in Medicine) interactions. This server provides tools to query and interact with DICOM servers, enabling Large Language Models to access and analyze medical imaging metadata.

dicom-mcp allows AI assistants to query patient information, studies, series, and instances from DICOM servers using standard DICOM networking protocols. It also supports extracting text from encapsulated PDF documents stored in DICOM format, making it possible to analyze clinical reports. It's built on pynetdicom and follows the Model Context Protocol specification.

Tools

  1. list_dicom_nodes

    • Lists all configured DICOM nodes and calling AE titles
    • Inputs: None
    • Returns: Current node, available nodes, current calling AE title, and available calling AE titles
  2. switch_dicom_node

    • Switches to a different configured DICOM node
    • Inputs:
      • node_name (string): Name of the node to switch to
    • Returns: Success message
  3. switch_calling_aet

    • Switches to a different configured calling AE title
    • Inputs:
      • aet_name (string): Name of the calling AE title to switch to
    • Returns: Success message
  4. verify_connection

    • Tests connectivity to the configured DICOM node using C-ECHO
    • Inputs: None
    • Returns: Success or failure message with details
  5. query_patients

    • Search for patients matching specified criteria
    • Inputs:
      • name_pattern (string, optional): Patient name pattern (can include wildcards)
      • patient_id (string, optional): Patient ID
      • birth_date (string, optional): Patient birth date (YYYYMMDD)
      • attribute_preset (string, optional): Preset level of detail (minimal, standard, extended)
      • additional_attributes (string[], optional): Additional DICOM attributes to include
      • exclude_attributes (string[], optional): DICOM attributes to exclude
    • Returns: Array of matching patient records
  6. query_studies

    • Search for studies matching specified criteria
    • Inputs:
      • patient_id (string, optional): Patient ID
      • study_date (string, optional): Study date or range (YYYYMMDD or YYYYMMDD-YYYYMMDD)
      • modality_in_study (string, optional): Modalities in study
      • study_description (string, optional): Study description (can include wildcards)
      • accession_number (string, optional): Accession number
      • study_instance_uid (string, optional): Study Instance UID
      • attribute_preset (string, optional): Preset level of detail
      • additional_attributes (string[], optional): Additional DICOM attributes to include
      • exclude_attributes (string[], optional): DICOM attributes to exclude
    • Returns: Array of matching study records
  7. query_series

    • Search for series within a study
    • Inputs:
      • study_instance_uid (string): Study Instance UID (required)
      • modality (string, optional): Modality (e.g., "CT", "MR")
      • series_number (string, optional): Series number
      • series_description (string, optional): Series description
      • series_instance_uid (string, optional): Series Instance UID
      • attribute_preset (string, optional): Preset level of detail
      • additional_attributes (string[], optional): Additional DICOM attributes to include
      • exclude_attributes (string[], optional): DICOM attributes to exclude
    • Returns: Array of matching series records
  8. query_instances

    • Search for instances within a series
    • Inputs:
      • series_instance_uid (string): Series Instance UID (required)
      • instance_number (string, optional): Instance number
      • sop_instance_uid (string, optional): SOP Instance UID
      • attribute_preset (string, optional): Preset level of detail
      • additional_attributes (string[], optional): Additional DICOM attributes to include
      • exclude_attributes (string[], optional): DICOM attributes to exclude
    • Returns: Array of matching instance records
  9. get_attribute_presets

    • Lists available attribute presets for queries
    • Inputs: None
    • Returns: Dictionary of available presets and their attributes by level
  10. retrieve_instance

    • Retrieves a specific DICOM instance and saves it to the local filesystem
    • Inputs:
      • study_instance_uid (string): Study Instance UID
      • series_instance_uid (string): Series Instance UID
      • sop_instance_uid (string): SOP Instance UID
      • output_directory (string, optional): Directory to save the retrieved instance to (default: "./retrieved_files")
    • Returns: Dictionary with information about the retrieval operation
  11. extract_pdf_text_from_dicom

    • Retrieves a DICOM instance containing an encapsulated PDF and extracts its text content
    • Inputs:
      • study_instance_uid (string): Study Instance UID
      • series_instance_uid (string): Series Instance UID
      • sop_instance_uid (string): SOP Instance UID
    • Returns: Dictionary with extracted text information and status

Installation

Prerequisites

  • Python 3.12 or higher
  • A DICOM server to connect to (e.g., Orthanc, dcm4chee, etc.)

Using pip

Install via pip:

pip install dicom-mcp

Configuration

dicom-mcp requires a YAML configuration file that defines the DICOM nodes and calling AE titles. Create a configuration file with the following structure:

# DICOM nodes configuration
nodes:
  orthanc:
    host: "localhost"
    port: 4242
    ae_title: "ORTHANC"
    description: "Local Orthanc DICOM server"
  
  clinical:
    host: "pacs.hospital.org"
    port: 11112
    ae_title: "CLIN_PACS"
    description: "Clinical PACS server"

# Local calling AE titles
calling_aets:
  default:
    ae_title: "MCPSCU"
    description: "Default calling AE title"
  
  modality:
    ae_title: "MODALITY"
    description: "Simulating a modality"

# Currently selected node
current_node: "orthanc"

# Currently selected calling AE title
calling_aet: "default"

Usage

Command Line

Run the server using the script entry point:

dicom-mcp /path/to/configuration.yaml

If using uv:

uv run dicom-mcp /path/to/configuration.yaml

Configuration with Claude Desktop

Add this to your claude_desktop_config.json:

"mcpServers": {
  "dicom": {
    "command": "uv",
    "args": ["--directory", "/path/to/dicom-mcp", "run", "dicom-mcp", "/path/to/configuration.yaml"]
  }
}

Usage with Zed

Add to your Zed settings.json:

"context_servers": [
  "dicom-mcp": {
    "command": {
      "path": "uv",
      "args": ["--directory", "/path/to/dicom-mcp", "run", "dicom-mcp", "/path/to/configuration.yaml"]
    }
  }
],

Example Queries

List available DICOM nodes

list_dicom_nodes()

Switch to a different node

switch_dicom_node(node_name="clinical")

Switch to a different calling AE title

switch_calling_aet(aet_name="modality")

Verify connection

verify_connection()

Search for patients

# Search by name pattern (using wildcard)
patients = query_patients(name_pattern="SMITH*")

# Search by patient ID
patients = query_patients(patient_id="12345678")

# Get detailed information
patients = query_patients(patient_id="12345678", attribute_preset="extended")

Search for studies

# Find all studies for a patient
studies = query_studies(patient_id="12345678")

# Find studies within a date range
studies = query_studies(study_date="20230101-20231231")

# Find studies by modality
studies = query_studies(modality_in_study="CT")

Search for series in a study

# Find all series in a study
series = query_series(study_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.1")

# Find series by modality and description
series = query_series(
    study_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.1",
    modality="CT",
    series_description="CHEST*"
)

Search for instances in a series

# Find all instances in a series
instances = query_instances(series_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.2")

# Find a specific instance by number
instances = query_instances(
    series_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.2",
    instance_number="1"
)

Retrieve a DICOM instance

# Retrieve a specific instance
result = retrieve_instance(
    study_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.1",
    series_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.2",
    sop_instance_uid="1.2.840.10008.5.1.4.1.1.2.1.3",
    output_directory="./dicom_files"
)

Extract text from a DICOM encapsulated PDF

# Extract text from an encapsulated PDF
result = extract_pdf_text_from_dicom(
    study_instance_uid="1.2.840.10008.5.1.4.1.1.104.1.1",
    series_instance_uid="1.2.840.10008.5.1.4.1.1.104.1.2",
    sop_instance_uid="1.2.840.10008.5.1.4.1.1.104.1.3"
)

Debugging

You can use the MCP inspector to debug the server:

npx @modelcontextprotocol/inspector uv --directory /path/to/dicom-mcp run dicom-mcp /path/to/configuration.yaml

Development

Setup Development Environment

  1. Clone the repository:

    git clone https://github.com/yourusername/dicom-mcp.git
    cd dicom-mcp
    
  2. Create a virtual environment:

    python -m venv .venv
    source .venv/bin/activate  # On Windows: .venv\Scripts\activate
    
  3. Install dependencies:

    pip install -e .
    

Running Tests

The tests require a running Orthanc server. You can start one using Docker:

cd tests
docker-compose up -d

Then run the tests:

pytest tests/test_dicom_mcp.py

To test PDF extraction functionality:

pytest tests/test_dicom_pdf.py

Project Structure

  • src/dicom_mcp/: Main package
    • __init__.py: Package initialization
    • __main__.py: Entry point
    • server.py: MCP server implementation
    • dicom_client.py: DICOM client implementation
    • attributes.py: DICOM attribute presets
    • config.py: Configuration management with Pydantic

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Metadata

Release files for dicom-mcp 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dicom-mcp 0.1.1
File Size Uploaded
dicom_mcp-0.1.1.tar.gz 24.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dicom-mcp 0.1.1
File Interpreter ABI Platform
dicom_mcp-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 41.8 kB

Release files / dicom_mcp-0.1.1.tar.gz

Download URL dicom_mcp-0.1.1.tar.gz
Size 24.2 kB
Tags Source
SHA-256 checksum
How to use checksums
93aea35f09314344460c2284ec1c93ed12e64d3bea625a69f9667fd10c1490c2
BLAKE2b-256 checksum
How to use checksums
0f3db63da5dc599ad501947a9ab1689cb1e257a27e1c4d303b7e8ca30c5ed12f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 28, 2025.

Transparency log

Release files / dicom_mcp-0.1.1-py3-none-any.whl

Download URL dicom_mcp-0.1.1-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ddcdf8ded8d5008847fc3a35d76fc1d634e351fc042e80b9c7210ba59e2c34b
BLAKE2b-256 checksum
How to use checksums
baff02e0d16a54495e566b1da1d7a7773ed5cd3d1fa7681e15d4822125649cc5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 28, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page