scan-dicom-directory
Scan and organize DICOM files within a specified directory into series for efficient medical image management using the DICOM-MCP server.
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)Executes the tool: validates input directory, invokes scan_directory helper, stores series in global state, notifies clients of resource changes, and returns a text 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)Registers the tool with the MCP server in list_tools(), defining name, description, and input schema requiring a 'directory' string.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/server.py:169-176 (schema)JSON schema for tool input: object with required 'directory' property (string path).inputSchema={ "type": "object", "properties": { "directory": {"type": "string", "description": "Path to directory containing DICOM files"}, }, "required": ["directory"], }, ),
- src/dicom_mcp/dicom_tools.py:73-116 (helper)Core helper function: recursively finds DICOM files via glob, reads metadata with pydicom (stop_before_pixels), groups by SeriesInstanceUID, constructs 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
- src/dicom_mcp/dicom_tools.py:38-47 (helper)Pydantic BaseModel defining the data structure for each DICOM series, used by scan_directory to represent grouped series info.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