D
Dicom
community
search
An MCP server to query and retrieve medical images and for parsing and reading dicom-encapsulated documents (pdf etc.).
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
-
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
-
switch_dicom_node
- Switches to a different configured DICOM node
- Inputs:
(string): Name of the node to switch tonode_name
- Returns: Success message
-
switch_calling_aet
- Switches to a different configured calling AE title
- Inputs:
(string): Name of the calling AE title to switch toaet_name
- Returns: Success message
-
verify_connection
- Tests connectivity to the configured DICOM node using C-ECHO
- Inputs: None
- Returns: Success or failure message with details
-
query_patients
- Search for patients matching specified criteria
- Inputs:
(string, optional): Patient name pattern (can include wildcards)name_pattern
(string, optional): Patient IDpatient_id
(string, optional): Patient birth date (YYYYMMDD)birth_date
(string, optional): Preset level of detail (minimal, standard, extended)attribute_preset
(string[], optional): Additional DICOM attributes to includeadditional_attributes
(string[], optional): DICOM attributes to excludeexclude_attributes
- Returns: Array of matching patient records
-
query_studies
- Search for studies matching specified criteria
- Inputs:
(string, optional): Patient IDpatient_id
(string, optional): Study date or range (YYYYMMDD or YYYYMMDD-YYYYMMDD)study_date
(string, optional): Modalities in studymodality_in_study
(string, optional): Study description (can include wildcards)study_description
(string, optional): Accession numberaccession_number
(string, optional): Study Instance UIDstudy_instance_uid
(string, optional): Preset level of detailattribute_preset
(string[], optional): Additional DICOM attributes to includeadditional_attributes
(string[], optional): DICOM attributes to excludeexclude_attributes
- Returns: Array of matching study records
-
query_series
- Search for series within a study
- Inputs:
(string): Study Instance UID (required)study_instance_uid
(string, optional): Modality (e.g., "CT", "MR")modality
(string, optional): Series numberseries_number
(string, optional): Series descriptionseries_description
(string, optional): Series Instance UIDseries_instance_uid
(string, optional): Preset level of detailattribute_preset
(string[], optional): Additional DICOM attributes to includeadditional_attributes
(string[], optional): DICOM attributes to excludeexclude_attributes
- Returns: Array of matching series records
-
query_instances
- Search for instances within a series
- Inputs:
(string): Series Instance UID (required)series_instance_uid
(string, optional): Instance numberinstance_number
(string, optional): SOP Instance UIDsop_instance_uid
(string, optional): Preset level of detailattribute_preset
(string[], optional): Additional DICOM attributes to includeadditional_attributes
(string[], optional): DICOM attributes to excludeexclude_attributes
- Returns: Array of matching instance records
-
get_attribute_presets
- Lists available attribute presets for queries
- Inputs: None
- Returns: Dictionary of available presets and their attributes by level
-
retrieve_instance
- Retrieves a specific DICOM instance and saves it to the local filesystem
- Inputs:
(string): Study Instance UIDstudy_instance_uid
(string): Series Instance UIDseries_instance_uid
(string): SOP Instance UIDsop_instance_uid
(string, optional): Directory to save the retrieved instance to (default: "./retrieved_files")output_directory
- Returns: Dictionary with information about the retrieval operation
-
extract_pdf_text_from_dicom
- Retrieves a DICOM instance containing an encapsulated PDF and extracts its text content
- Inputs:
(string): Study Instance UIDstudy_instance_uid
(string): Series Instance UIDseries_instance_uid
(string): SOP Instance UIDsop_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 current_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
-
Clone the repository:
git clone https://github.com/yourusername/dicom-mcp.git cd dicom-mcp
-
Create a virtual environment:
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
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
: Main packagesrc/dicom_mcp/
: Package initialization__init__.py
: Entry point__main__.py
: MCP server implementationserver.py
: DICOM client implementationdicom_client.py
: DICOM attribute presetsattributes.py
: Configuration management with Pydanticconfig.py
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built on pynetdicom
- Follows the Model Context Protocol specification
- Uses PyPDF2 for PDF text extraction
Related Servers
Aiven
official
Navigate your [Aiven projects](https://go.aiven.io/mcp-server) and interact with the PostgreSQL®, Apache Kafka®, ClickHouse® and OpenSearch® services
View DetailsApify
official
[Actors MCP Server](https://apify.com/apify/actors-mcp-server): Use 3,000+ pre-built cloud tools to extract data from websites, e-commerce, social media, search engines, maps, and more
View Details