medical-codes-mcp-server

v0.2.3 pre-1.0

Offline US healthcare code lookup and crosswalk — ICD-10-CM, ICD-10-PCS, HCPCS Level II, and RxNorm drugs, keyless and deterministic.

medical-codes.caseyjhand.com/mcp
claude mcp add --transport http medical-codes-mcp-server https://medical-codes.caseyjhand.com/mcp
codex mcp add medical-codes-mcp-server --url https://medical-codes.caseyjhand.com/mcp
{
  "mcpServers": {
    "medical-codes-mcp-server": {
      "url": "https://medical-codes.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http medical-codes-mcp-server https://medical-codes.caseyjhand.com/mcp
{
  "mcpServers": {
    "medical-codes-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://medical-codes.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "medical-codes-mcp-server": {
      "type": "http",
      "url": "https://medical-codes.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://medical-codes.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

6

medcode_get_code

Decode one or more US medical codes to their official descriptions across ICD-10-CM (diagnoses), ICD-10-PCS (inpatient procedures), HCPCS Level II (supplies/drugs/services), and RxNorm (drugs, by RXCUI). Also decodes a National Drug Code (NDC) — hyphenated or 10/11-digit — directly to its RxNorm product offline, tagged `source: "NDC"`. Auto-detects the system from each code's shape; pass an explicit `system` only when a value is genuinely ambiguous. Accepts 1–50 codes and returns partial success: resolved codes in `found`, unresolved in `notFound` with a per-code reason, so one bad code never fails the batch. Set `includeHierarchy` to attach each code's parent and immediate children (with a `childrenTruncated` flag when a code has more children than the cap returns — walk the full set via medcode_browse_hierarchy or medcode_map_codes). The resolved `system` is echoed on every result for chaining into medcode_map_codes or a billability check.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "medcode_get_code",
    "arguments": {
      "codes": "<codes>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "codes": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "description": "A single code to decode (with or without dots), an RXCUI, or an NDC. Must not be blank or whitespace-only."
      },
      "description": "Codes to decode (1–50). Mixed systems are fine — each is detected independently. An NDC (hyphenated or 10/11-digit) decodes to its RxNorm product."
    },
    "system": {
      "description": "Force every code to be looked up in this system. Omit to auto-detect per code.",
      "type": "string",
      "enum": [
        "ICD10CM",
        "ICD10PCS",
        "HCPCS",
        "RXNORM"
      ]
    },
    "includeHierarchy": {
      "default": false,
      "description": "When true, attach each found code's parent and immediate children.",
      "type": "boolean"
    }
  },
  "required": [
    "codes",
    "includeHierarchy"
  ],
  "additionalProperties": false
}
view source ↗

medcode_search_codes

Find US medical codes whose official descriptions match a described concept, via full-text search over the bundled index. Every search term must appear — matched first as a token prefix, then as a substring so inflected and compound forms are also found (a "neuropathy" search surfaces "mononeuropathy"/"polyneuropathy" siblings too, not only a standalone "neuropathy" token). Filter by `system` (ICD10CM/ICD10PCS/HCPCS/RXNORM), `billableOnly` to exclude headers/categories, and `chapter`. Use when you have a clinical description and need the code — the reverse of medcode_get_code. Results echo the resolved system per row for chaining, rank exact prefix matches ahead of substring-only matches with a deterministic tie-break, and disclose truncation with a `nextCursor`: pass it back as `cursor` to page through the full ranked set.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "medcode_search_codes",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Clinical description to match, e.g. \"type 2 diabetes with neuropathy\". Must not be blank or whitespace-only."
    },
    "system": {
      "description": "Restrict results to one system. Omit to search all bundled systems.",
      "type": "string",
      "enum": [
        "ICD10CM",
        "ICD10PCS",
        "HCPCS",
        "RXNORM"
      ]
    },
    "billableOnly": {
      "default": false,
      "description": "When true, return only billable leaf codes (exclude headers/categories).",
      "type": "boolean"
    },
    "chapter": {
      "description": "Restrict to a chapter/range bucket (the value from a code's `chapter` field).",
      "type": "string"
    },
    "limit": {
      "description": "Max codes per page. Defaults to the server's MEDCODE_MAX_RESULTS (50), ceiling 200.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "cursor": {
      "description": "Opaque continuation token from a previous response's `nextCursor`, to fetch the next page of the same ranked result set. Omit for the first page.",
      "type": "string"
    }
  },
  "required": [
    "query",
    "billableOnly"
  ],
  "additionalProperties": false
}
view source ↗

medcode_check_code

Validate whether a US medical code exists, is current, and is billable in the active bundled release. Returns a discriminated status — valid_billable, valid_not_billable, valid_header, or terminated — with a `whyNot` explaining non-billable and terminated cases (e.g. "valid ICD-10-CM category but not billable — submit a more specific child code"). This is the detail a coder needs before submitting a claim. Auto-detects the system from the code's shape; pass an explicit `system` to disambiguate. A non-billable or terminated code is a successful result with a whyNot, not an error — only a code that exists in no bundled system raises unknown_code.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "medcode_check_code",
    "arguments": {
      "code": "<code>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "minLength": 1,
      "description": "The code to validate, with or without dots. Must not be blank or whitespace-only."
    },
    "system": {
      "description": "Force the lookup into this system. Omit to auto-detect from the code's shape.",
      "type": "string",
      "enum": [
        "ICD10CM",
        "ICD10PCS",
        "HCPCS",
        "RXNORM"
      ]
    }
  },
  "required": [
    "code"
  ],
  "additionalProperties": false
}
view source ↗

