Skip to main content
Glama
wso2

FHIR MCP Server

by wso2

Model Context Protocol (MCP) Server for Fast Healthcare Interoperability Resources (FHIR) APIs

License Get Support on Stack Overflow Join the community on Discord X Listed on Spark Install via Spark

Table of Contents

Related MCP server: FHIR MCP Server

Overview

The FHIR MCP Server is a Model Context Protocol (MCP) server that provides seamless integration with FHIR APIs. Designed for developers, integrators, and healthcare innovators, this server acts as a bridge between modern AI/LLM tools and healthcare data, making it easy to search, retrieve, and analyze clinical information.

Demo

Demo with HAPI FHIR server

This video showcases the MCP server's functionality when connected to a public HAPI FHIR server. This example showcases direct interaction with an open FHIR server that does not require an authorization flow.

https://github.com/user-attachments/assets/cc6ac87e-8329-4da4-a090-2d76564a3abf

Demo with EPIC Sandbox

This video showcases the MCP server's capabilities within the Epic EHR ecosystem. It demonstrates the complete OAuth 2.0 Authorization Code Grant flow.

https://github.com/user-attachments/assets/96b433f1-3e53-4564-8466-65ab48d521de

Core Features

  • MCP-compatible transport: Serves FHIR via stdio, SSE, or streamable HTTP

  • SMART-on-FHIR based authentication support: Securely authenticate with FHIR servers and clients

  • Response Filtering using FHIRPath: Filter resources and bundles returned by read and search operations using custom FHIRPath expressions to retrieve only the fields needed for the task, reducing payload sizes.

  • Tool integration: Integratable with any MCP client such as VS Code, Claude Desktop, and MCP Inspector

Prerequisites

  • Python 3.8+

  • uv (for dependency management)

  • An accessible FHIR API server.

Installation

You can use the FHIR MCP Server by installing our Python package, or by cloning this repository.

Installing using PyPI Package

  1. Configure Environment Variables:

    To run the server, you must set FHIR_SERVER_BASE_URL.

    • To enable authorization: Set FHIR_SERVER_BASE_URL, FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET, and FHIR_SERVER_SCOPES. Authorization is enabled by default.

    • To disable authorization: Set FHIR_SERVER_DISABLE_AUTHORIZATION to True.

    By default, the MCP server runs on http://localhost:8000, and you can customize the host and port using FHIR_MCP_HOST and FHIR_MCP_PORT.

    You can set these by exporting them as environment variables like below or by creating a .env file (referencing .env.example).

    export FHIR_SERVER_BASE_URL=""
    export FHIR_SERVER_CLIENT_ID=""
    export FHIR_SERVER_CLIENT_SECRET=""
    export FHIR_SERVER_SCOPES=""
    
    export FHIR_MCP_HOST="localhost"
    export FHIR_MCP_PORT="8000"
  2. Install the PyPI package and run the server

    uvx fhir-mcp-server

Installing from Source

  1. Clone the repository:

    git clone <repository_url>
    cd <repository_directory>
  2. Create a virtual environment and install dependencies:

    uv venv
    source .venv/bin/activate
    uv pip sync requirements.txt

    Or with pip:

    python -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  3. Configure Environment Variables: Copy the example file and customize if needed:

    cp .env.example .env
  4. Run the server:

    uv run fhir-mcp-server

Installing using Docker

Running the MCP Server with Docker

You can run the MCP server using Docker for a consistent, isolated environment.

Note on Authorization: When running the MCP server locally via Docker or Docker Compose, authorization should be disabled by setting the environment variable, FHIR_SERVER_DISABLE_AUTHORIZATION=True . This would be fixed in the future releases.

  1. Build the Docker Image or pull the docker image from the container registry:

    • Build from source:

      docker build -t fhir-mcp-server .
    • Pull from GitHub Container Registry:

      docker pull wso2/fhir-mcp-server:latest
  2. Configure Environment Variables

    Copy the example environment file and edit as needed:

    cp .env.example .env
    # Edit .env to set your FHIR server, client credentials, etc.

    Alternatively, you can pass environment variables directly with -e flags or use Docker secrets for sensitive values. See the Configuration section for details on available environment variables.

  3. Run the Container

    docker run --env-file .env -p 8000:8000 fhir-mcp-server

    This will start the server and expose it on port 8000. Adjust the port mapping as needed.

Using Docker Compose with HAPI FHIR Server

For a quick setup that includes both the FHIR MCP server and a HAPI FHIR server (with PostgreSQL), use the provided docker-compose.yml. This sets up an instant development environment for testing FHIR operations.

  1. Prerequisites:

    • Docker and Docker Compose installed.

  2. Run the Stack:

    docker-compose up -d

    This command will:

  3. Access the Services:

  4. Configure Additional Environment Variables:

    If you need to customize OAuth or other settings, adjust the env variables in the docker-compose.yml. The compose file sets basic configuration; refer to the Configuration section for full options.

Integration with MCP Clients

The FHIR MCP Server is designed for seamless integration with various MCP clients.

VS Code

Install in VS Code Install in VS Code Insiders

Add the following JSON block to your MCP configuration file in VS Code (> V1.104). You can do this by pressing Ctrl + Shift + P and typing MCP: Open User Configuration.

"servers": {
    "fhir": {
        "type": "http",
        "url": "http://localhost:8000/mcp",
    }
}
"servers": {
    "fhir": {
        "command": "uv",
        "args": [
            "--directory",
            "/path/to/fhir-mcp-server",
            "run",
            "fhir-mcp-server",
            "--transport",
            "stdio"
        ],
        "env": {
            "FHIR_SERVER_ACCESS_TOKEN": "Your FHIR Access Token"
        }
    }
}
"servers": {
    "fhir": {
        "type": "sse",
        "url": "http://localhost:8000/sse",
    }
}

Claude Desktop

Add the following JSON block to your Claude Desktop settings to connect to your local MCP server.

  • Launch the Claude Desktop app, click on the Claude menu in the top bar, and select "Settings…".

  • In the Settings pane, click “Developer” in the left sidebar. Then click "Edit Config". This will open your configuration file in your file system. If it doesn’t exist yet, Claude will create one automatically at:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Open the claude_desktop_config.json file in any text editor. Replace its contents with the following JSON block to register the MCP server:

{
    "mcpServers": {
        "fhir": {
            "command": "npx",
            "args": [
                "-y",
                "mcp-remote",
                "http://localhost:8000/mcp"
            ]
        }
    }
}
{
    "mcpServers": {
        "fhir": {
            "command": "uv",
            "args": [
                "--directory",
                "/path/to/fhir-mcp-server",
                "run",
                "fhir-mcp-server",
                "--transport",
                "stdio"
            ],
            "env": {
                "FHIR_SERVER_ACCESS_TOKEN": "Your FHIR Access Token"
            }
        }
    }
}
{
    "mcpServers": {
        "fhir": {
            "command": "npx",
            "args": [
                "-y",
                "mcp-remote",
                "http://localhost:8000/sse"
            ]
        }
    }
}

MCP Inspector

Follow these steps to get the MCP Inspector up and running:

  • Open a terminal and run the following command:

    npx -y @modelcontextprotocol/inspector

  • In the MCP Inspector interface:

  • Transport Type: Streamable HTTP

  • URL: http://localhost:8000/mcp

  • Transport Type: STDIO

  • Command: uv

  • Arguments: --directory /path/to/fhir-mcp-server run fhir-mcp-server --transport stdio

  • Transport Type: SSE

  • URL: http://localhost:8000/sse

Make sure your MCP server is already running and listening on the above endpoint.

Once connected, MCP Inspector will allow you to visualize tool invocations, inspect request/response payloads, and debug your tool implementations easily.

Configuration

CLI Options

You can customize the behavior of the MCP server using the following command-line flags:

  • --transport

    • Description: Specifies the transport protocol used by the MCP server to communicate with clients.

    • Accepted values: stdio, sse, streamable-http

    • Default: streamable-http

  • --log-level

    • Description: Sets the logging verbosity level for the server.

    • Accepted values: DEBUG, INFO, WARN, ERROR (case-insensitive)

    • Default: INFO

  • --help

    • Description: Displays a help message with available server options and exits.

    • Usage: Automatically provided by the command-line interface.

Sample Usages:

uv run fhir-mcp-server --transport streamable-http --log-level DEBUG
uv run fhir-mcp-server --help

Environment Variables

