Skip to main content
Glama

npi-providers-mcp-server

Npi Search Providers

npi_search_providers
Read-onlyIdempotent

Search the NPPES NPI registry for individual practitioners and healthcare organizations by name, organization name, location, provider type, and specialty. Plain-language specialty terms (e.g. "cardiologist", "pediatric cardiologist") resolve through the bundled NUCC taxonomy; the top match's specialization or classification becomes taxonomy_description, and all resolved candidates are returned in metadata. Location belongs in the dedicated city/state/postal_code inputs, not inside specialty. Each provider row includes the NPI, name, primary specialty, city/state/ZIP, type, and active/deactivated status; the NPI is the input for npi_get_provider when the full record is needed. At least one search criterion is required, and the registry rejects state-only searches. When city/state/postal_code are given, only practice addresses are searched, never mailing addresses: a provider is returned only when its primary practice location or one of its other practice locations matches all of them. A provider kept on another practice location names it in matchedLocation. Name searches also match former and other names, sorted by current name; such a row names the matching name in matchedOtherName. The registry never reports a true match total, and one search reaches only its first 1200 matches: a full page names the next in nextPage, and the terminal window (skip 1000, limit 200) returns continuationPostalCodes, postal_code prefixes that continue the search.

Input Schema

NameRequiredDescriptionDefault
cityNoPractice-location city, case-insensitive. A trailing "*" after at least 2 characters matches every city starting with them (e.g. "SAN F*").
skipNoResults to skip for pagination (0–1000). A full page names the next in nextPage.
limitNoMaximum providers to return (default 10). Values above 200 are clamped to the registry cap of 200 with a notice.
stateNo2-letter state code (e.g. "WA"). The registry rejects state-only searches, so another criterion is required. A blank value is treated as omitted.
last_nameNoIndividual last name. Trailing wildcard "*" allowed with at least 2 leading characters.
specialtyNoPlain-language specialty (e.g. "pediatric cardiologist"), resolved through the bundled NUCC taxonomy to exact descriptions before searching. Codes NUCC marks inactive are never resolved. The matched taxonomy is echoed in the result. Mutually exclusive with taxonomy_description.
first_nameNoIndividual first name. Trailing wildcard "*" allowed with at least 2 leading characters.
name_searchNoOne person's name. The first token becomes first_name and the last token becomes last_name; use first_name/last_name when middle names or multi-part surnames matter.
postal_codeNoPractice-location ZIP code: 5 digits (also matching the ZIP+4 codes that extend it), 9 digits, or a 2–9 digit prefix with one trailing "*" (e.g. "98*", "981*"). A ZIP+4 prefix (6+ digits) never matches a practice address recorded with only a 5-digit ZIP.
provider_typeNoRestrict to individuals (NPI-1) or organizations (NPI-2). Omit to search both; when set, it must match the name fields ("individual" for first_name/last_name/name_search, "organization" for organization_name).
organization_nameNoOrganization name (implies provider_type organization; cannot be combined with first_name, last_name, or name_search). Trailing wildcard "*" allowed with at least 2 leading characters.
taxonomy_descriptionNoExact NUCC taxonomy description for direct passthrough — use when the taxonomy description is already known. Mutually exclusive with specialty.
use_first_name_aliasNoInclude first-name variants (default true upstream). False requests exact first-name matching. Applies to the resolved first_name, including name_search, only without a wildcard; other-name matching remains enabled.

Output Schema

