npi-verify
by gm4prezi
README.md
# npi-verify
A small, typed Python client and MCP server for the public CMS NPPES NPI Registry.
[](https://github.com/gm4prezi/npi-verify/actions/workflows/ci.yml)
## What it is
`npi-verify` looks up and searches United States healthcare providers against the
National Plan and Provider Enumeration System (NPPES) NPI Registry. NPPES is the
authoritative registry published by the Centers for Medicare and Medicaid Services
(CMS). Every clinician and healthcare organization that bills US payers has an NPI,
and the registry is the source of truth for that identity.
The package gives you two things:
1. A typed, dependency-light Python client that parses NPPES JSON into frozen
dataclasses.
2. An MCP (Model Context Protocol) server that exposes the same lookups as tools an
AI agent can call.
## Why
If you are building anything that touches the healthcare workforce, you eventually
need to confirm that a provider is real and that the identity you were handed matches
the public record. Checking the NPI against the CMS source of truth is the cheapest,
most defensible verification step available, and it requires no credentials. This
package makes that check a one-line call and a reusable agent tool.
The client validates the NPI offline before it ever hits the network, using the
same Luhn checksum (over the `80840` issuer prefix) that NPPES itself uses, so
malformed input fails fast and for free.
## Public CMS data, no PHI
The NPPES NPI Registry is free, public, and requires no authentication. It returns
provider demographic data only: names, NPIs, taxonomies, practice addresses, and
enumeration status. It contains no protected health information (PHI). This package
sends no credentials and stores nothing.
## Install
```bash
pip install npi-verify
```
To use the MCP server, install the optional `mcp` extra:
```bash
pip install "npi-verify[mcp]"
```
From source:
```bash
git clone https://github.com/gm4prezi/npi-verify.git
cd npi-verify
pip install -e ".[dev]"
```
## Client usage
Look up a single provider by NPI:
```python
from npi_verify import NPIClient
with NPIClient() as client:
provider = client.lookup_npi("1234567893")
if provider is None:
print("No provider with that NPI.")
else:
print(provider.name, provider.credential)
print(provider.taxonomy.description)
print(provider.primary_address.city, provider.primary_address.state)
```
Search by name, state, taxonomy, or organization:
```python
from npi_verify import NPIClient
with NPIClient() as client:
providers = client.search(
last_name="Rivera",
state="GA",
taxonomy_description="Internal Medicine",
limit=10,
)
for provider in providers:
print(provider.npi, provider.name, provider.entity_type)
```
Validate an NPI without any network call:
```python
from npi_verify import is_valid_npi, validate_npi
is_valid_npi("1234567893") # True
is_valid_npi("1234567890") # False (bad checksum)
validate_npi("0000000000") # raises ValueError
```
### Errors
- `lookup_npi` and `validate_npi` raise `ValueError` for a structurally invalid NPI.
- A not-found lookup returns `None`. An empty search returns `[]`.
- Network failures, timeouts, and NPPES query errors raise `NPIRegistryError`.
## MCP usage
The package ships an MCP server over stdio that exposes two tools, `lookup_npi` and
`search_providers`, both wired to the client above.
Run it directly:
```bash
npi-verify-mcp
# or
python -m npi_verify.mcp_server
```
Register it with an MCP client (for example, Claude Desktop) by adding this to your
MCP configuration:
```json
{
"mcpServers": {
"npi-verify": {
"command": "npi-verify-mcp"
}
}
}
```
If you prefer not to install the console script, point the config at the module:
```json
{
"mcpServers": {
"npi-verify": {
"command": "python",
"args": ["-m", "npi_verify.mcp_server"]
}
}
}
```
## Data model
`lookup_npi` and `search` return frozen `Provider` dataclasses:
| Field | Description |
| ------------------ | ------------------------------------------------------ |
| `npi` | The 10-digit NPI. |
| `entity_type` | `"Individual"` or `"Organization"`. |
| `name` | Person name, or organization name for entity type 2. |
| `credential` | Credential string (for example `MD`), individuals only.|
| `taxonomy` | Primary taxonomy: code, description, state, license. |
| `primary_address` | Practice location address (falls back to mailing). |
| `status` | NPPES status code (`A` for active). |
| `enumeration_date` | The date the NPI was issued. |
## Development
```bash
pip install -e ".[dev]"
pytest
```
The default test run mocks all HTTP, so it makes no network calls and is safe for CI.
A single live smoke test against the real NPPES API is marked `live` and is skipped by
default. Run it explicitly with:
```bash
pytest -m live
```
## License
MIT. See [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues