🚀 DICOM MCP Server - Medical Imaging AI Integration 🏥
Enables AI assistants to query, read, and move data on PACS using the standard Model Context Protocol (MCP), with Orthanc as the reference implementation. Integrated with FHIR and a mini - RIS DB.
🚀 Quick Start
📥 Installation
Install using pip by cloning the repository:
gh repo clone sscotti/dicom-mcp
cd dicom-mcp
python3 -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
⚙️ Configuration
dicom-mcp requires a YAML configuration file (configuration.yaml or similar) defining DICOM nodes and calling AE titles. Adapt the configuration or keep as is for compatibility with the sample ORTHANC Server.
nodes:
main:
host: "localhost"
port: 4242
ae_title: "ORTHANC"
description: "Local Orthanc DICOM server (Primary)"
secondary:
host: "localhost"
port: 4243
ae_title: "ORTHANC2"
description: "Local Orthanc DICOM server (Secondary)"
current_node: "main"
calling_aet: "MCPSCU"
fhir_servers:
firely:
base_url: "https://server.fire.ly"
description: "Firely FHIR Test Server (public, no API key needed)"
siim:
base_url: "https://hackathon.siim.org/fhir"
api_key: "${SIIM_API_KEY}"
description: "SIIM Hackathon FHIR server"
hapi_local:
base_url: "http://localhost:8080/fhir"
description: "Local HAPI FHIR server"
current_fhir: "hapi_local"
mini_ris:
host: "localhost"
port: 3306
user: "orthanc_ris_app"
password: "${MINI_RIS_DB_PASSWORD}"
database: "orthanc_ris"
pool_size: 5
⚠️ Important Note
DICOM - MCP is not meant for clinical use, and should not be connected with live hospital databases or databases with patient - sensitive data. Doing so could lead to both loss of patient data, and leakage of patient data onto the internet. DICOM - MCP can be used with locally hosted open - weight LLMs for complete data privacy.
💡 Usage Tip
This project uses MCP Jam for development, testing, and LLM integration needs. The mcp-config.example.json file is provided as a template with relative paths that you can adapt to your setup. That can be imported as JSON into MCPJAM to configure the interface.
Docker Container Setup (Orthancs, FHIR, PostGres and MySQL)
docker-compose up -d
dotenv run -- pytest
UI at https://localhost:8042 and https://localhost:8043, note that the repo is configured with TLS certs, so https.
HAPI FHIR will be available at http://localhost:8080/fhir
See FHIR Servers Guide for detailed configuration options including Firely test server and SIIM integration.
🔌 Using with MCP Jam
MCP Jam is the recommended tool for testing and exploring your DICOM MCP server. It offers an interface with Guest Mode for immediate testing without any setup. Although, if can also use something like the Cursor IDE after configured.
Start MCP Jam:
cd /path/to/dicom-mcp
source venv/bin/activate
npx -y @mcpjam/inspector@latest or npx -y @mcpjam/inspector@beta
Setup Server in MCP Jam:
- Click "Guest Mode" in the MCP Jam interface (no account required)
- Add Server Manually with these settings, or import
mcp-config.example.json as a template:
- Server Name:
DICOM MCP
- Command:
{path_to_venv}/bin/python (e.g., venv/bin/python or absolute path)
- Arguments:
-m dicom_mcp configuration.yaml --transport stdio
- Environment Variables:
- Name:
PYTHONPATH
- Value:
src (relative) or absolute path to src directory
- Working Directory: Path to your dicom-mcp project root
Example Configuration (macOS/Linux):
- Command:
/absolute/path/to/dicom-mcp/venv/bin/python
- Arguments:
-m dicom_mcp configuration.yaml --transport stdio
- Environment Variable:
PYTHONPATH = /absolute/path/to/dicom-mcp/src
MCP Jam Interface:
Configure LLM in MCP Jam:
- Go to the Settings tab
- Add your API keys for LLM providers:
- OpenAI - For GPT - 4, GPT - 4o, o1, etc.
- Anthropic - For Claude 3.5 Sonnet, Claude Opus, etc.
- Google Gemini - For Gemini 2.5 Pro, Flash, etc.
- Deepseek - For Deepseek Chat, Reasoner
- Ollama - Auto - detects local models (no API key needed)
- Go to the Playground tab to start chatting with your DICOM server
System Prompt:
For better LLM interactions, you can configure a system prompt in MCP Jam's Playground tab. A template is available in system_prompt.txt - copy it into the system prompt field when starting a new session.
Note: MCP Jam Guest Mode may not persist system prompts between sessions. Keep system_prompt.txt handy to copy - paste when needed.
MCP Jam Features:
- ✅ Guest Mode: No account required - start testing immediately
- ✅ Beautiful UI: Modern interface with AI provider logos
- ✅ Easy Setup: Simple server configuration with clear forms
- ✅ Real - time Testing: Interactive tool execution with immediate results
- ✅ Full Functionality: Access to all 11 DICOM tools
- ✅ LLM Playground: Test your DICOM server with various LLMs
- ✅ Community Driven: Active development with regular updates
MCP Jam Tabs:
- Servers Tab: Manage and connect to your DICOM MCP server
- Tools Tab: Browse and test all 11 DICOM tools interactively
- Playground Tab: Chat with your DICOM server using configured LLMs
- Settings Tab: Configure API keys and LLM providers
Available DICOM Tools:
verify_connection - Test DICOM connectivity
list_dicom_nodes - Show configured servers
query_patients - Search for patients
query_studies - Find studies by criteria
query_series - Locate series within studies
query_instances - Find individual DICOM images
extract_pdf_text_from_dicom - Extract text from DICOM PDFs
move_series / move_study - Transfer DICOM data
switch_dicom_node - Change active server
get_attribute_presets - Show query detail levels
Available FHIR Tools (when FHIR is configured):
verify_fhir_connection - Test FHIR server connectivity
list_fhir_servers - List configured FHIR servers
fhir_search_patient - Search for Patient resources
fhir_search_imaging_study - Search for ImagingStudy resources
fhir_read_resource - Read any FHIR resource by type and ID
fhir_create_resource - Create new FHIR resources (Patient, ImagingStudy, ServiceRequest, etc.)
fhir_update_resource - Update existing FHIR resources
See FHIR_SERVERS.md for configuration details.
Mini - RIS Tools (when MySQL is configured):
list_mini_ris_patients - Browse patient demographics stored in the mini - RIS schema (filter by MRN or name)
create_mwl_from_order - Create a DICOM Modality Worklist entry from an existing mini - RIS order
create_synthetic_cr_study - Generate synthetic CR DICOM images and send to PACS (virtual modality)
Radiology Reporting Tools (when MySQL is configured):
get_study_for_report - Retrieve complete study information for radiology reporting
list_radiologists - List available radiologists with credentials
create_radiology_report - Create structured radiology report with findings and impression
generate_report_pdf - Generate professional PDF from report (base64 encoded)
attach_report_to_pacs - Upload report PDF to PACS as DICOM Encapsulated PDF
Mini - RIS Database Schema:
The mini_ris.sql schema provides a complete radiology information system with:
- Core Entities: Patients, Providers, Encounters, Orders, Imaging Studies, Reports
- Reference Tables:
dicom_tags - 50 essential DICOM tag definitions for MWL/MPPS validation
procedures - 14 CR/XR procedure codes with typical views and image counts
modalities - Standard DICOM modality codes
body_parts - Anatomical regions for imaging
- MWL/MPPS Support: Tables for Modality Worklist and Modality Performed Procedure Step tracking
Setup:
- Launch the MySQL service:
docker compose up -d mysql
- Initialize the database (automatic on first start, or manually):
docker exec -i dicom-mcp-mysql-1 mysql -uorthanc_ris_app -porthanc_ris_app orthanc_ris < mysql/mini_ris.sql
- Configure environment variables in
.env:MINI_RIS_DB_PASSWORD=orthanc_ris_app
- Verify
configuration.yaml contains the mini_ris block.
Included CR Procedures:
The database includes 14 common Computed Radiography (CR) procedures optimized for single - image study workflows:
- Chest (1 or 2 views)
- Abdomen (1 or 2 views)
- Pelvis, Cervical/Lumbar Spine
- Upper Extremity: Hand, Wrist, Shoulder
- Lower Extremity: Knee, Ankle, Foot
- Skull
Each procedure includes typical view projections (AP, PA, Lateral, Oblique) and expected image counts for realistic test data generation.
MWL/MPPS Services:
The project includes integrated Modality Worklist (MWL) and Modality Performed Procedure Step (MPPS) services for managing imaging workflow:
- mwl - mpps (port 4104) - DICOM SCP for MWL queries and MPPS N - CREATE/N - SET operations
- mwl - api (port 8000) - FastAPI REST interface for creating and managing MWL entries from mini - RIS orders
Environment Variables:
Both services share the same MySQL database configuration via:
MINI_RIS_DB_PASSWORD=orthanc_ris_app
Usage:
- Start the MWL/MPPS services:
docker compose up -d mwl-mpps mwl-api
- Query worklist via DICOM C - FIND:
findscu -v -W -k 0008,0050="" -k 0010,0020="" localhost 4104
findscu -v -W -k 0008,0050="ACC-2025-0001" localhost 4104
- Create MWL entries via REST API:
curl -X POST http://localhost:8000/mwl/create_from_json \
-H "Content-Type: application/json" \
-d @mwl_payload.json
- View MWL records in web dashboard:
open http://localhost:8000/mwl
The MWL/MPPS tables (mwl, mpps, mwl_tasks) in the mini - RIS database store all worklist items and procedure step statuses, enabling full traceability from order to completed exam.
Creating MWLs from Orders (via MCP Tool):
The create_mwl_from_order tool automates MWL creation from mini - RIS orders:
create_mwl_from_order(
order_id=1,
scheduled_station_aet="ORTHANC"
)
{
"success": true,
"message": "MWL created successfully for order 1",
"accession_number": "ACC-2025-0001",
"patient_name": "Alex Johnson",
"patient_id": "MRN1001",
"procedure": "Chest X-Ray 2 Views",
"modality": "CR",
"scheduled_time": "2025-06-01 09:15:00",
"mwl_id": 42
}
This enables LLM - driven workflows like:
- "Create a worklist entry for order 1"
- "Patient MRN1001 has arrived, set up their chest x - ray"
- "List all scheduled orders and create MWLs for today's patients"
Virtual CR Device 🆕
The project includes a virtual CR (Computed Radiography) device that generates synthetic DICOM images for complete workflow demonstrations:
create_mwl_from_order(order_id=1)
create_synthetic_cr_study(
accession_number="ACC-2025-0001",
image_mode="simple",
send_to_pacs=True
)
Image Generation Modes:
simple (No API key required) - Basic synthetic images with anatomical outlines
ai (Requires OPENAI_API_KEY) - Realistic AI - generated images via OpenAI gpt - image - 1 model
auto (Default) - Uses AI if key available, falls back to simple
sample - Uses pre - made sample images from library
⚠️ Important Note:
- Synthetic images are for development/testing/training only. NOT for clinical use.
- AI mode uses OpenAI's
gpt - image - 1 model (~30 - 40 seconds per image)
- Multi - view studies (2+ images) may timeout in MCP clients but still complete successfully
- Images are created and sent to PACS even if you see a timeout error
- Check Orthanc to verify the images arrived
- For faster generation or reliable testing, use
image_mode="simple" instead of "auto"
Configuration:
Add to .env (optional for AI mode):
OPENAI_API_KEY=sk - proj - xxxxx
LLM - Driven Workflow Examples:
User: "Patient Johnson completed their chest x - ray, create the study"
LLM: Calls create_synthetic_cr_study(accession_number="ACC-2025-0001", image_mode="simple")
Result: 2 - view chest study appears in Orthanc instantly!
User: "Generate a realistic chest x - ray showing pneumonia in the right lung"
LLM: Calls with image_mode="ai", image_description="pneumonia right lower lobe"
Result: gpt - image - 1 generates photorealistic pneumonia appearance (~40 seconds)
Note: May show timeout error but images still arrive in PACS
This completes the full RIS/PACS workflow:
Order → MWL → Virtual Device → DICOM Images → PACS Storage → Viewing → Reporting
Radiology Reporting 🆕
Create professional radiology reports and attach them as DICOM Encapsulated PDFs to studies in your PACS:
study_info = get_study_for_report(accession_number="ACC-2025-0001")
radiologists = list_radiologists()
report = create_radiology_report(
accession_number="ACC-2025-0001",
findings="""
The heart is normal in size. The mediastinum is unremarkable.
Both lungs are clear without focal consolidation, pleural effusion, or pneumothorax.
No acute bony abnormality is identified.
""",
impression="Normal chest radiograph. No acute cardiopulmonary process.",
author_provider_id=3,
report_status="Final"
)
pdf_data = generate_report_pdf(report_id=report['report_id'])
result = attach_report_to_pacs(report_id=report['report_id'])
Report Workflow Features:
- Database Storage: Reports saved in mini - RIS
reports table with full audit trail
- Professional PDF: Generated with ReportLab (default) - institutional header, demographics, findings, impression, signature
- Alternative PDF Library: WeasyPrint is also installed as an option for HTML/CSS - based PDF generation (useful for web - based report templates)
- DICOM Standard: Encapsulated PDF (SOP Class:
1.2.840.10008.5.1.4.1.1.104.1)
- PACS Integration: PDF attached to original study as new series (Modality: DOC, Series #9999)
- Status Tracking: Preliminary → Final → Amended → Cancelled
- Provider Attribution: Links to radiologist in mini - RIS providers table
LLM - Driven Reporting Examples:
User: "Create a final report for accession ACC-2025-0001. Normal chest x - ray."
LLM: → get_study_for_report() to fetch patient/study data
→ list_radiologists() to get available radiologists
→ create_radiology_report() with structured findings/impression
→ attach_report_to_pacs() to send PDF to PACS
Result: Complete report in database + PDF in PACS!
User: "Generate a preliminary report for the knee study showing a tibial fracture"
LLM: → Creates report with report_status="Preliminary"
→ Structures findings describing the fracture
→ Generates and attaches PDF to PACS
Result: Preliminary report available for review
User: "Show me the PDF for report ID 5"
LLM: → generate_report_pdf(report_id=5)
→ Returns base64 PDF for display/download
Report Status Workflow:
Preliminary → Final → [Amended] → [Cancelled]
Each status change creates a new audit trail entry with timestamp.
Database Schema:
reports:
- report_id (PK)
- imaging_study_id (FK to imaging_studies)
- report_number (unique, e.g., "RPT-ACC-2025-0001-20250601120000")
- author_provider_id (FK to providers - radiologist)
- report_status (enum: Preliminary, Final, Amended, Cancelled)
- report_datetime (timestamp)
- report_text (LONGTEXT - findings)
- impression (TEXT - clinical impression)
- dicom_sop_instance_uid (populated after PACS attachment)
- dicom_series_instance_uid (populated after PACS attachment)
Complete Imaging + Reporting Workflow:
┌─────────────────────────────────────────────────────────┐
│ 1. Order Management (Mini-RIS) │
│ create_mwl_from_order(order_id=1) │
└────────────────┬────────────────────────────────────────┘
│
┌────────────────▼────────────────────────────────────────┐
│ 2. Image Acquisition (Virtual CR Device) │
│ create_synthetic_cr_study(accession="ACC-2025-0001") │
└────────────────┬────────────────────────────────────────┘
│
┌────────────────▼────────────────────────────────────────┐
│ 3. PACS Storage (Orthanc) │
│ Images viewable at http://localhost:8042 │
└────────────────┬────────────────────────────────────────┘
│
┌────────────────▼────────────────────────────────────────┐
│ 4. Radiology Reporting │
│ create_radiology_report(...) │
│ attach_report_to_pacs(report_id=1) │
└────────────────┬────────────────────────────────────────┘
│
┌────────────────▼────────────────────────────────────────┐
│ 5. Complete Study in PACS │
│ - CR Images (Series 1, 2) │
│ - Report PDF (Series 9999, Modality DOC) │
└─────────────────────────────────────────────────────────┘
🧪 Synthetic Data for Testing
To test orchestration workflows, populate your local HAPI FHIR server with synthetic data:
python tests/populate_synthetic_fhir_data.py
This creates:
- 5 test patients with realistic demographics
- ServiceRequests (orders) for imaging studies
- ImagingStudies linked to patients
- DiagnosticReports with findings
🔄 Orchestration Workflows
The MCP server enables end - to - end radiology workflows combining FHIR and DICOM:
- Order Entry: Create ServiceRequest in FHIR
- Study Acquisition: Link DICOM studies to FHIR ImagingStudies
- Reporting: Generate DiagnosticReports from DICOM PDFs
- Workflow Management: Track orders through completion
🔧 Development & Debugging
MCP Jam is the recommended tool for development, testing, and debugging your DICOM MCP server.
Development Workflow:
- Start Docker:
docker-compose up -d
- Load test data:
dotenv run -- pytest (uploads sample DICOM data)
- Start MCP Jam:
npx -y @mcpjam/inspector@latest or npx -y @mcpjam/inspector@beta
- Test tools: Use the Tools tab to test all DICOM operations interactively
- Test with LLMs: Use the Playground tab to test natural language interactions
- Debug issues: Check Server Notifications for errors and detailed logging
Benefits of MCP Jam for Development:
- ✅ Guest Mode - No account required, works immediately
- ✅ Real - time testing of all DICOM tools with immediate feedback
- ✅ Interactive interface for exploring DICOM data and responses
- ✅ LLM integration - Test how AI assistants interact with your server
- ✅ Debug logging - View detailed server notifications and errors
- ✅ Tool browser - Easily discover and test all available tools
✨ Features
dicom-mcp provides tools to:
- 🔍 Query Orthanc: Search for patients, studies, series, and instances using various criteria.
- 📄 Read DICOM Reports (PDF): Retrieve DICOM instances containing encapsulated PDFs (e.g., clinical reports) and extract the text content.
- 📄 Create RIS and DICOM Reports (PDF):: Create sample reports in PDF format.
- ➡️ Send DICOM Images: Send series or studies to other DICOM destinations, e.g. AI endpoints for image segmentation, classification, etc.
- ⚙️ Utilities: Manage connections and understand query options.
- ⚙️ FHIR methods:
- ⚙️ Mini - RIS:
- ⚙️ MWL server:
📄 License
This project is licensed under the MIT License - see the
for details.
🙏 Acknowledgments