NameRequiredDescriptionDefault
capNoThe limit that was applied.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of providers returned.
noticeNoGuidance — the page-size-not-total caveat, the next page or terminal-window continuation procedure, other-name and location-filter counts, or how to broaden an empty result.
nextPageNoThe next page: re-run the same arguments with this skip and limit. Present after a full page while rows remain reachable. When skip + limit passes 1000 it is skip 1000, limit 200, whose leading rows repeat rows already returned (the notice says how many) — dedupe by NPI.
providersNoMatching provider rows (up to limit).
truncatedNoTrue when the NPPES page contained at least cap providers before location constraints were applied; more may match even when shown is below cap.
resolvedTaxonomiesNoTaxonomy candidates ranked for the specialty term. The first candidate supplies appliedTaxonomyDescription; a different candidate can be selected through taxonomy_description.
appliedFirstNameAliasNoEffective first-name alias expansion for a resolved non-wildcard first name, including the upstream default true. Absent when no first name exists or it contains a wildcard.
continuationPostalCodesNoPresent only at the terminal window (a full page at skip 1000, limit 200): postal_code prefixes that continue the same search, each re-run from skip 0 with the same arguments — the notice gives the full procedure. Empty when no postal split remains (postal_code is already a 5-digit ZIP, a full ZIP+4, or not a numeric ZIP prefix).
appliedTaxonomyDescriptionNoThe exact NUCC specialization or classification used as the specialty filter.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum providers to return (1–200; the registry caps at 200)."New value: +"Maximum providers to return (default 10). Values above 200 are clamped to the registry cap of 200 with a notice."
    • changedInput schema / properties / limit / maximum
      Previous value: -200New value: +9007199254740991
    • addedInput schema / properties / use_first_name_alias
      Added value: +{
      +  "description": "Include first-name variants (default true upstream). False requests exact first-name matching. Applies to the resolved first_name, including name_search, only without a wildcard; other-name matching remains enabled.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / appliedFirstNameAlias
      Added value: +{
      +  "description": "Effective first-name alias expansion for a resolved non-wildcard first name, including the upstream default true. Absent when no first name exists or it contains a wildcard.",
      +  "type": "boolean"
      +}
  2. Changed13 schema fields changed
    • changedInput schema / properties / city / description
      Previous value: -"Practice-location city."New value: +"Practice-location city, case-insensitive. A trailing \"*\" after at least 2 characters matches every city starting with them (e.g. \"SAN F*\")."
    • addedInput schema / properties / city / pattern
      Added value: +"^[^*]*$|^[^*]{2,}\\*$"
    • changedInput schema / properties / organization_name / description
      Previous value: -"Organization name (implies provider_type organization). Trailing wildcard \"*\" allowed with at least 2 leading characters."New value: +"Organization name (implies provider_type organization; cannot be combined with first_name, last_name, or name_search). Trailing wildcard \"*\" allowed with at least 2 leading characters."
    • changedInput schema / properties / postal_code / description
      Previous value: -"Practice-location postal/ZIP code (5 or 9 digits)."New value: +"Practice-location ZIP code: 5 digits (also matching the ZIP+4 codes that extend it), 9 digits, or a 2–9 digit prefix with one trailing \"*\" (e.g. \"98*\", \"981*\"). A ZIP+4 prefix (6+ digits) never matches a practice address recorded with only a 5-digit ZIP."
    • addedInput schema / properties / postal_code / pattern
      Added value: +"^[^*]*$|^\\d{2,9}\\*$"
    • changedInput schema / properties / provider_type / description
      Previous value: -"Restrict to individuals (NPI-1) or organizations (NPI-2). Omit to search both."New value: +"Restrict to individuals (NPI-1) or organizations (NPI-2). Omit to search both; when set, it must match the name fields (\"individual\" for first_name/last_name/name_search, \"organization\" for organization_name)."
    • changedInput schema / properties / skip / description
      Previous value: -"Results to skip for pagination (0–1000). Only the first 1200 matches are reachable; skip beyond 1000 silently returns the same window — narrow the query instead of paging further."New value: +"Results to skip for pagination (0–1000). A full page names the next in nextPage."
    • addedOutput schema / properties / continuationPostalCodes
      Added value: +{
      +  "description": "Present only at the terminal window (a full page at skip 1000, limit 200): postal_code prefixes that continue the same search, each re-run from skip 0 with the same arguments — the notice gives the full procedure. Empty when no postal split remains (postal_code is already a 5-digit ZIP, a full ZIP+4, or not a numeric ZIP prefix).",
      +  "items": {
      +    "description": "A trailing-\"*\" postal_code prefix.",
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_search_criteria`: No effective search criterion was provided. `conflicting_specialty`: Both specialty and taxonomy_description were supplied. `unresolved_specialty`: The specialty term matched no active NUCC taxonomy (the message names any inactive codes it matched). `invalid_search_field`: The registry returned a field error (e.g. wildcard under 2 characters, bad provider type). Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_search_criteria`: No effective search criterion was provided. `conflicting_specialty`: Both specialty and taxonomy_description were supplied. `mixed_provider_criteria`: Individual criteria (first_name, last_name, name_search) were combined with organization criteria (organization_name), directly or through provider_type. `unresolved_specialty`: The specialty term matched no active NUCC taxonomy (the message names any inactive codes it matched), or was made only of generic words (\"doctor\", \"M.D.\", \"specialist\") that name no specialty. `invalid_search_field`: The registry returned a field error (e.g. wildcard under 2 characters, bad provider type). Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_search_criteria",
      -  "conflicting_specialty",
      -  "unresolved_specialty",
      -  "invalid_search_field"
      -]New value: +[
      +  "no_search_criteria",
      +  "conflicting_specialty",
      +  "mixed_provider_criteria",
      +  "unresolved_specialty",
      +  "invalid_search_field"
      +]
    • addedOutput schema / properties / nextPage
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The next page: re-run the same arguments with this skip and limit. Present after a full page while rows remain reachable. When skip + limit passes 1000 it is skip 1000, limit 200, whose leading rows repeat rows already returned (the notice says how many) — dedupe by NPI.",
      +  "properties": {
      +    "limit": {
      +      "description": "The limit to send for the next page.",
      +      "type": "number"
      +    },
      +    "skip": {
      +      "description": "The skip to send for the next page.",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "skip",
      +    "limit"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance — pagination ceiling, page-size-not-total caveat, or how to broaden an empty result."New value: +"Guidance — the page-size-not-total caveat, the next page or terminal-window continuation procedure, other-name and location-filter counts, or how to broaden an empty result."
    • addedOutput schema / properties / providers / items / properties / matchedOtherName
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The other (former, professional, DBA, or alternate) name this row matched the name search through. Present only when the current name fails a requested last_name, organization_name, or wildcard first_name and this other name satisfies it (case-insensitive, ignoring punctuation and spaces, trailing \"*\" as a prefix). An exact first_name alone never marks a row: the registry also matches first-name variants (Bob for Robert).",
      +  "properties": {
      +    "name": {
      +      "description": "The other name as \"First Middle Last\", or its organization name.",
      +      "type": "string"
      +    },
      +    "type": {
      +      "description": "Registry name type, e.g. \"Former Name\", \"Professional Name\".",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "name"
      +  ],
      +  "type": "object"
      +}
  3. Changed2 schema fields changed
    • changedInput schema / properties / specialty / description
      Previous value: -"Plain-language specialty (e.g. \"pediatric cardiologist\"), resolved through the bundled NUCC taxonomy to exact descriptions before searching. The matched taxonomy is echoed in the result. Mutually exclusive with taxonomy_description."New value: +"Plain-language specialty (e.g. \"pediatric cardiologist\"), resolved through the bundled NUCC taxonomy to exact descriptions before searching. Codes NUCC marks inactive are never resolved. The matched taxonomy is echoed in the result. Mutually exclusive with taxonomy_description."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_search_criteria`: No effective search criterion was provided. `conflicting_specialty`: Both specialty and taxonomy_description were supplied. `unresolved_specialty`: The specialty term matched no NUCC taxonomy. `invalid_search_field`: The registry returned a field error (e.g. wildcard under 2 characters, bad provider type). Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_search_criteria`: No effective search criterion was provided. `conflicting_specialty`: Both specialty and taxonomy_description were supplied. `unresolved_specialty`: The specialty term matched no active NUCC taxonomy (the message names any inactive codes it matched). `invalid_search_field`: The registry returned a field error (e.g. wildcard under 2 characters, bad provider type). Other values are possible when a failure originates below the handler."
  4. Changed4 schema fields changed
    • changedOutput schema / properties / providers / items / properties / city / description
      Previous value: -"Practice-location city when present."New value: +"Primary practice-location city when present."
    • addedOutput schema / properties / providers / items / properties / matchedLocation
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The additional practice location that satisfied the requested city/state/postal_code. Present only when the primary practice location is elsewhere.",
      +  "properties": {
      +    "city": {
      +      "description": "City of the matching practice location.",
      +      "type": "string"
      +    },
      +    "postalCode": {
      +      "description": "Postal/ZIP code of the matching practice location.",
      +      "type": "string"
      +    },
      +    "state": {
      +      "description": "State of the matching practice location.",
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedOutput schema / properties / providers / items / properties / postalCode / description
      Previous value: -"Practice-location postal/ZIP code when present."New value: +"Primary practice-location postal/ZIP code when present."
    • changedOutput schema / properties / providers / items / properties / state / description
      Previous value: -"Practice-location state when present."New value: +"Primary practice-location state when present."
  5. Changed12 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / name_search / description
      Previous value: -"Convenience shortcut: a single person's name, split into first/last heuristically. For precise control use first_name/last_name."New value: +"One person's name. The first token becomes first_name and the last token becomes last_name; use first_name/last_name when middle names or multi-part surnames matter."
    • changedInput schema / properties / state / description
      Previous value: -"2-letter state code (e.g. \"WA\"). The registry rejects state-only searches — pair it with another criterion. Blank values from form-based clients are treated as omitted."New value: +"2-letter state code (e.g. \"WA\"). The registry rejects state-only searches, so another criterion is required. A blank value is treated as omitted."
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "providers"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • changedOutput schema / properties / appliedTaxonomyDescription / description
      Previous value: -"The single taxonomy_description sent to the registry (from specialty resolution or the raw escape hatch)."New value: +"The exact NUCC specialization or classification used as the specialty filter."
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `no_search_criteria`: No effective search criterion was provided. `conflicting_specialty`: Both specialty and taxonomy_description were supplied. `unresolved_specialty`: The specialty term matched no NUCC taxonomy. `invalid_search_field`: The registry returned a field error (e.g. wildcard under 2 characters, bad provider type). Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "no_search_criteria",
      +            "conflicting_specialty",
      +            "unresolved_specialty",
      +            "invalid_search_field"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / resolvedTaxonomies / description
      Previous value: -"The taxonomy candidates the specialty term resolved to; the first was sent to the registry. Re-run with taxonomy_description to pick a different one."New value: +"Taxonomy candidates ranked for the specialty term. The first candidate supplies appliedTaxonomyDescription; a different candidate can be selected through taxonomy_description."
    • changedOutput schema / properties / resolvedTaxonomies / items / properties / description / description
      Previous value: -"The taxonomy description (specialization or classification) the registry matched on — the value sent as taxonomy_description."New value: +"Search-compatible NUCC specialization or classification for this candidate."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the returned page hit the limit — more may match."New value: +"True when the NPPES page contained at least cap providers before location constraints were applied; more may match even when shown is below cap."
    • removedOutput schema / required
      Removed value: -[
      -  "providers"
      -]
  6. Changed5 schema fields changed
    • addedInput schema / properties / state / anyOf
      Added value: +[
      +  {
      +    "const": "",
      +    "type": "string"
      +  },
      +  {
      +    "description": "2-letter state code (e.g. \"WA\").",
      +    "pattern": "^[A-Z]{2}$",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / state / description
      Previous value: -"2-letter state code (e.g. \"WA\"). The registry rejects state-only searches — pair it with another criterion."New value: +"2-letter state code (e.g. \"WA\"). The registry rejects state-only searches — pair it with another criterion. Blank values from form-based clients are treated as omitted."
    • removedInput schema / properties / state / pattern
      Removed value: -"^[A-Z]{2}$"
    • removedInput schema / properties / state / type
      Removed value: -"string"
    • addedOutput schema / properties / providers / items / properties / postalCode
      Added value: +{
      +  "description": "Practice-location postal/ZIP code when present.",
      +  "type": "string"
      +}
  7. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover readOnly, idempotent, openWorld, but the description adds substantial operational context beyond them: the 1200-match window, nextPage pagination and the terminal-window continuationPostalCodes, practice-vs-mailing address semantics with matchedLocation, former-name matching with matchedOtherName, and that no true total is ever reported. These are non-obvious behaviors an agent needs.

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?

Front-loaded with purpose and searchable fields, then escalates to constraint and pagination edge cases; nearly every sentence carries operational value. It is dense and long, and a few clauses (e.g. location-not-in-specialty) could be tightened, but there is little true waste.

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?

For a 13-parameter, open-world registry search with an output schema covering return values, the description supplies everything an agent needs: criteria constraints, address-scope semantics, pagination limits, and sibling routing. Nothing material is left unstated.

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?

Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema: how specialty resolution chooses the top match and echoes all candidates in metadata, that name_search tokenizes into first/last, and that provider_type must align with the name field used. Some content (wildcard rules, ZIP+4 nuance) duplicates the schema, keeping it from a 5.

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?

States a specific verb and resource ('Search the NPPES NPI registry') plus the full set of supported criteria, and explicitly routes to the sibling npi_get_provider for full records. An agent can distinguish this search tool from both siblings without opening their schemas.

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?

Gives explicit selection rules: use specialty for plain-language terms vs taxonomy_description for known codes (mutually exclusive), location goes in dedicated inputs not specialty, name_search vs first_name/last_name, and the hard constraint that at least one criterion is required with state-only rejected. This is when/when-not/alternatives guidance at its fullest.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.