Skip to main content
Glama
sdesani

NPI MCP Server

by sdesani

title: NPI MCP Server emoji: 🩺 colorFrom: blue colorTo: green sdk: docker pinned: false app_port: 8000

NPI MCP Server

An MCP server that wraps the public NPPES NPI Registry API (version 2.1, no authentication) and exposes it over streamable HTTP at /mcp.

It does more than proxy the registry. Three tools pass NPPES queries through; three add logic the registry does not provide — offline checksum validation, a composite referral-eligibility assessment, and a plain-English specialty search that maps everyday clinical words onto NUCC taxonomy codes.

Tools

Direct NPPES access:

Tool

Use it when

search_provider(first_name, last_name, state, limit)

You know the provider's name. state is a 2-letter code.

lookup_by_npi(npi_number)

You already hold an exact 10-digit NPI.

get_specialties(npi_number)

You only need the provider's NUCC taxonomies.

Derived intelligence, not available from NPPES:

Tool

Use it when

validate_npi_format(npi_number)

Cheap offline pre-flight. Runs the CMS Luhn checksum over 80840 + the first 9 digits. Synchronous, no network call — use it before lookup_by_npi to avoid a wasted round trip on a mistyped number.

check_provider_status(npi_number)

"Can I refer a patient to this provider?" Five ordered checks: checksum → registry lookup → active enumeration → declared primary taxonomy → complete practice address. Returns an actionable concern per failed check.

find_providers_by_specialty(specialty_keyword, state, last_name_hint)

The user describes a kind of provider — "a cardiologist", "peds", "skin". Maps the phrase to NUCC codes, searches, then filters out the registry's text-match noise.

Supported specialty keywords: cardiology, dermatology, family medicine, neurology, oncology, orthopedic, pediatrics, psychiatry — plus common synonyms such as heart, peds, mental health, skin, cancer and primary care.

The three derived tools never raise. A mistyped NPI, an unknown NPI, an NPPES outage or an unrecognized keyword each return a structured result explaining what happened, so the calling model can recover instead of seeing an exception. An upstream outage is reported as inconclusive rather than "no such provider".

Endpoints

Path

Purpose

POST /mcp

MCP streamable HTTP endpoint.

GET /health

{"status", "version", "uptime_seconds"}.

GET /

Server name, version and MCP endpoint path, so a platform root probe gets 200.

Configuration

Variable

Meaning

MCP_ALLOWED_HOSTS

Comma-separated public hostnames to trust for DNS-rebinding protection. localhost and 127.0.0.1 (with and without ports) are always allowed. Each host H also trusts the origin https://H.

HOST / PORT

Bind address. The container defaults to 0.0.0.0:8000.

LOG_LEVEL

Default INFO.

The public hostname is runtime configuration, never compiled in, so one image serves both deployment targets. The resolved allowed_hosts are logged at startup.

Set MCP_ALLOWED_HOSTS for any non-local deployment. Without it, requests arriving with a public Host header are rejected with HTTP 421.

Deploy

Hugging Face Spaces (Docker SDK)

The frontmatter above configures the Space; app_port: 8000 matches the Dockerfile's EXPOSE. Add a Space variable MCP_ALLOWED_HOSTS set to the Space hostname, e.g. your-name-npi-mcp.hf.space. The MCP endpoint is then https://your-name-npi-mcp.hf.space/mcp.

Cloudflare tunnel

docker build -t npi-mcp .
docker run -d -p 8000:8000 -e MCP_ALLOWED_HOSTS="<your-tunnel-host>.trycloudflare.com" npi-mcp
cloudflared tunnel --url http://localhost:8000

A quick tunnel's hostname changes every run, so pass the new one via MCP_ALLOWED_HOSTS and restart the container. Multiple hosts are accepted, so a stable named tunnel and a Space hostname can be trusted at the same time.

Local development

pip install -e .
npi-mcp                    # http://0.0.0.0:8000
mcp dev src/npi_mcp/server.py

mcp dev loads server.py by file path, so the module has no parent package — every intra-package import is absolute (from npi_mcp.models import ...).

The SDK is pinned to mcp[cli]>=1.0,<2: the 2.x SDK renames FastMCP to MCPServer and changes the API.