MCP Server Configurations:

  • FHIR_MCP_HOST: The hostname or IP address the MCP server should bind to (e.g., localhost for local-only access, or 0.0.0.0 for all interfaces).

  • FHIR_MCP_PORT: The port on which the MCP server will listen for incoming client requests (e.g., 8000).

  • FHIR_MCP_SERVER_URL: If set, this value will be used as the server's base URL instead of generating it from host and port. Useful for custom URL configurations or when behind a proxy.

  • FHIR_MCP_REQUEST_TIMEOUT: Timeout duration in seconds for requests from the MCP server to the FHIR server (default: 30).

MCP Server OAuth2 with FHIR server Configuration (MCP Client ↔ MCP Server): These variables configure the MCP client's secure connection to the MCP server, using the OAuth2 authorization code grant flow with a FHIR server.

  • FHIR_SERVER_CLIENT_ID: The OAuth2 client ID used to authorize MCP clients with the FHIR server.

  • FHIR_SERVER_DISABLE_AUTHORIZATION: If set to True, disables authorization checks on the MCP server, allowing connections to publicly accessible FHIR servers.

  • FHIR_SERVER_CLIENT_SECRET: The client secret corresponding to the FHIR client ID. Used during token exchange.

  • FHIR_SERVER_BASE_URL: The base URL of the FHIR server (e.g., https://hapi.fhir.org/baseR4). This is used to generate tool URIs and to route FHIR requests.

  • FHIR_SERVER_SCOPES: A space-separated list of OAuth2 scopes to request from the FHIR authorization server (e.g., user/Patient.read user/Observation.read). Add fhirUser openid to enable retrieval of user context for the get_user tool. If these two scopes are not configured, the get_user tool returns an empty result because the ID token lacks the user's FHIR resource reference.

  • FHIR_SERVER_ACCESS_TOKEN: The access token to use for authenticating requests to the FHIR server. If this variable is set, the server will bypass the OAuth2 authorization flow and use this token directly for all requests.

NOTE

FHIR_SERVER_ACCESS_TOKEN is intended for local stdio mode deployments only, as a convenience to bypass interactive OAuth authentication. Do not use this variable when the MCP server is exposed over a network or the public internet.

Tools

  • get_capabilities: Retrieves metadata about a specified FHIR resource type, including its supported search parameters and custom operations.

    • type: The FHIR resource type name (e.g., "Patient", "Observation", "Encounter")

  • search: Executes a standard FHIR search interaction on a given resource type, returning a bundle or list of matching resources.

    • type: The FHIR resource type name (e.g., "MedicationRequest", "Condition", "Procedure").

    • searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"family":"Simpson","birthdate":"1956-05-12"}).

    • response_filter_fhirpaths: (Optional) An array of FHIRPath expressions (e.g., ["Patient.name", "Patient.birthDate", "Bundle.link.where(relation='next').url"]) to apply to the resources in the response bundle.

  • read: Performs a FHIR "read" interaction to retrieve a single resource instance by its type and resource ID, optionally refining the response with search parameters or custom operations.

    • type: The FHIR resource type name (e.g., "DiagnosticReport", "AllergyIntolerance", "Immunization").

    • id: The logical ID of a specific FHIR resource instance.

    • searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"device-name":"glucometer"}).

    • operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$everything").

    • response_filter_fhirpaths: (Optional) An array of FHIRPath expressions (e.g., ["Patient.name", "Observation.valueQuantity"]) to filter the returned single resource (or entries when using custom operations like $everything).

  • create: Executes a FHIR "create" interaction to persist a new resource of the specified type.

    • type: The FHIR resource type name (e.g., "Device", "CarePlan", "Goal").

    • payload: A JSON object representing the full FHIR resource body to be created.

    • searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"address-city":"Boston"}).

    • operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$evaluate").

  • update: Performs a FHIR "update" interaction by replacing an existing resource instance's content with the provided payload.

    • type: The FHIR resource type name (e.g., "Location", "Organization", "Coverage").

    • id: The logical ID of a specific FHIR resource instance.

    • payload: The complete JSON representation of the FHIR resource, containing all required elements and any optional data.

    • searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"patient":"Patient/54321","relationship":"father"}).

    • operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$lastn").

  • delete: Execute a FHIR "delete" interaction on a specific resource instance.

    • type: The FHIR resource type name (e.g., "ServiceRequest", "Appointment", "HealthcareService").

    • id: The logical ID of a specific FHIR resource instance.

    • searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"category":"laboratory","issued:"2025-05-01"}).

    • operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$expand").

  • get_user: Retrieves the currently authenticated user's FHIR resource (for example the linked Patient resource) and returns a concise profile containing available demographic fields such as id, name, and birthDate.

