Skip to main content
Glama
erikhoward

Azure AHDS FHIR MCP Server

by erikhoward

search_fhir

Search healthcare data in Azure FHIR servers using comprehensive search parameters, modifiers, and pagination to retrieve specific FHIR resources.

Instructions

Search FHIR resources using comprehensive Azure FHIR search capabilities.

Supports resource-specific and common search parameters, modifiers, prefixes, chained searches, and result management. Returns paginated results in FHIR searchset bundles.

Key Features: • Resource-specific and common search parameters (_id, _lastUpdated, _tag, etc.) • Search modifiers (:missing, :exact, :contains, :text, :not, etc.) • Prefixes for ordered parameters (gt, lt, ge, le, etc.) • Chained searches (e.g., Encounter?subject:Patient.name=Jane) • Reverse chained searches using _has parameter • Include and revinclude searches (_include, _revinclude) • Result parameters (_count, _sort, _elements, _summary, _total) • Composite search parameters for complex queries • Pagination support with configurable page sizes (max 1000)

Args: resource_type: FHIR resource type to search (e.g., 'Patient', 'Observation', 'Condition') search_params: Dictionary of FHIR search parameters. Common examples: • {"name": "Smith", "_count": 50} - Search patients by name, limit 50 results • {"birthdate": "gt1990-01-01", "_sort": "birthdate"} - Patients born after 1990, sorted • {"identifier": "12345", "_include": "Patient:general-practitioner"} - Include GP • {"code": "77386006", "_include": "Observation:subject"} - Pregnancy observations with patients • {"_lastUpdated": "gt2024-01-01"} - Resources updated after date ctx: MCP Context for logging and progress reporting

