Skip to main content
Glama
NyxToolsDev

DICOM/HL7/FHIR Interoperability MCP Server

pacs_study_summary

Query PACS studies and generate complete interoperability mappings between DICOM, HL7, and FHIR standards for healthcare data integration.

Instructions

[Premium] Query a study from PACS and show its complete interoperability mapping. Returns: (1) study metadata from PACS, (2) DICOM-to-HL7 field mapping for key fields, (3) HL7-to-FHIR resource mapping, (4) a generated HL7 ORM^O01 message skeleton pre-filled with the study's actual data. This is the bridge between 'what's in PACS' and 'how do I represent it in HL7/FHIR'. Search by Study Instance UID or accession number.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
study_instance_uidNoStudy Instance UID to look up.
accession_numberNoAccession number to look up (alternative to UID).

Implementation Reference

  • The handler function _handle_study_summary executes the tool logic, including fetching study data from PACS and generating the summary components.
    def _handle_study_summary(arguments: dict) -> str:
        """Query a study from PACS and generate a complete interoperability summary."""
        study_uid = arguments.get("study_instance_uid", "")
        accession = arguments.get("accession_number", "")
    
        if not study_uid and not accession:
            return "Provide either study_instance_uid or accession_number to look up a study."
    
        # Step 1: Query PACS for the study
        filters = QueryFilters(limit=1)
        if study_uid:
            filters.study_instance_uid = study_uid
        elif accession:
            filters.accession_number = accession
    
        results = pacs_find(filters)
    
        if not results:
            search_term = study_uid or accession
            return format_pacs_result(f"No study found matching: {search_term}")
    
        study = results[0]
        if not isinstance(study, StudyResult):
            return format_pacs_result("Unexpected result type from PACS query.")
    
        # Step 2: Build the interoperability summary
        lines = [
            "PACS Study Interoperability Summary",
            "=" * 70,
            "",
            "SECTION 1: STUDY METADATA (from PACS)",
            "-" * 40,
        ]
    
        # Display study metadata
        study_data = study.model_dump()
        for key, value in study_data.items():
            if value:
                label = key.replace("_", " ").title()
                lines.append(f"  {label}: {value}")
    
        # Step 3: DICOM → HL7 mapping
        lines.extend([
            "",
            "SECTION 2: DICOM → HL7 v2 FIELD MAPPING",
            "-" * 40,
            f"  {'DICOM Tag':<25} {'Value':<25} {'HL7 Field':<15}",
            f"  {'─' * 25} {'─' * 25} {'─' * 15}",
        ])
    
        for field_name, dicom_tag, hl7_field in _KEY_STUDY_FIELDS:
            value = study_data.get(_camel_to_snake(field_name), "")
            if value:
                lines.append(f"  {field_name:<25} {str(value)[:25]:<25} {hl7_field:<15}")
    
        # Step 4: HL7 → FHIR mapping
        lines.extend([
            "",
            "SECTION 3: HL7 v2 → FHIR R4 RESOURCE MAPPING",
            "-" * 40,
            f"  {'HL7 Field':<15} {'FHIR Resource':<25} {'FHIR Path':<30}",
            f"  {'─' * 15} {'─' * 25} {'─' * 30}",
        ])
    
        # Map the key HL7 fields to FHIR
        _hl7_to_fhir_quick = {
            "PID-3": ("Patient", "Patient.identifier"),
            "PID-5": ("Patient", "Patient.name"),
            "PID-7": ("Patient", "Patient.birthDate"),
            "PID-8": ("Patient", "Patient.gender"),
            "PV1-8": ("Encounter", "Encounter.participant"),
            "OBR-4": ("ServiceRequest", "ServiceRequest.code"),
            "OBR-7": ("ServiceRequest", "ServiceRequest.occurrenceDateTime"),
            "OBR-18": ("ServiceRequest", "ServiceRequest.identifier"),
            "OBR-24": ("ImagingStudy", "ImagingStudy.modality"),
            "MSH-4": ("MessageHeader", "MessageHeader.source.endpoint"),
        }
    
        for _, _, hl7_field in _KEY_STUDY_FIELDS:
            if hl7_field in _hl7_to_fhir_quick:
                fhir_resource, fhir_path = _hl7_to_fhir_quick[hl7_field]
                lines.append(f"  {hl7_field:<15} {fhir_resource:<25} {fhir_path:<30}")
    
        # Step 5: Generate HL7 ORM^O01 skeleton
        lines.extend([
            "",
            "SECTION 4: GENERATED HL7 ORM^O01 MESSAGE",
            "-" * 40,
            "  (Pre-filled with study data from PACS)",
            "",
        ])
    
        orm_message = _generate_orm(study)
        for seg in orm_message:
            lines.append(f"  {seg}")
    
        # Step 6: Integration pattern reference
        lines.extend([
            "",
            "SECTION 5: INTEGRATION CONTEXT",
            "-" * 40,
            "  Pattern: Radiology Order-to-Result Workflow (IHE SWF)",
            "  This study would typically flow through:",
            "    1. HIS/EHR sends ORM^O01 → Integration Engine",
            "    2. Integration Engine → RIS (order creation)",
            "    3. RIS → Modality Worklist (MWL C-FIND)",
            "    4. Modality acquires images → PACS (C-STORE)",
            "    5. RIS sends ORU^R01 (report) → Integration Engine → EHR",
            "",
            "  Use 'explain_integration_pattern' with 'radiology workflow' for full details.",
        ])
    
        return format_pacs_result("\n".join(lines))
  • The inputSchema definition for pacs_study_summary.
        inputSchema={
            "type": "object",
            "properties": {
                "study_instance_uid": {
                    "type": "string",
                    "description": "Study Instance UID to look up.",
                    "default": "",
                },
                "accession_number": {
                    "type": "string",
                    "description": "Accession number to look up (alternative to UID).",
                    "default": "",
                },
            },
        },
    ),
  • The registration of pacs_study_summary within the PACS_COMBINED_TOOLS list.
    PACS_COMBINED_TOOLS = [
        Tool(
            name="pacs_study_summary",
            description=(
                "[Premium] Query a study from PACS and show its complete interoperability mapping. "
                "Returns: (1) study metadata from PACS, (2) DICOM-to-HL7 field mapping for key fields, "
                "(3) HL7-to-FHIR resource mapping, (4) a generated HL7 ORM^O01 message skeleton "
                "pre-filled with the study's actual data. This is the bridge between 'what's in PACS' "
                "and 'how do I represent it in HL7/FHIR'. "
                "Search by Study Instance UID or accession number."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "study_instance_uid": {
                        "type": "string",
                        "description": "Study Instance UID to look up.",
                        "default": "",
                    },
                    "accession_number": {
                        "type": "string",
                        "description": "Accession number to look up (alternative to UID).",
                        "default": "",
                    },
                },
            },
        ),
    ]

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/NyxToolsDev/dicom-hl7-mcp-server'

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