Development & Testing

Installing Development Dependencies

To run tests and contribute to development, install the test dependencies:

Using pip:

# Install project in development mode with test dependencies
pip install -e '.[test]'

# Or install from requirements file
pip install -r requirements-dev.txt

Using uv:

# Install development dependencies
uv sync --dev

Running Tests

The project includes a comprehensive test suite covering all major functionality:

# Simple test runner
python run_tests.py

# Or direct pytest usage
PYTHONPATH=src python -m pytest tests/ -v --cov=src/fhir_mcp_server

Using pytest:

pytest tests/

This will discover and run all tests in the tests/ directory.

Test Features:

  • 100+ tests with comprehensive coverage

  • Full async/await support using pytest-asyncio

  • Complete mocking of HTTP requests and external dependencies

  • Coverage reporting with terminal and HTML output

  • Fast execution with no real network calls

The test suite includes:

  • Unit tests: Core functionality testing

  • Integration tests: Component interaction validation

  • Edge case coverage: Error handling and validation scenarios

  • Mocked OAuth flows: Realistic authentication testing

Coverage reports are generated in htmlcov/index.html for detailed analysis.

Available Tools

7 tools
createA

Executes a FHIR create interaction to persist a new resource of the specified type. It is required to supply the full resource payload in JSON form. Use this tool when you need to add new data (e.g., a new Patient or Observation). Note that servers may reject resources that violate profiles or mandatory bindings.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe FHIR resource type name. Must exactly match one of the resource types supported by the server.
payloadYesA JSON object representing the full FHIR resource body to be created. It must include all required elements of the resource's profile.
searchParamNoA mapping of FHIR search parameter names to their desired values. These parameters refine queries for operation-specific query qualifiers. Only parameters exposed by `get_capabilities` for that resource type are valid.
operationNoThe name of a custom FHIR operation or extended query defined for the resourceMust match one of the operation names returned by `get_capabilities`.

TDQS

A4/5.0
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 and does well by disclosing key behavioral traits: it specifies that servers may reject resources for profile violations or mandatory binding issues, which is crucial for a write operation. However, it doesn't mention other potential behaviors like rate limits, authentication needs, or response formats.

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 appropriately sized and front-loaded, with the first sentence stating the core purpose. The second sentence adds required input details, and the third provides usage context and behavioral notes. Every sentence earns its place, though it could be slightly more streamlined.

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

Completeness3/5

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

For a mutation tool with 4 parameters, no annotations, and no output schema, the description is adequate but has gaps. It covers the purpose and some behavioral aspects (server rejections), but lacks details on prerequisites, error handling, or return values. Given the complexity, it should do more to compensate for missing structured data.

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 already documents all parameters thoroughly. The description adds minimal value beyond the schema by mentioning 'full resource payload in JSON form' and 'specified type,' but it doesn't provide additional semantic context or usage examples for parameters. Baseline 3 is appropriate given high schema coverage.

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 specific action ('Executes a FHIR `create` interaction'), the resource involved ('new resource of the specified type'), and distinguishes it from siblings by specifying it's for adding new data rather than reading, updating, or deleting. The examples (Patient, Observation) further clarify the purpose.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool ('when you need to add new data'), but it doesn't explicitly mention when not to use it or name specific alternatives among the sibling tools (e.g., use 'update' for existing resources, 'read' for retrieval). The guidance is helpful but lacks sibling differentiation.

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

deleteA

