Skip to main content
Glama

npi-providers-mcp-server

Npi Lookup Taxonomy

npi_lookup_taxonomy
Read-onlyIdempotent

Resolve and browse the NUCC Healthcare Provider Taxonomy — the specialty code set NPPES uses — fully offline (bundled). Mode resolve turns a plain-language specialty (e.g. "cardiologist", "heart doctor") into matching active taxonomy entries, excluding codes NUCC marks inactive; mode get returns the full entry for an exact code, including NUCC's Notes; mode browse walks the hierarchy (grouping → classification → specialization), optionally filtered by grouping and NUCC section. Individual includes Group codes; section does not determine NPI entity type, which comes from NPPES enumeration_type. Every entry carries its status, and an inactive code names its replacement when NUCC gives one; get and browse still return inactive codes. A resolved entry's specialization, or its classification when specialization is absent, maps directly to npi_search_providers.taxonomy_description.

Input Schema

NameRequiredDescriptionDefault
codeNoFor get only: exact NUCC taxonomy code, e.g. "207RC0000X".
modeYesresolve: plain-language specialty to codes; get: exact code; browse: hierarchy.
skipNoEntries to skip before the page (0–1000). Keep the same query and limit, then raise skip by limit each call.
limitNoMaximum entries for resolve/browse; defaults to 20. Positive integers above 50 are clamped to 50 unless NPI_CLAMP_LIMITS is disabled.
queryNoThe plain-language specialty term to resolve, e.g. "pediatric cardiologist".
sectionNoFor browse only: NUCC section, independent of NPI entity type. Individual includes Group codes.
groupingNoFilter to a top-level grouping by case-insensitive substring, e.g. "physicians".

Output Schema

