scan-dicom-directory
Scan directories to find and organize DICOM medical image files into structured series for analysis and management.
Instructions
Scan a directory for DICOM files and organize them into series
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| directory | Yes | Path to directory containing DICOM files |
Implementation Reference
- src/dicom_mcp/server.py:258-279 (handler)MCP tool handler for 'scan-dicom-directory': validates directory, calls scan_directory helper, stores series in global state, notifies clients of resource changes, and returns summary of found series.elif name == "scan-dicom-directory": directory = arguments.get("directory") if not directory or not os.path.isdir(directory): raise ValueError(f"Invalid directory: {directory}") # Scan the directory for DICOM files series_list = scan_directory(directory) # Update state with found series for series in series_list: dicom_data[series.series_uid] = series # Notify clients that resources have changed await server.request_context.session.send_resource_list_changed() return [ types.TextContent( type="text", text=f"Found {len(series_list)} DICOM series in {directory}:\n" + "\n".join([f"- {s.modality or 'Unknown'}: {s.description or s.series_uid} ({s.file_count} files)" for s in series_list]) ) ]
- src/dicom_mcp/server.py:166-176 (registration)Registration of the 'scan-dicom-directory' tool in handle_list_tools(), including description and JSON input schema requiring 'directory' path.types.Tool( name="scan-dicom-directory", description="Scan a directory for DICOM files and organize them into series", inputSchema={ "type": "object", "properties": { "directory": {"type": "string", "description": "Path to directory containing DICOM files"}, }, "required": ["directory"], }, ),
- src/dicom_mcp/dicom_tools.py:38-47 (schema)Pydantic model (schema) for DicomSeries used as return type for scan_directory and stored in server state.class DicomSeries(BaseModel): """Model representing a DICOM series""" series_uid: str study_uid: Optional[str] = None modality: str description: Optional[str] = None path: str file_count: int patient_id: Optional[str] = None
- src/dicom_mcp/dicom_tools.py:73-116 (helper)Core helper function that scans directory recursively for DICOM files using glob and pydicom, groups by SeriesInstanceUID, extracts metadata, and returns list of DicomSeries objects.def scan_directory(directory: str) -> List[DicomSeries]: """Scan a directory for DICOM files and organize them into series""" series_dict = {} # Find all DICOM files (recursively if needed) dicom_files = [] for ext in [".dcm", ".DCM", ""]: # Empty string for no extension files dicom_files.extend(glob.glob(os.path.join(directory, f"**/*{ext}"), recursive=True)) for file_path in dicom_files: try: ds = pydicom.dcmread(file_path, stop_before_pixels=True) series_uid = ds.SeriesInstanceUID if series_uid not in series_dict: series_dict[series_uid] = { "files": [], "study_uid": getattr(ds, "StudyInstanceUID", None), "modality": getattr(ds, "Modality", "Unknown"), "description": getattr(ds, "SeriesDescription", None), "patient_id": getattr(ds, "PatientID", None) } series_dict[series_uid]["files"].append(file_path) except Exception as e: print(f"Error reading {file_path}: {e}") # Convert to DicomSeries objects result = [] for series_uid, data in series_dict.items(): # Use the directory of the first file as the series path series_path = os.path.dirname(data["files"][0]) if data["files"] else "" result.append(DicomSeries( series_uid=series_uid, study_uid=data["study_uid"], modality=data["modality"], description=data["description"], path=series_path, file_count=len(data["files"]), patient_id=data["patient_id"] )) return result