Execute a FHIR delete interaction on a specific resource instance. Use this tool when you need to remove a single resource identified by its logical ID or optionally filtered by search parameters. The optional id parameter must match an existing resource instance when present. If you include searchParam, the server will perform a conditional delete, deleting the resource only if it matches the given criteria. If you supply operation, it will execute the named FHIR operation (e.g., $expunge) on the resource. This tool returns a FHIR OperationOutcome describing success or failure of the deletion.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe FHIR resource type name. Must exactly match one of the resource types supported by the server.
idNoThe logical ID of a specific FHIR resource instance.
searchParamNoA mapping of FHIR search parameter names to their desired values. These parameters refine queries for operation-specific query qualifiers. Only parameters exposed by `get_capabilities` for that resource type are valid.
operationNoThe name of a custom FHIR operation or extended query defined for the resourceMust match one of the operation names returned by `get_capabilities`.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries full burden and does well. It discloses that this is a destructive operation ('remove a single resource'), explains conditional behavior ('deleting the resource only if it matches the given criteria'), mentions server validation ('must match an existing resource instance'), and describes the return type ('FHIR OperationOutcome'). It doesn't cover rate limits or authentication needs.

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 appropriately sized and front-loaded. The first sentence states the core purpose, followed by specific usage scenarios and parameter interactions. Every sentence adds value with no wasted words, and the structure logically progresses from general to specific details.

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

Completeness4/5

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

For a complex destructive operation with 4 parameters, no annotations, and no output schema, the description does well. It explains the tool's behavior, parameter interactions, and return type. However, it doesn't mention prerequisites like authentication or potential side effects, which would be helpful given the destructive nature.

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 already documents all parameters thoroughly. The description adds some semantic context by explaining how parameters interact (e.g., 'If you include searchParam, the server will perform a conditional delete'), but doesn't provide significant additional meaning beyond what's in the schema descriptions.

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: 'Execute a FHIR `delete` interaction on a specific resource instance.' It specifies the verb ('delete'), resource ('FHIR resource'), and distinguishes from siblings like 'create', 'read', 'update', and 'search' by focusing on removal operations.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool: 'when you need to remove a single resource identified by its logical ID or optionally filtered by search parameters.' It explains conditional deletion and operation execution scenarios. However, it doesn't explicitly state when not to use it or name alternatives among siblings.

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

get_capabilitiesA

Retrieves metadata about a specified FHIR resource type, including its supported search parameters and custom operations. This tool MUST always be invoked before performing any resource operation (such as search, read, create, update, or delete) to discover the valid searchParams and operations permitted for that resource type. Do not use this tool to fetch actual resources.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe FHIR resource type name. Must exactly match one of the core or profile-defined resource types as per the FHIR specification.

TDQS

A4.4/5.0
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 the tool's purpose and constraints (e.g., it's for metadata discovery, not resource fetching), but lacks details on potential errors, rate limits, or authentication requirements. However, it adds significant context beyond basic functionality.

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 front-loaded with the core purpose, followed by usage rules and exclusions in two concise sentences. Every sentence earns its place by providing essential guidance without redundancy, making it highly efficient and well-structured.

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

Completeness4/5

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

Given the tool's complexity (metadata discovery for FHIR operations) and lack of annotations or output schema, the description is largely complete. It explains the tool's role and constraints clearly, though it could benefit from mentioning what the output includes (e.g., search parameters, operations) or error handling, which would enhance completeness.

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?

The input schema has 100% description coverage, clearly documenting the single required parameter 'type' with examples. The description adds no additional parameter-specific information beyond what the schema provides, such as format details or constraints, so it meets the baseline for high schema coverage.

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 specific action ('Retrieves metadata') and resource ('FHIR resource type'), distinguishing it from sibling tools like 'read' or 'search' that fetch actual resources. It explicitly contrasts with those operations by stating 'Do not use this tool to fetch actual resources.'

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool ('MUST always be invoked before performing any resource operation') and when not to use it ('Do not use this tool to fetch actual resources'). It implicitly positions this as a prerequisite for other operations like search, read, create, update, or delete, offering clear alternatives.

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

get_userA

Retrieves the authenticated user's FHIR profile. Use this tool when you need to access the current user's demographic and contact details.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses that it retrieves the 'authenticated user's' profile, implying authentication requirements, and mentions 'demographic and contact details' as output content. However, it lacks details on error conditions, rate limits, or whether it's read-only/safe—critical for a tool with no annotations. This is adequate but has clear gaps.

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 two concise sentences with zero waste: the first states the purpose, and the second provides usage guidelines. It's front-loaded with the core action and efficiently adds context without redundancy. Every sentence earns its place.

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