medcode_map_codes

Crosswalk a US medical code or drug across systems and within a hierarchy. Hierarchy directions: `parents` and `children` walk a code's prefix hierarchy one level per call — immediate parent/children only (depth-1); call iteratively for the full ancestor or descendant path (ICD-10-CM/HCPCS; ICD-10-PCS codes have no prefix parent). A resolvable code with no edge in the requested direction is a successful empty result with a notice, not an error. Drug directions (RxNorm): `name_to_rxcui` (drug name → RXCUI), `ndc_to_rxcui` and `rxcui_to_ndc` (NDC ↔ RXCUI; NDCs accepted hyphenated or 10/11-digit), `rxcui_to_ingredients` and `rxcui_to_brands` (RXCUI → ingredient/brand RXCUIs). Every result carries `source` provenance (which system or edge answered) so a chained call (e.g. into openfda with a resolved NDC) uses the right identifier. The `children` and `name_to_rxcui` directions can return large sets and paginate: a `nextCursor` in the response is passed back as `cursor` (with an optional `limit` page size) to walk the full set; the point directions ignore both.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "medcode_map_codes",
    "arguments": {
      "from": "<from>",
      "direction": "<direction>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "from": {
      "type": "string",
      "minLength": 1,
      "description": "The source value: a code (for parents/children), a drug name, an NDC, or an RXCUI. Must not be blank or whitespace-only."
    },
    "direction": {
      "type": "string",
      "enum": [
        "parents",
        "children",
        "name_to_rxcui",
        "ndc_to_rxcui",
        "rxcui_to_ndc",
        "rxcui_to_ingredients",
        "rxcui_to_brands"
      ],
      "description": "What to map to. parents/children return the immediate parent or children only (depth-1) — call iteratively to walk a full path; the rxcui/ndc/name directions are RxNorm drug crosswalks."
    },
    "system": {
      "description": "For parents/children, force the source code into this system. Omit to auto-detect.",
      "type": "string",
      "enum": [
        "ICD10CM",
        "ICD10PCS",
        "HCPCS",
        "RXNORM"
      ]
    },
    "limit": {
      "description": "Max results per page for the paginated directions (children, name_to_rxcui). Defaults to MEDCODE_MAX_RESULTS (50), ceiling 200. Ignored by the point directions.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "cursor": {
      "description": "Opaque continuation token from a previous response's `nextCursor`, for the paginated directions (children, name_to_rxcui). Omit for the first page.",
      "type": "string"
    }
  },
  "required": [
    "from",
    "direction"
  ],
  "additionalProperties": false
}
view source ↗

medcode_browse_hierarchy

Walk a US medical code system's hierarchy for discovery without a search term. With no `node`, returns the top-level entries (ICD-10-CM categories, HCPCS range buckets, or ICD-10-PCS first-axis values). With a `node`, returns its immediate children. ICD-10-CM and HCPCS use a prefix hierarchy (a shorter code is the parent of a longer one); ICD-10-PCS is axis-based — each of its 7 characters is an independent axis (section, body system, root operation, body part, approach, device, qualifier), but only the top-level Section axis is browsable (omit `node`): positions 2–7 are context-dependent on the preceding axis path and are not enumerable from a flat partial code. Lets an agent orient in an unfamiliar system or enumerate a category's specific codes. A large child set paginates: when the response carries a `nextCursor`, pass it back as `cursor` to fetch the next page.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "medcode_browse_hierarchy",
    "arguments": {
      "system": "<system>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "system": {
      "type": "string",
      "enum": [
        "ICD10CM",
        "ICD10PCS",
        "HCPCS",
        "RXNORM"
      ],
      "description": "The code system to browse."
    },
    "node": {
      "description": "A node to expand — or omit / pass an empty string for the top level. For ICD-10-CM/HCPCS, a code whose children to list; ICD-10-PCS supports only top-level Section browsing. Must not be blank or whitespace-only when provided.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "minLength": 1,
          "description": "A code whose children to list (ICD-10-CM/HCPCS). ICD-10-PCS supports only top-level Section browsing — a partial PCS code does not expand to next-position axis values."
        }
      ]
    },
    "limit": {
      "description": "Max entries per page. Defaults to MEDCODE_MAX_RESULTS (50), ceiling 200.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "cursor": {
      "description": "Opaque continuation token from a previous response's `nextCursor`, to fetch the next page of children/entries. Omit for the top of the list.",
      "type": "string"
    }
  },
  "required": [
    "system"
  ],
  "additionalProperties": false
}
view source ↗

medcode_list_systems

List the bundled US medical code systems with their release identifiers, effective dates, and code counts. Confirms which ICD-10-CM fiscal year, ICD-10-PCS fiscal year, HCPCS Level II release, and RxNorm normalized set are active before acting on any decode, search, or crosswalk result. The corpus is offline and built at package-build time — this call reports exactly which release is baked into the running server. ICD-10-CM/PCS are the US clinical modifications, not the ICD-10/ICD-11 base.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "medcode_list_systems",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
view source ↗