NameRequiredDescriptionDefault
capNoThe limit that was applied.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of entries returned.
noticeNoGuidance — how to page a truncated result with skip, or how to broaden when nothing matched.
matchesNoMatching taxonomy entries. For mode "get" this is the single requested entry; for "resolve"/"browse" it is the ranked/sorted matches up to limit.
truncatedNoTrue when the list was capped at `limit` (more entries may match).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • addedInput schema / additionalProperties
      Added value: +false
    • removedInput schema / oneOf
      Removed value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "limit": {
      -        "default": 20,
      -        "description": "Maximum matching entries to return (1–50).",
      -        "maximum": 50,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "mode": {
      -        "const": "resolve",
      -        "description": "Resolve a plain-language specialty to taxonomy codes.",
      -        "type": "string"
      -      },
      -      "query": {
      -        "description": "The plain-language specialty term to resolve, e.g. \"pediatric cardiologist\".",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "skip": {
      -        "default": 0,
      -        "description": "Entries to skip before the page (0–1000). Keep the same query and limit, then raise skip by limit each call.",
      -        "maximum": 1000,
      -        "minimum": 0,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "mode",
      -      "query"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "code": {
      -        "description": "The exact NUCC taxonomy code, e.g. \"207RC0000X\".",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "mode": {
      -        "const": "get",
      -        "description": "Fetch one exact taxonomy entry by code.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "mode",
      -      "code"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "grouping": {
      -        "description": "Filter to a top-level grouping by case-insensitive substring, e.g. \"physicians\".",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "default": 20,
      -        "description": "Maximum entries to return (1–50).",
      -        "maximum": 50,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "mode": {
      -        "const": "browse",
      -        "description": "Browse the taxonomy hierarchy.",
      -        "type": "string"
      -      },
      -      "section": {
      -        "description": "Filter by NPI section: Individual (NPI-1) or Non-Individual (NPI-2).",
      -        "enum": [
      -          "Individual",
      -          "Non-Individual"
      -        ],
      -        "type": "string"
      -      },
      -      "skip": {
      -        "default": 0,
      -        "description": "Entries to skip before the page (0–1000). Keep the same filters and limit, then raise skip by limit each call.",
      -        "maximum": 1000,
      -        "minimum": 0,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  }
      -]
    • addedInput schema / properties
      Added value: +{
      +  "code": {
      +    "description": "For get only: exact NUCC taxonomy code, e.g. \"207RC0000X\".",
      +    "type": "string"
      +  },
      +  "grouping": {
      +    "description": "Filter to a top-level grouping by case-insensitive substring, e.g. \"physicians\".",
      +    "type": "string"
      +  },
      +  "limit": {
      +    "description": "Maximum entries for resolve/browse; defaults to 20. Positive integers above 50 are clamped to 50 unless NPI_CLAMP_LIMITS is disabled.",
      +    "maximum": 9007199254740991,
      +    "minimum": 1,
      +    "type": "integer"
      +  },
      +  "mode": {
      +    "description": "resolve: plain-language specialty to codes; get: exact code; browse: hierarchy.",
      +    "enum": [
      +      "resolve",
      +      "get",
      +      "browse"
      +    ],
      +    "type": "string"
      +  },
      +  "query": {
      +    "description": "The plain-language specialty term to resolve, e.g. \"pediatric cardiologist\".",
      +    "type": "string"
      +  },
      +  "section": {
      +    "description": "For browse only: NUCC section, independent of NPI entity type. Individual includes Group codes.",
      +    "enum": [
      +      "Individual",
      +      "Non-Individual"
      +    ],
      +    "type": "string"
      +  },
      +  "skip": {
      +    "description": "Entries to skip before the page (0–1000). Keep the same query and limit, then raise skip by limit each call.",
      +    "maximum": 1000,
      +    "minimum": 0,
      +    "type": "integer"
      +  }
      +}
    • addedInput schema / required
      Added value: +[
      +  "mode"
      +]
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_match`: A get code matched no taxonomy entry, a resolve query matched no active one (the message names any inactive codes it matched), or a resolve query was made only of generic words (\"doctor\", \"M.D.\", \"specialist\") that name no specialty. `missing_argument`: The required query or code was present but blank after trimming. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_match`: A get code matched no taxonomy entry, a resolve query matched no active one (the message names any inactive codes it matched), or a resolve query was made only of generic words (\"doctor\", \"M.D.\", \"specialist\") that name no specialty. `missing_argument`: The required query or code was missing or blank after trimming. `wrong_mode_argument`: An explicitly supplied field belongs to a different mode. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_match",
      -  "missing_argument"
      -]New value: +[
      +  "no_match",
      +  "missing_argument",
      +  "wrong_mode_argument"
      +]
    • changedOutput schema / properties / matches / items / properties / section / description
      Previous value: -"NPI enumeration scope: Individual (NPI-1) or Non-Individual (NPI-2)."New value: +"NUCC section. Individual includes Group codes; Non-Individual covers facilities, suppliers and agencies. Provider entity type comes from NPPES enumeration_type."
  2. Changed1 schema field changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_match`: A get code matched no taxonomy entry, or a resolve query matched no active one (the message names any inactive codes it matched). `missing_argument`: The required query or code was present but blank after trimming. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_match`: A get code matched no taxonomy entry, a resolve query matched no active one (the message names any inactive codes it matched), or a resolve query was made only of generic words (\"doctor\", \"M.D.\", \"specialist\") that name no specialty. `missing_argument`: The required query or code was present but blank after trimming. Other values are possible when a failure originates below the handler."
  3. Changed5 schema fields changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_match`: A resolve query or get code matched no taxonomy entry. `missing_argument`: The required query or code was present but blank after trimming. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_match`: A get code matched no taxonomy entry, or a resolve query matched no active one (the message names any inactive codes it matched). `missing_argument`: The required query or code was present but blank after trimming. Other values are possible when a failure originates below the handler."
    • addedOutput schema / properties / matches / items / properties / notes
      Added value: +{
      +  "description": "NUCC Notes: sources, revision history, and status remarks. Returned by mode \"get\" only, when NUCC records a note.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / matches / items / properties / replacedBy
      Added value: +{
      +  "description": "For an inactive code, the active replacement code NUCC names, when it names one.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / matches / items / properties / status
      Added value: +{
      +  "description": "NUCC status. Inactive codes are no longer maintained: mode \"resolve\" excludes them, while \"get\" and \"browse\" return them.",
      +  "enum": [
      +    "active",
      +    "inactive"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / properties / matches / items / required
      Previous value: -[
      -  "code",
      -  "grouping",
      -  "classification",
      -  "displayName",
      -  "section"
      -]New value: +[
      +  "code",
      +  "grouping",
      +  "classification",
      +  "displayName",
      +  "section",
      +  "status"
      +]
  4. Changed8 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 / oneOf
      Added value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "limit": {
      +        "default": 20,
      +        "description": "Maximum matching entries to return (1–50).",
      +        "maximum": 50,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "mode": {
      +        "const": "resolve",
      +        "description": "Resolve a plain-language specialty to taxonomy codes.",
      +        "type": "string"
      +      },
      +      "query": {
      +        "description": "The plain-language specialty term to resolve, e.g. \"pediatric cardiologist\".",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "skip": {
      +        "default": 0,
      +        "description": "Entries to skip before the page (0–1000). Keep the same query and limit, then raise skip by limit each call.",
      +        "maximum": 1000,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "mode",
      +      "query"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "code": {
      +        "description": "The exact NUCC taxonomy code, e.g. \"207RC0000X\".",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "mode": {
      +        "const": "get",
      +        "description": "Fetch one exact taxonomy entry by code.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "mode",
      +      "code"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "grouping": {
      +        "description": "Filter to a top-level grouping by case-insensitive substring, e.g. \"physicians\".",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "default": 20,
      +        "description": "Maximum entries to return (1–50).",
      +        "maximum": 50,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "mode": {
      +        "const": "browse",
      +        "description": "Browse the taxonomy hierarchy.",
      +        "type": "string"
      +      },
      +      "section": {
      +        "description": "Filter by NPI section: Individual (NPI-1) or Non-Individual (NPI-2).",
      +        "enum": [
      +          "Individual",
      +          "Non-Individual"
      +        ],
      +        "type": "string"
      +      },
      +      "skip": {
      +        "default": 0,
      +        "description": "Entries to skip before the page (0–1000). Keep the same filters and limit, then raise skip by limit each call.",
      +        "maximum": 1000,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  }
      +]
    • removedInput schema / properties
      Removed value: -{
      -  "code": {
      -    "description": "For mode \"get\": the exact NUCC taxonomy code (e.g. \"207RC0000X\").",
      -    "type": "string"
      -  },
      -  "grouping": {
      -    "description": "For mode \"browse\": filter to a top-level grouping by case-insensitive substring (e.g. \"physicians\").",
      -    "type": "string"
      -  },
      -  "limit": {
      -    "default": 20,
      -    "description": "Maximum entries to return for resolve/browse (1–50). Ignored for get.",
      -    "maximum": 50,
      -    "minimum": 1,
      -    "type": "integer"
      -  },
      -  "mode": {
      -    "description": "resolve: plain term → codes. get: exact code → entry. browse: walk the hierarchy.",
      -    "enum": [
      -      "resolve",
      -      "get",
      -      "browse"
      -    ],
      -    "type": "string"
      -  },
      -  "query": {
      -    "description": "For mode \"resolve\": the plain-language specialty term to resolve (e.g. \"pediatric cardiologist\").",
      -    "type": "string"
      -  },
      -  "section": {
      -    "description": "For mode \"browse\": filter by NPI section — Individual (NPI-1) or Non-Individual (NPI-2).",
      -    "enum": [
      -      "Individual",
      -      "Non-Individual"
      -    ],
      -    "type": "string"
      -  },
      -  "skip": {
      -    "default": 0,
      -    "description": "Entries to skip before the page, for paging past a truncated resolve/browse result (0–1000). Keep the same query/filters and limit, raise skip by limit each call. Ignored for get.",
      -    "maximum": 1000,
      -    "minimum": 0,
      -    "type": "integer"
      -  }
      -}
    • removedInput schema / required
      Removed value: -[
      -  "mode"
      -]
    • 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": [
      +      "matches"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • 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_match`: A resolve query or get code matched no taxonomy entry. `missing_argument`: The required query or code was present but blank after trimming. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "no_match",
      +            "missing_argument"
      +          ],
      +          "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"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "matches"
      -]
  5. Changed2 schema fields changed
    • addedInput schema / properties / skip
      Added value: +{
      +  "default": 0,
      +  "description": "Entries to skip before the page, for paging past a truncated resolve/browse result (0–1000). Keep the same query/filters and limit, raise skip by limit each call. Ignored for get.",
      +  "maximum": 1000,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when nothing matched — suggests broadening or browsing the hierarchy."New value: +"Guidance — how to page a truncated result with skip, or how to broaden when nothing matched."
  6. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/closed-world, so the bar is met; the description goes further by disclosing that the dataset is fully offline and bundled, that inactive codes carry replacement pointers when NUCC supplies them, and how status is surfaced on every entry. That is genuine behavioral context an agent cannot get from the annotations.

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 the core identity, then modes, then caveats — no filler sentences. The mode clauses are packed into one long paragraph, which is dense but every clause carries distinct information; minor readability cost keeps it from a 5.

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?

With 7 parameters, enum modes, and an output schema already documenting return shape, the description fills exactly the remaining gaps: mode selection, inactive-code behavior, hierarchy traversal, and the handoff to npi_search_providers. Nothing an agent needs to invoke correctly is missing.

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 the baseline is 3; the description adds real meaning on top: `section` is independent of NPI entity type, and Individual includes Group codes. It does not elaborate on pagination interaction between skip/limit beyond what the schema already states, so it stops short of 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+resource (resolve/browse the NUCC Healthcare Provider Taxonomy) and enumerates all three modes with their distinct semantics. It also positions itself against the sibling by noting the resolved value maps directly to npi_search_providers.taxonomy_description, so an agent can tell where this tool ends and the sibling begins.

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?

Explicit mode routing: `resolve` for plain-language terms, `get` for exact codes, `browse` for hierarchy walking. It adds the non-obvious exclusion rule that `get`/`browse` still return inactive codes while `resolve` filters them out, and warns that `section` does not determine NPI entity type — a common misuse the agent would otherwise make before calling npi_get_provider.

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.