Completeness3/5

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

Given the tool's complexity (simple retrieval), no annotations, no output schema, and 0 parameters, the description is minimally adequate. It covers the purpose and usage but lacks behavioral details like response format or error handling. For a tool with no structured fields to rely on, it should do more to be complete, but it meets the minimum viable threshold.

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

Parameters4/5

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

The tool has 0 parameters, and schema description coverage is 100% (empty schema). The description doesn't need to explain parameters, and it correctly avoids adding unnecessary details. A baseline of 4 is appropriate for zero-parameter tools, as there's no parameter semantics to cover beyond what the schema provides.

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 tool's purpose: 'Retrieves the authenticated user's FHIR profile' (specific verb+resource). It adds context about accessing 'demographic and contact details,' which helps distinguish it from generic 'get' operations. However, it doesn't explicitly differentiate from sibling tools like 'read' or 'search,' which might also retrieve user data, preventing a perfect score.

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

Usage Guidelines4/5

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

The description provides clear usage guidance: 'Use this tool when you need to access the current user's demographic and contact details.' This gives context for when to invoke it. However, it doesn't specify when NOT to use it or mention alternatives among sibling tools (e.g., 'read' might retrieve other users' profiles), so it falls short of a 5.

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

readA

Performs a FHIR read interaction to retrieve a single resource instance by its type and resource ID, optionally refining the response with search parameters or custom operations. Use it when you know the exact resource ID and require that one resource; do not use it for bulk queries. If additional query-level parameters or operations are needed (e.g., _elements or $validate), include them in searchParam or operation.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe FHIR resource type name. Must exactly match one of the resource types supported by the server.
idYesThe logical ID of a specific FHIR resource instance.
searchParamNoA mapping of FHIR search parameter names to their desired values. These parameters refine queries for operation-specific query qualifiers. Only parameters exposed by `get_capabilities` for that resource type are valid.
operationNoThe name of a custom FHIR operation or extended query defined for the resource must match one of the operation names returned by `get_capabilities`.

TDQS

A4/5.0
Behavior3/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 explains the tool's purpose and constraints (single resource retrieval, not for bulk queries) but lacks details on error handling, rate limits, authentication requirements, or response format. It does mention that search parameters must match those from 'get_capabilities', adding some context, but overall behavioral traits are minimally covered.

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 efficiently structured in two sentences: the first states the purpose and scope, and the second provides usage guidelines and parameter context. It's front-loaded with key information and avoids redundancy, though it could be slightly more concise by integrating the parameter details more seamlessly.

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

Completeness3/5

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

Given the tool's moderate complexity (4 parameters, nested objects, no output schema, and no annotations), the description is adequate but has gaps. It covers purpose and usage well but lacks details on behavioral aspects like error handling or response format. Without annotations or an output schema, the description doesn't fully compensate for these missing elements, leaving some context incomplete.

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 already documents all parameters thoroughly. The description adds marginal value by explaining that search parameters 'refine the response' and operations are 'custom FHIR operations', but it doesn't provide additional syntax or format details beyond what the schema specifies. This meets the baseline for high schema coverage.

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 performs a FHIR 'read' interaction to retrieve a single resource instance by type and ID, distinguishing it from bulk query tools like 'search' and other CRUD operations like 'create', 'update', and 'delete'. It specifies the exact verb ('retrieve'), resource ('single resource instance'), and scope ('by its type and resource ID').

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool ('when you know the exact resource ID and require that one resource') and when not to use it ('do not use it for bulk queries'). It also mentions alternatives implicitly by contrasting with bulk queries, though it doesn't name specific sibling tools like 'search' directly. The inclusion of 'If additional query-level parameters or operations are needed...' further clarifies usage scenarios.

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

updateA

Performs a FHIR update interaction by replacing an existing resource instance's content with the provided payload. Use it when you need to overwrite a resource's data in its entirety, such as correcting or completing a record, and you already know the resource's logical id. Optionally, you can include searchParam for conditional updates (e.g., only update if the resource matches certain criteria) or specify a custom operation (e.g., $validate to run validation before updating) The tool returns the updated resource or an OperationOutcome detailing any errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe FHIR resource type name. Must exactly match one of the resource types supported by the server.
idYesThe logical ID of a specific FHIR resource instance.
payloadYesThe complete JSON representation of the FHIR resource, containing all required elements and any optional data. Servers replace the existing resource with this exact content, so the payload must include all mandatory fields defined by the resource's profile and any previous data you wish to preserve.
searchParamNoA mapping of FHIR search parameter names to their desired values. These parameters refine queries for operation-specific query qualifiers. Only parameters exposed by `get_capabilities` for that resource type are valid.
operationNoThe name of a custom FHIR operation or extended query defined for the resourceMust match one of the operation names returned by `get_capabilities`.

TDQS

A4.5/5.0
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 explains that this is a destructive write operation ('replacing an existing resource instance's content'), mentions that the payload must include all required fields and any data to preserve, describes optional conditional updates and custom operations, and notes the return value includes either the updated resource or error details. It doesn't cover rate limits or authentication requirements, but provides substantial operational context.

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 appropriately sized at three sentences, front-loaded with the core purpose, followed by usage guidance, and ending with return value information. Every sentence adds value, though it could be slightly more concise by combining some concepts about optional parameters.

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

Completeness4/5

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

For a complex mutation tool with 5 parameters, no annotations, and no output schema, the description does well by explaining the destructive nature, parameter interactions, and return values. It covers the essential context needed to use the tool correctly, though could benefit from mentioning authentication or error handling specifics.

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

Parameters4/5

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

With 100% schema description coverage, the baseline is 3. The description adds meaningful context beyond the schema by explaining the purpose of each parameter: 'type' identifies the FHIR resource, 'id' is the logical ID, 'payload' must contain complete resource data for replacement, 'searchParam' enables conditional updates, and 'operation' allows custom operations. This provides practical guidance on how parameters work together.

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 performs a FHIR 'update' interaction by replacing an existing resource's content with a provided payload. It specifies the verb ('replacing'), resource ('FHIR resource instance'), and distinguishes it from siblings by mentioning it's for overwriting entire resources when you know the logical ID, unlike create (new resources) or read/search (retrieval operations).

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool ('when you need to overwrite a resource's data in its entirety, such as correcting or completing a record, and you already know the resource's logical id') and mentions conditional updates and custom operations as optional use cases. It distinguishes from siblings by implying this is for full replacements rather than partial updates or other operations.

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

TDQS

A4.2/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose aligned with FHIR operations: create, delete, get_capabilities, get_user, read, search, and update. There is no overlap in functionality; for example, read retrieves a single resource by ID, while search queries multiple resources, and get_capabilities fetches metadata rather than resources. The descriptions reinforce these boundaries, making misselection unlikely.

Naming Consistency4/5

The naming is mostly consistent with a verb-based pattern (create, delete, read, search, update) and underscores for multi-word names (get_capabilities, get_user). However, get_capabilities and get_user deviate slightly from the simpler verb style of other tools, though they remain readable and follow a similar structure. This minor inconsistency prevents a perfect score.

Tool Count5/5

With 7 tools, this server is well-scoped for FHIR operations, covering core interactions like CRUD (create, read, update, delete), search, metadata discovery (get_capabilities), and user context (get_user). Each tool earns its place without redundancy, and the count is typical for a domain-specific server, avoiding bloat or thin coverage.

Completeness5/5

The tool set provides complete coverage for FHIR interactions, including all essential CRUD operations (create, read, update, delete), search for queries, get_capabilities for metadata discovery, and get_user for authentication context. There are no obvious gaps; agents can perform full lifecycle management and queries without dead ends in this domain.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables LLM-based agents to interact with FHIR healthcare data through natural language prompts, providing full CRUD operations on FHIR resources, document processing, and semantic search capabilities.
    13
    98
    MIT
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables seamless integration with FHIR APIs for healthcare applications, allowing users to search, retrieve, create, update, and analyze clinical information through natural language interactions. Supports SMART-on-FHIR authentication and works with various healthcare systems like EPIC and HAPI FHIR servers.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to securely interact with FHIR healthcare servers and HL7 terminology services. Provides comprehensive healthcare data operations with built-in PHI protection, audit logging, and SMART on FHIR authentication.
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Provides read/write access to any FHIR-compliant healthcare API with built-in validation, supporting resource management, search operations, and granular permissions through natural language.
    5
    1

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

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