@sequoiaport/codes
Advanced tools
+183
| # SequoiaCodex API — Agent System Prompt | ||
| You now have access to the SequoiaCodex medical coding API. Use it to search and look up ICD-10, CPT, HCPCS, SNOMED, RxNorm, LOINC codes, and Medicare coverage guidelines (LCD/NCD). | ||
| ## CRITICAL: Take things one step at a time | ||
| Do NOT try to do everything at once. Complete **Setup** fully before moving on to **Usage**. | ||
| ## Domain Guide — READ THIS CAREFULLY | ||
| There are TWO different domains. Using the wrong one will fail. | ||
| - **sequoiacodes.com** — ONLY for the auth flow (creating sessions, polling for keys, seeing the actual UI and dashboard for a user). Do NOT use this domain for anything other than the auth flow. | ||
| - **api.sequoiacodes.com** — ONLY for making API queries once you have a key. Do NOT use this domain for auth. | ||
| --- | ||
| # Setup | ||
| Complete both steps below before making any API queries. | ||
| ## Step 1: Get an API key | ||
| **Before doing anything else**, check if the `SEQUOIA_CODES_API_KEY` environment variable is already set. If it is, you already have a key — skip the rest of this step and go directly to Step 2. | ||
| **Only if no key is found**, ask the user: | ||
| > "Do you already have a SequoiaCodex API key, or would you like me to generate one for you?" | ||
| Wait for their response. Do NOT proceed to Step 2 until this is resolved. | ||
| - **If they have a key**: Ask them to provide it, then move on to Step 2. | ||
| - **If they want you to generate one**: Follow the Agent Auth Flow below, then move on to Step 2 once you have the key. | ||
| ### Agent Auth Flow | ||
| **IMPORTANT**: You MUST use `curl` via a shell/bash tool for these requests. Do NOT use a fetch/GET tool — the first request is a POST and will fail with a 405 if sent as GET. | ||
| Use **sequoiacodes.com** (NOT api.sequoiacodes.com) for auth. | ||
| #### 1. Create an auth session | ||
| Run this exact curl command: | ||
| ```bash | ||
| curl -s -X POST https://sequoiacodes.com/api/agent-auth/session \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"agent_id": "your-agent-name"}' | ||
| ``` | ||
| Response: | ||
| ```json | ||
| { | ||
| "session_id": "...", | ||
| "session_secret": "...", | ||
| "auth_url": "...", | ||
| "expires_at": ... | ||
| } | ||
| ``` | ||
| Save the `session_id`, `session_secret`, and `auth_url` from the response. | ||
| #### 2. Show the auth URL to the user | ||
| Display the `auth_url` to the user and ask them to open it in their browser to sign in and approve the connection. **Wait for the user to confirm they have completed sign-in before polling.** | ||
| #### 3. Poll for the API key | ||
| Once the user confirms they signed in, run this curl command (replacing the placeholders with values from step 1): | ||
| ```bash | ||
| curl -s https://sequoiacodes.com/api/agent-auth/session/{session_id} \ | ||
| -H "Authorization: Bearer {session_secret}" | ||
| ``` | ||
| If the response shows `"status": "pending"`, wait 3–5 seconds and run the same curl again. Repeat until status is `"completed"`. | ||
| #### 4. Retrieve the API key | ||
| When status is `"completed"`, the response includes the API key: | ||
| ```json | ||
| { "status": "completed", "api_key": "sk_live_seq_..." } | ||
| ``` | ||
| **Store this key securely — it is only returned once.** The session expires after 10 minutes. | ||
| ## Step 2: Read the documentation | ||
| Now that you have a key, read the docs at https://github.com/Sequoia-Port/codes to understand the available endpoints, parameters, and response formats. Do NOT guess at endpoints or parameters — always consult the docs first. | ||
| **Once you have reviewed the docs, you are ready to move on to Usage.** | ||
| --- | ||
| # Usage | ||
| You must have an API key and have read the documentation before proceeding. | ||
| ## Making API requests | ||
| Use **api.sequoiacodes.com** for ALL data queries. Run queries using `curl` via a shell/bash tool. | ||
| ``` | ||
| Base URL: https://api.sequoiacodes.com | ||
| Auth header: Authorization: Bearer {api_key} | ||
| Method: GET for all endpoints | ||
| URL pattern: /v1/{system}/{action}?{params} | ||
| ``` | ||
| ### Available Endpoints | ||
| | System | Action | Params | | ||
| |----------|---------------------------|------------------------------------| | ||
| | icd10 | searchCode | query, limit?, billingOnly? | | ||
| | icd10 | identifyCode | code | | ||
| | icd10 | getChapters | (none) | | ||
| | cpt | searchCode | query, limit? | | ||
| | cpt | identifyCode | code | | ||
| | cpt | getCost | code | | ||
| | cpt | linkIcd10 | code | | ||
| | hcpcs | searchCode | query, limit? | | ||
| | hcpcs | identifyCode | code | | ||
| | hcpcs | getCost | code | | ||
| | snomed | searchCode | query, limit? | | ||
| | snomed | identifyCode | code | | ||
| | rxnorm | searchCode | query, limit? | | ||
| | rxnorm | identifyCode | type (ndc or rxcui), code | | ||
| | rxnorm | getIngredients | rxcui | | ||
| | loinc | searchCode | query, limit? | | ||
| | loinc | identifyCode | code | | ||
| | loinc | getPanelMembers | code | | ||
| | lcd | searchGuidelines | query, limit? | | ||
| | lcd | identifyGuideline | id | | ||
| | ncd | searchGuidelines | query, limit? | | ||
| | ncd | identifyGuideline | id?, section? | | ||
| | clinical | checkCoverage | (see /v1/clinical/getMetadata) | | ||
| | clinical | getProceduresForDiagnosis | (see /v1/clinical/getMetadata) | | ||
| | clinical | getMetadata | (none) | | ||
| All search endpoints accept `query` (string) and optional `limit` (1–200). | ||
| Use `searchCode` to find codes by description. Use `identifyCode` to look up a specific code. | ||
| ### Example | ||
| ```bash | ||
| curl -s "https://api.sequoiacodes.com/v1/icd10/searchCode?query=hypertension" \ | ||
| -H "Authorization: Bearer sk_live_seq_..." | ||
| ``` | ||
| ```json | ||
| { | ||
| "success": true, | ||
| "data": { | ||
| "query": "hypertension", | ||
| "count": 3, | ||
| "results": [ | ||
| { | ||
| "code": "I10", | ||
| "short_description": "Essential (primary) hypertension", | ||
| "long_description": "Essential (primary) hypertension", | ||
| "is_billable": true, | ||
| "chapter": "IX", | ||
| "similarity": 0.98 | ||
| } | ||
| ] | ||
| }, | ||
| "version": "v1" | ||
| } | ||
| ``` | ||
| Responses follow a consistent `{ success, data, version }` envelope. | ||
| --- | ||
| ## Quick Reference | ||
| | What you're doing | Domain | | ||
| |---------------------------|---------------------------------| | ||
| | Creating auth session | sequoiacodes.com | | ||
| | Polling for API key | sequoiacodes.com | | ||
| | Making API data queries | api.sequoiacodes.com | | ||
| | Reading documentation | github.com/Sequoia-Port/codes | |
+581
| #!/usr/bin/env node | ||
| "use strict"; | ||
| // src/mcp.ts | ||
| var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js"); | ||
| var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js"); | ||
| var import_zod4 = require("zod"); | ||
| // src/errors.ts | ||
| var CodesApiError = class extends Error { | ||
| constructor(status, message, action) { | ||
| super(message); | ||
| this.status = status; | ||
| this.action = action; | ||
| this.name = "CodesApiError"; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| name: this.name, | ||
| status: this.status, | ||
| message: this.message, | ||
| action: this.action | ||
| }; | ||
| } | ||
| }; | ||
| // src/engines.ts | ||
| var import_zod = require("zod"); | ||
| var SnomedSearchCodeInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var SnomedIdentifyCodeInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var SnomedCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchCode(input) { | ||
| const validated = SnomedSearchCodeInputSchema.parse(input); | ||
| return this.request( | ||
| "snomed/searchCode", | ||
| validated | ||
| ); | ||
| } | ||
| async identifyCode(input) { | ||
| const validated = SnomedIdentifyCodeInputSchema.parse(input); | ||
| return this.request("snomed/identifyCode", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| }; | ||
| var Icd10SearchCodeInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional(), | ||
| billingOnly: import_zod.z.boolean().optional() | ||
| }); | ||
| var Icd10IdentifyCodeInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var Icd10Category = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchCode(input) { | ||
| const validated = Icd10SearchCodeInputSchema.parse(input); | ||
| return this.request("icd10/searchCode", validated); | ||
| } | ||
| async identifyCode(input) { | ||
| const validated = Icd10IdentifyCodeInputSchema.parse(input); | ||
| return this.request("icd10/identifyCode", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| async getChapters() { | ||
| return this.request("icd10/getChapters", {}); | ||
| } | ||
| }; | ||
| var CptSearchCodeInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var CptIdentifyCodeInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var CptGetCostInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var CptLinkIcd10InputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var CptCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchCode(input) { | ||
| const validated = CptSearchCodeInputSchema.parse(input); | ||
| return this.request("cpt/searchCode", validated); | ||
| } | ||
| async identifyCode(input) { | ||
| const validated = CptIdentifyCodeInputSchema.parse(input); | ||
| return this.request("cpt/identifyCode", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| async getCost(input) { | ||
| const validated = CptGetCostInputSchema.parse(input); | ||
| return this.request("cpt/getCost", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| async linkIcd10(input) { | ||
| const validated = CptLinkIcd10InputSchema.parse(input); | ||
| return this.request("cpt/linkIcd10", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| }; | ||
| var HcpcsSearchCodeInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var HcpcsIdentifyCodeInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var HcpcsGetCostInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var HcpcsCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchCode(input) { | ||
| const validated = HcpcsSearchCodeInputSchema.parse(input); | ||
| return this.request("hcpcs/searchCode", validated); | ||
| } | ||
| async identifyCode(input) { | ||
| const validated = HcpcsIdentifyCodeInputSchema.parse(input); | ||
| return this.request("hcpcs/identifyCode", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| async getCost(input) { | ||
| const validated = HcpcsGetCostInputSchema.parse(input); | ||
| return this.request("hcpcs/getCost", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| }; | ||
| var LoincSearchCodeInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var LoincIdentifyCodeInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var LoincGetPanelMembersInputSchema = import_zod.z.object({ | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var LoincCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchCode(input) { | ||
| const validated = LoincSearchCodeInputSchema.parse(input); | ||
| return this.request( | ||
| "loinc/searchCode", | ||
| validated | ||
| ); | ||
| } | ||
| async identifyCode(input) { | ||
| const validated = LoincIdentifyCodeInputSchema.parse(input); | ||
| return this.request("loinc/identifyCode", { | ||
| code: validated.code | ||
| }); | ||
| } | ||
| async getPanelMembers(input) { | ||
| const validated = LoincGetPanelMembersInputSchema.parse(input); | ||
| return this.request( | ||
| "loinc/getPanelMembers", | ||
| { code: validated.code } | ||
| ); | ||
| } | ||
| }; | ||
| var RxnormSearchCodeInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var RxnormIdentifyCodeInputSchema = import_zod.z.object({ | ||
| type: import_zod.z.enum(["ndc", "rxcui"]), | ||
| code: import_zod.z.string().min(1) | ||
| }); | ||
| var RxnormGetIngredientsInputSchema = import_zod.z.object({ | ||
| rxcui: import_zod.z.string().min(1) | ||
| }); | ||
| var RxnormCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchCode(input) { | ||
| const validated = RxnormSearchCodeInputSchema.parse(input); | ||
| return this.request("rxnorm/searchCode", validated); | ||
| } | ||
| async identifyCode(input) { | ||
| const validated = RxnormIdentifyCodeInputSchema.parse(input); | ||
| return this.request( | ||
| "rxnorm/identifyCode", | ||
| { type: validated.type, code: validated.code } | ||
| ); | ||
| } | ||
| async getIngredients(input) { | ||
| const validated = RxnormGetIngredientsInputSchema.parse(input); | ||
| return this.request( | ||
| "rxnorm/getIngredients", | ||
| validated | ||
| ); | ||
| } | ||
| }; | ||
| var LcdSearchGuidelinesInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var LcdIdentifyGuidelineInputSchema = import_zod.z.object({ | ||
| id: import_zod.z.string().min(1) | ||
| }); | ||
| var LcdCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchGuidelines(input) { | ||
| const validated = LcdSearchGuidelinesInputSchema.parse(input); | ||
| return this.request( | ||
| "lcd/searchGuidelines", | ||
| validated | ||
| ); | ||
| } | ||
| async identifyGuideline(input) { | ||
| const validated = LcdIdentifyGuidelineInputSchema.parse(input); | ||
| return this.request("lcd/identifyGuideline", { | ||
| id: validated.id | ||
| }); | ||
| } | ||
| }; | ||
| var NcdSearchGuidelinesInputSchema = import_zod.z.object({ | ||
| query: import_zod.z.string().min(1), | ||
| limit: import_zod.z.number().int().min(1).max(200).optional() | ||
| }); | ||
| var NcdIdentifyGuidelineInputSchema = import_zod.z.object({ | ||
| id: import_zod.z.string().optional(), | ||
| section: import_zod.z.string().optional() | ||
| }).refine((data) => data.id || data.section, { | ||
| message: "Either id or section must be provided" | ||
| }); | ||
| var NcdCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| async searchGuidelines(input) { | ||
| const validated = NcdSearchGuidelinesInputSchema.parse(input); | ||
| return this.request( | ||
| "ncd/searchGuidelines", | ||
| validated | ||
| ); | ||
| } | ||
| async identifyGuideline(input) { | ||
| const validated = NcdIdentifyGuidelineInputSchema.parse(input); | ||
| return this.request("ncd/identifyGuideline", { | ||
| id: validated.id, | ||
| section: validated.section | ||
| }); | ||
| } | ||
| }; | ||
| // src/schemas/clinical.ts | ||
| var import_zod2 = require("zod"); | ||
| var DiagnosisToProceduresInputSchema = import_zod2.z.object({ | ||
| snomed_id: import_zod2.z.string().optional(), | ||
| icd10_code: import_zod2.z.string().optional(), | ||
| query: import_zod2.z.string().optional() | ||
| }); | ||
| var CoverageCheckInputSchema = import_zod2.z.object({ | ||
| cpt_code: import_zod2.z.string().min(1), | ||
| icd10_code: import_zod2.z.string().optional() | ||
| }); | ||
| var DiagnosisToProceduresOutputSchema = import_zod2.z.object({ | ||
| snomed_id: import_zod2.z.string().optional(), | ||
| icd10_code: import_zod2.z.string().optional(), | ||
| icd10_mappings: import_zod2.z.array(import_zod2.z.record(import_zod2.z.unknown())).optional(), | ||
| procedures: import_zod2.z.array(import_zod2.z.record(import_zod2.z.unknown())).optional() | ||
| }); | ||
| var CoverageCheckOutputSchema = import_zod2.z.object({ | ||
| cpt_code: import_zod2.z.string(), | ||
| icd10_code: import_zod2.z.string().optional(), | ||
| lcd: import_zod2.z.record(import_zod2.z.unknown()).optional(), | ||
| has_guidelines: import_zod2.z.boolean(), | ||
| diagnosis_covered: import_zod2.z.boolean().optional() | ||
| }); | ||
| var GetCategoriesOutputSchema = import_zod2.z.object({ | ||
| snomed_semantic_tags: import_zod2.z.record(import_zod2.z.unknown()).optional(), | ||
| icd10_chapters: import_zod2.z.array(import_zod2.z.record(import_zod2.z.unknown())).optional(), | ||
| cpt_categories: import_zod2.z.array(import_zod2.z.record(import_zod2.z.unknown())).optional() | ||
| }); | ||
| // src/schemas/system.ts | ||
| var import_zod3 = require("zod"); | ||
| var GetResultInputSchema = import_zod3.z.object({ | ||
| request_id: import_zod3.z.string().min(1) | ||
| }); | ||
| var GetResultOutputSchema = import_zod3.z.object({ | ||
| request_id: import_zod3.z.string(), | ||
| status: import_zod3.z.enum(["pending", "running", "completed", "failed"]), | ||
| query: import_zod3.z.string().optional(), | ||
| result: import_zod3.z.record(import_zod3.z.unknown()).optional(), | ||
| error: import_zod3.z.string().optional() | ||
| }); | ||
| var EngineStatusSchema = import_zod3.z.record(import_zod3.z.enum(["ok", "error", "unknown"])); | ||
| var HealthOutputSchema = import_zod3.z.object({ | ||
| status: import_zod3.z.enum(["ok", "degraded"]), | ||
| version: import_zod3.z.string().optional(), | ||
| environment: import_zod3.z.string().optional(), | ||
| engines: EngineStatusSchema.optional() | ||
| }); | ||
| // src/client.ts | ||
| var ClinicalCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| /** Check LCD coverage for a CPT code + optional ICD-10 pair */ | ||
| async checkCoverage(input) { | ||
| const validated = CoverageCheckInputSchema.parse(input); | ||
| return this.request( | ||
| "clinical/checkCoverage", | ||
| validated | ||
| ); | ||
| } | ||
| /** Map a diagnosis (SNOMED or ICD-10) to relevant procedures */ | ||
| async getProceduresForDiagnosis(input) { | ||
| const validated = DiagnosisToProceduresInputSchema.parse(input); | ||
| return this.request( | ||
| "clinical/getProceduresForDiagnosis", | ||
| validated | ||
| ); | ||
| } | ||
| /** Get metadata/categories from all engines (semantic tags, chapters, etc.) */ | ||
| async getMetadata() { | ||
| return this.request("clinical/getMetadata", {}); | ||
| } | ||
| }; | ||
| var SystemCategory = class { | ||
| constructor(request) { | ||
| this.request = request; | ||
| } | ||
| /** Get async request result by ID */ | ||
| async getResult(input) { | ||
| const validated = GetResultInputSchema.parse(input); | ||
| return this.request("system/getResult", validated); | ||
| } | ||
| /** Health check all engines */ | ||
| async health() { | ||
| return this.request("system/health", {}); | ||
| } | ||
| }; | ||
| var DEFAULT_BASE_URL = "https://api.sequoiacodes.com"; | ||
| var DEFAULT_VERSION = "v1"; | ||
| var SequoiaCodesClient = class { | ||
| apiKey; | ||
| baseUrl; | ||
| version; | ||
| // ========================================================================== | ||
| // Orchestrator Categories | ||
| // ========================================================================== | ||
| /** Clinical orchestrator: coverage check, diagnosis-to-procedures, metadata */ | ||
| clinical; | ||
| /** System actions: get async result, health check */ | ||
| system; | ||
| // ========================================================================== | ||
| // Coding System Categories | ||
| // ========================================================================== | ||
| /** SNOMED CT coding system */ | ||
| snomed; | ||
| /** ICD-10 diagnosis codes */ | ||
| icd10; | ||
| /** CPT procedure codes */ | ||
| cpt; | ||
| /** HCPCS procedure codes */ | ||
| hcpcs; | ||
| /** LOINC laboratory test codes */ | ||
| loinc; | ||
| /** RxNorm drug/medication codes */ | ||
| rxnorm; | ||
| // ========================================================================== | ||
| // Guideline Categories | ||
| // ========================================================================== | ||
| /** LCD (Local Coverage Determination) guidelines */ | ||
| lcd; | ||
| /** NCD (National Coverage Determination) guidelines */ | ||
| ncd; | ||
| constructor(config) { | ||
| this.apiKey = config.apiKey; | ||
| this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL; | ||
| this.version = config.version ?? DEFAULT_VERSION; | ||
| const boundRequest = this.request.bind(this); | ||
| this.clinical = new ClinicalCategory(boundRequest); | ||
| this.system = new SystemCategory(boundRequest); | ||
| this.snomed = new SnomedCategory(boundRequest); | ||
| this.icd10 = new Icd10Category(boundRequest); | ||
| this.cpt = new CptCategory(boundRequest); | ||
| this.hcpcs = new HcpcsCategory(boundRequest); | ||
| this.loinc = new LoincCategory(boundRequest); | ||
| this.rxnorm = new RxnormCategory(boundRequest); | ||
| this.lcd = new LcdCategory(boundRequest); | ||
| this.ncd = new NcdCategory(boundRequest); | ||
| } | ||
| /** | ||
| * Make an HTTP request to the Codes API Gateway. | ||
| */ | ||
| async request(path, params, method = "GET") { | ||
| const url = new URL(`${this.baseUrl}/${this.version}/${path}`); | ||
| const headers = { | ||
| Authorization: `Bearer ${this.apiKey}`, | ||
| "Content-Type": "application/json" | ||
| }; | ||
| const options = { | ||
| method, | ||
| headers | ||
| }; | ||
| if (method === "GET" && params) { | ||
| for (const [key, value] of Object.entries(params)) { | ||
| if (value !== void 0 && value !== null) { | ||
| if (Array.isArray(value)) { | ||
| url.searchParams.set(key, JSON.stringify(value)); | ||
| } else if (typeof value === "object") { | ||
| url.searchParams.set(key, JSON.stringify(value)); | ||
| } else { | ||
| url.searchParams.set(key, String(value)); | ||
| } | ||
| } | ||
| } | ||
| } else if (method === "POST" && params) { | ||
| options.body = JSON.stringify(params); | ||
| } | ||
| const response = await fetch(url.toString(), options); | ||
| const data = await response.json(); | ||
| if (!response.ok || !data.success) { | ||
| throw new CodesApiError( | ||
| response.status, | ||
| data.error || "Unknown error", | ||
| path | ||
| ); | ||
| } | ||
| return data.data; | ||
| } | ||
| }; | ||
| // src/mcp.ts | ||
| var CODE_SYSTEMS = ["icd10", "cpt", "hcpcs", "snomed", "rxnorm", "loinc"]; | ||
| var GUIDELINE_SYSTEMS = ["lcd", "ncd"]; | ||
| var apiKey = process.env.SEQUOIA_CODES_API_KEY; | ||
| if (!apiKey) { | ||
| console.error("SEQUOIA_CODES_API_KEY environment variable is required"); | ||
| process.exit(1); | ||
| } | ||
| var client = new SequoiaCodesClient({ apiKey }); | ||
| var server = new import_mcp.McpServer({ | ||
| name: "sequoia-codes", | ||
| version: "0.1.0" | ||
| }); | ||
| server.tool( | ||
| "searchCode", | ||
| "Search medical codes by description across ICD-10, CPT, HCPCS, SNOMED, RxNorm, or LOINC systems.", | ||
| { | ||
| system: import_zod4.z.enum(CODE_SYSTEMS).describe("The coding system to search"), | ||
| query: import_zod4.z.string().min(1).describe("Search text (e.g. 'diabetes', 'knee replacement')"), | ||
| limit: import_zod4.z.number().int().min(1).max(200).optional().describe("Max results (1-200)"), | ||
| billingOnly: import_zod4.z.boolean().optional().describe("ICD-10 only: filter to billable codes") | ||
| }, | ||
| async ({ system, query, limit, billingOnly }) => { | ||
| const params = { query }; | ||
| if (limit !== void 0) params.limit = limit; | ||
| if (system === "icd10" && billingOnly !== void 0) params.billingOnly = billingOnly; | ||
| const result = await client[system].searchCode(params); | ||
| return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; | ||
| } | ||
| ); | ||
| server.tool( | ||
| "identifyCode", | ||
| "Look up a specific medical code, get cost data, ICD-10 links, panel members, ingredients, or chapters.", | ||
| { | ||
| system: import_zod4.z.enum(CODE_SYSTEMS).describe("The coding system"), | ||
| code: import_zod4.z.string().default("").describe("The code to look up (not needed for getChapters)"), | ||
| type: import_zod4.z.enum(["ndc", "rxcui"]).optional().describe("RxNorm only: lookup type"), | ||
| action: import_zod4.z.enum(["lookup", "getCost", "linkIcd10", "getPanelMembers", "getIngredients", "getChapters"]).default("lookup").describe( | ||
| "lookup (default), getCost (CPT/HCPCS), linkIcd10 (CPT), getPanelMembers (LOINC), getIngredients (RxNorm), getChapters (ICD-10)" | ||
| ) | ||
| }, | ||
| async ({ system, code, type, action }) => { | ||
| let result; | ||
| switch (action) { | ||
| case "getCost": | ||
| if (system !== "cpt" && system !== "hcpcs") { | ||
| return { content: [{ type: "text", text: "getCost is only available for cpt and hcpcs systems" }] }; | ||
| } | ||
| result = await client[system].getCost({ code }); | ||
| break; | ||
| case "linkIcd10": | ||
| if (system !== "cpt") { | ||
| return { content: [{ type: "text", text: "linkIcd10 is only available for the cpt system" }] }; | ||
| } | ||
| result = await client.cpt.linkIcd10({ code }); | ||
| break; | ||
| case "getPanelMembers": | ||
| if (system !== "loinc") { | ||
| return { content: [{ type: "text", text: "getPanelMembers is only available for the loinc system" }] }; | ||
| } | ||
| result = await client.loinc.getPanelMembers({ code }); | ||
| break; | ||
| case "getIngredients": | ||
| if (system !== "rxnorm") { | ||
| return { content: [{ type: "text", text: "getIngredients is only available for the rxnorm system" }] }; | ||
| } | ||
| result = await client.rxnorm.getIngredients({ rxcui: code }); | ||
| break; | ||
| case "getChapters": | ||
| if (system !== "icd10") { | ||
| return { content: [{ type: "text", text: "getChapters is only available for the icd10 system" }] }; | ||
| } | ||
| result = await client.icd10.getChapters(); | ||
| break; | ||
| default: { | ||
| if (system === "rxnorm") { | ||
| result = await client.rxnorm.identifyCode({ type: type ?? "rxcui", code }); | ||
| } else { | ||
| result = await client[system].identifyCode({ code }); | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; | ||
| } | ||
| ); | ||
| server.tool( | ||
| "searchGuidelines", | ||
| "Search or look up Medicare coverage guidelines (LCD/NCD). Provide query to search, or id/section to look up a specific guideline.", | ||
| { | ||
| system: import_zod4.z.enum(GUIDELINE_SYSTEMS).describe("lcd (Local Coverage) or ncd (National Coverage)"), | ||
| query: import_zod4.z.string().optional().describe("Search text for guidelines"), | ||
| id: import_zod4.z.string().optional().describe("Guideline ID for direct lookup"), | ||
| section: import_zod4.z.string().optional().describe("NCD only: section number (e.g. '220.6')"), | ||
| limit: import_zod4.z.number().int().min(1).max(200).optional().describe("Max results (1-200)") | ||
| }, | ||
| async ({ system, query, id, section, limit }) => { | ||
| let result; | ||
| if (query) { | ||
| const params = { query }; | ||
| if (limit !== void 0) params.limit = limit; | ||
| result = await client[system].searchGuidelines(params); | ||
| } else if (id || section) { | ||
| if (system === "ncd") { | ||
| result = await client.ncd.identifyGuideline({ id, section }); | ||
| } else { | ||
| if (!id) { | ||
| return { content: [{ type: "text", text: "LCD lookup requires an id" }] }; | ||
| } | ||
| result = await client.lcd.identifyGuideline({ id }); | ||
| } | ||
| } else { | ||
| return { content: [{ type: "text", text: "Provide either query (to search) or id/section (to look up a specific guideline)" }] }; | ||
| } | ||
| return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; | ||
| } | ||
| ); | ||
| async function main() { | ||
| const transport = new import_stdio.StdioServerTransport(); | ||
| await server.connect(transport); | ||
| } | ||
| main().catch((err) => { | ||
| console.error("MCP server failed to start:", err); | ||
| process.exit(1); | ||
| }); |
+78
| # MCP Server Setup | ||
| Once you have your `SEQUOIA_CODES_API_KEY`, you can add the SequoiaCodes MCP server to give your AI tools direct access to medical code search and lookup. | ||
| ## Add to Claude Code | ||
| ```bash | ||
| claude mcp add sequoia-codes -- npx -y @sequoiaport/codes@latest | ||
| ``` | ||
| Then set the API key as an environment variable so the MCP server can use it: | ||
| ```bash | ||
| # Add to your shell profile (.zshrc, .bashrc, etc.) | ||
| export SEQUOIA_CODES_API_KEY="sk_live_seq_..." | ||
| ``` | ||
| ## Add to Cursor | ||
| In `.cursor/mcp.json`: | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "sequoia-codes": { | ||
| "command": "npx", | ||
| "args": ["-y", "@sequoiaport/codes@latest"], | ||
| "env": { | ||
| "SEQUOIA_CODES_API_KEY": "sk_live_seq_..." | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| ## Add to VS Code | ||
| In `.vscode/mcp.json`: | ||
| ```json | ||
| { | ||
| "servers": { | ||
| "sequoia-codes": { | ||
| "command": "npx", | ||
| "args": ["-y", "@sequoiaport/codes@latest"], | ||
| "env": { | ||
| "SEQUOIA_CODES_API_KEY": "sk_live_seq_..." | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| ## Available Tools | ||
| The MCP server exposes 3 tools: | ||
| ### `searchCode` | ||
| Search medical codes by description. | ||
| - `system` (required): `icd10`, `cpt`, `hcpcs`, `snomed`, `rxnorm`, or `loinc` | ||
| - `query` (required): search text | ||
| - `limit` (optional): max results (1–200) | ||
| - `billingOnly` (optional): ICD-10 only — filter to billable codes | ||
| ### `identifyCode` | ||
| Look up a specific code, get cost data, ICD-10 links, panel members, ingredients, or chapters. | ||
| - `system` (required): `icd10`, `cpt`, `hcpcs`, `snomed`, `rxnorm`, or `loinc` | ||
| - `code` (required for most actions): the code to look up | ||
| - `type` (optional): RxNorm only — `ndc` or `rxcui` | ||
| - `action` (optional): `lookup` (default), `getCost`, `linkIcd10`, `getPanelMembers`, `getIngredients`, `getChapters` | ||
| ### `searchGuidelines` | ||
| Search or look up Medicare coverage guidelines. | ||
| - `system` (required): `lcd` or `ncd` | ||
| - `query` (optional): search text | ||
| - `id` (optional): guideline ID for direct lookup | ||
| - `section` (optional): NCD only — section number | ||
| - `limit` (optional): max results (1–200) |
+5
-1
| { | ||
| "name": "@sequoiaport/codes", | ||
| "version": "0.1.0-beta.0", | ||
| "version": "0.1.0-beta.1", | ||
| "description": "Retrieve ICD-10, CPT, SNOMED, and more medical codes via the Sequoia Codes API.", | ||
@@ -8,2 +8,5 @@ "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "bin": { | ||
| "sequoia-codes-mcp": "./dist/mcp.js" | ||
| }, | ||
| "scripts": { | ||
@@ -36,2 +39,3 @@ "build": "tsup" | ||
| "dependencies": { | ||
| "@modelcontextprotocol/sdk": "^1.12.1", | ||
| "zod": "^3.23.0" | ||
@@ -38,0 +42,0 @@ }, |
+0
-2
@@ -237,3 +237,2 @@ # @sequoiaport/codes | ||
| # Or install individual skills | ||
| npx skills add @sequoiaport/codes/medical-codes | ||
| npx skills add @sequoiaport/codes/icd10-codes | ||
@@ -251,3 +250,2 @@ npx skills add @sequoiaport/codes/cpt-codes | ||
| |-------|-------------| | ||
| | `medical-codes` | Comprehensive skill covering all coding systems, guidelines, and clinical orchestration | | ||
| | `icd10-codes` | ICD-10 diagnosis code search and lookup | | ||
@@ -254,0 +252,0 @@ | `cpt-codes` | CPT procedure code search, lookup, cost/RVU, and ICD-10 linking | |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
232136
9.21%10
42.86%3818
13.63%2
100%261
-0.76%3
50%3
50%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added