Returns: List of matching FHIR resources extracted from searchset Bundle

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
resource_typeYes
search_paramsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary implementation of the 'search_fhir' tool: decorated with @mcp.tool() for MCP registration, executes FHIR search API requests, extracts results from Bundle, attaches catalog metadata including inputSchema for validation.
    @mcp.tool()
    async def search_fhir(resource_type: str, search_params: Optional[Dict[str, Any]] = None, ctx: Optional[Context] = None) -> List[Dict[str, Any]]:
        """
        Search FHIR resources using comprehensive Azure FHIR search capabilities.
    
        Supports resource-specific and common search parameters, modifiers, prefixes, chained searches, 
        and result management. Returns paginated results in FHIR searchset bundles.
    
        Key Features:
        • Resource-specific and common search parameters (_id, _lastUpdated, _tag, etc.)
        • Search modifiers (:missing, :exact, :contains, :text, :not, etc.)
        • Prefixes for ordered parameters (gt, lt, ge, le, etc.)
        • Chained searches (e.g., Encounter?subject:Patient.name=Jane)
        • Reverse chained searches using _has parameter
        • Include and revinclude searches (_include, _revinclude)
        • Result parameters (_count, _sort, _elements, _summary, _total)
        • Composite search parameters for complex queries
        • Pagination support with configurable page sizes (max 1000)
    
        Args:
            resource_type: FHIR resource type to search (e.g., 'Patient', 'Observation', 'Condition')
            search_params: Dictionary of FHIR search parameters. Common examples:
                • {"name": "Smith", "_count": 50} - Search patients by name, limit 50 results
                • {"birthdate": "gt1990-01-01", "_sort": "birthdate"} - Patients born after 1990, sorted
                • {"identifier": "12345", "_include": "Patient:general-practitioner"} - Include GP
                • {"code": "77386006", "_include": "Observation:subject"} - Pregnancy observations with patients
                • {"_lastUpdated": "gt2024-01-01"} - Resources updated after date
            ctx: MCP Context for logging and progress reporting
    
        Returns:
            List of matching FHIR resources extracted from searchset Bundle
        """
        if search_params is None:
            search_params = {}
    
        if resource_type not in FHIR_RESOURCES:
            error_msg = f"Invalid resource type: {resource_type}"
            logger.error(error_msg)
            if ctx:
                await ctx.error(error_msg)
            return []
    
        try:
            token = await get_fhir_token(ctx)
            headers = {"Authorization": f"Bearer {token}"}
    
            # Build URL with search parameters
            url = f"{FHIR_URL}/{resource_type}"
    
            if ctx:
                await ctx.info(f"Searching {resource_type} with params: {search_params}")
    
            response = requests.get(url, headers=headers,
                                    params=search_params, timeout=30)
    
            if response.status_code != 200:
                error_msg = f"Search failed: {response.status_code} - {response.text}"
                logger.error(error_msg)
                if ctx:
                    await ctx.error(error_msg)
                return []
    
            bundle = cast(Dict[str, Any], response.json())
    
            # Extract resources from Bundle
            if "entry" in bundle:
                results = [entry["resource"] for entry in bundle["entry"]]
                if ctx:
                    await ctx.info(f"Found {len(results)} {resource_type} resources")
                return results
            else:
                if ctx:
                    await ctx.info(f"No {resource_type} resources found")
                return []
    
        except (requests.RequestException, ValueError, KeyError) as e:
            error_msg = f"Error during search: {str(e)}"
            logger.error(error_msg)
            if ctx:
                await ctx.error(error_msg)
            return []
    
    
    _attach_tool_metadata("search_fhir", search_fhir)
  • Attaches tool metadata (name, description, inputSchema) from catalog.yaml to the search_fhir function for FastMCP discovery.
    _attach_tool_metadata("search_fhir", search_fhir)
  • Test fixture loading catalog.yaml which defines inputSchema for 'search_fhir' tool (not the primary schema location, but confirms existence). Actual schema in src/azure_fhir_mcp_server/config/catalog.yaml (file not directly accessible).
    catalog_path = Path(__file__).parent.parent / "src" / \
        "azure_fhir_mcp_server" / "config" / "catalog.yaml"
    
    with open(catalog_path, 'r', encoding='utf-8') as f:
        catalog_data = yaml.safe_load(f)
  • Computes list of valid FHIR resource types from catalog for validating search_fhir resource_type parameter.
    FHIR_RESOURCES = _compute_resource_types(RESOURCE_METADATA)
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: it returns paginated results in FHIR searchset bundles, supports configurable page sizes (max 1000), and handles complex search capabilities. It doesn't mention authentication needs, rate limits, or error handling, but covers most operational aspects well for a search tool.

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

Conciseness4/5

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

The description is well-structured with clear sections (overview, key features, args, returns) and uses bullet points for readability. It's appropriately sized for a complex tool but could be slightly more concise—some bullet points are verbose. Overall, it's front-loaded with purpose and efficiently organized, with most sentences earning their place.

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

Completeness5/5

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

Given the tool's complexity (FHIR search with many features), no annotations, and an output schema present, the description is highly complete. It covers purpose, features, parameters with examples, and return values, compensating for the lack of annotations. The output schema means it doesn't need to detail return structures, and it provides enough context for effective use.

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

Parameters5/5

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

The schema has 0% description coverage, so the description must fully compensate. It excels by providing detailed parameter semantics: it explains 'resource_type' as 'FHIR resource type to search' with examples, and 'search_params' as a dictionary with comprehensive examples and common use cases. The 'Args' section adds significant value beyond the bare schema, making parameters clear and actionable.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Search FHIR resources using comprehensive Azure FHIR search capabilities.' It specifies the verb ('search'), resource ('FHIR resources'), and platform ('Azure FHIR'), making it highly specific. With no sibling tools, it doesn't need differentiation, but the description is comprehensive and unambiguous about what the tool does.

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

Usage Guidelines3/5

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

The description implies usage context through its detailed feature list and examples, suggesting it's for complex FHIR queries. However, it lacks explicit guidance on when to use this tool versus alternatives (e.g., simpler queries or other FHIR operations). With no sibling tools, this is less critical, but it doesn't provide clear exclusions or prerequisites, leaving usage somewhat open-ended.

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/erikhoward/azure-fhir-mcp-server'

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