Skip to main content
Glama

load-dicom-series

Load DICOM medical image series into memory using Series UID for processing in the DICOM-MCP server system.

Instructions

Load a DICOM series into memory for processing

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
series_uidYesSeries UID of the DICOM series to load

Implementation Reference

  • The handler function for the 'load-dicom-series' tool within the @server.call_tool() dispatcher. It validates the series_uid argument, retrieves the corresponding DicomSeries from dicom_data, loads the image data using the load_dicom_image helper, caches the numpy array and metadata, computes shape and intensity range, and returns a text content summary.
    elif name == "load-dicom-series":
        series_uid = arguments.get("series_uid")
        if not series_uid or series_uid not in dicom_data:
            raise ValueError(f"Invalid or unknown series UID: {series_uid}")
            
        series = dicom_data[series_uid]
        
        # Load the DICOM series
        image_array, metadata = load_dicom_image(series.path)
        
        # Cache the loaded data
        dicom_cache[series_uid] = {
            "image": image_array,
            "metadata": metadata
        }
        
        # Return summary information
        shape = image_array.shape
        intensity_range = (float(image_array.min()), float(image_array.max()))
        
        return [
            types.TextContent(
                type="text",
                text=f"Loaded DICOM series {series_uid}\n" +
                     f"Shape: {shape}\n" +
                     f"Intensity range: {intensity_range}\n" +
                     f"Metadata: {json.dumps(metadata, indent=2, default=str)}"
            )
        ]
  • The tool registration in the @server.list_tools() handler, defining the tool name, description, and input JSON schema requiring 'series_uid'.
    types.Tool(
        name="load-dicom-series",
        description="Load a DICOM series into memory for processing",
        inputSchema={
            "type": "object",
            "properties": {
                "series_uid": {"type": "string", "description": "Series UID of the DICOM series to load"},
            },
            "required": ["series_uid"],
        },
    ),
  • Helper function that performs the actual DICOM series loading using ITK to read the series directory into a 3D numpy array and extracts geometric metadata (size, spacing, origin, direction). Called by the tool handler.
    def load_dicom_image(series_path: str) -> Tuple[np.ndarray, Dict[str, Any]]:
        """Load a DICOM series into a 3D numpy array and metadata dictionary"""
        try:
            # Use ITK to read the DICOM series
            itk_image = itk.imread(series_path, itk.F)
            
            # Convert to numpy array
            np_array = itk.GetArrayFromImage(itk_image)
            
            # Extract metadata
            size = itk_image.GetLargestPossibleRegion().GetSize()
            spacing = itk_image.GetSpacing()
            origin = itk_image.GetOrigin()
            direction = itk_image.GetDirection().GetVnlMatrix().as_matrix().flatten().tolist()
            
            metadata = {
                "size": (int(size[0]), int(size[1]), int(size[2])),
                "spacing": (float(spacing[0]), float(spacing[1]), float(spacing[2])),
                "origin": (float(origin[0]), float(origin[1]), float(origin[2])),
                "direction": direction
            }
            
            return np_array, metadata
        except Exception as e:
            raise RuntimeError(f"Failed to load DICOM image: {e}")
  • Pydantic model used to represent and store DICOM series information, including the path used for loading and series_uid as key 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
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only states the action without behavioral details. It doesn't disclose memory implications, performance characteristics, error conditions, or what 'processing' entails, leaving significant gaps for a tool that loads data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste. It's front-loaded with the core action and purpose, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations and no output schema, the description is incomplete. It lacks details on what 'into memory' implies (e.g., memory limits, format), what 'processing' means, or expected outcomes, leaving the agent with insufficient context for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents the 'series_uid' parameter. The description adds no additional meaning beyond implying the UID identifies the series to load, aligning with the schema but not enhancing it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Load') and resource ('a DICOM series'), specifying it's for processing. It distinguishes from siblings like 'load-dicom-seg' by focusing on series rather than segmentation, but doesn't explicitly contrast with 'extract-dicom-metadata' or 'scan-dicom-directory'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like 'extract-dicom-metadata' or 'load-dicom-seg'. The description implies usage for processing but doesn't specify prerequisites, such as needing the series to be available from a prior scan.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shaunporwal/DICOM-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server