| name | tools |
| description | Healthcare API usage patterns for ICD-10, CPT, NPI, NCD/LCD, and PubMed |
| version | 1.0.0 |
| context | infrastructure |
Tools Skill
This skill defines how to use healthcare APIs and MCPs (Model Context Protocol servers) to access medical data.
Available Tools
| Tool | Source | Purpose | Status |
|---|
| ICD-10 | ICD-10 Codes MCP | Diagnosis code lookup | ✅ Full access |
| CPT | Local Medicare Codes | Procedure code lookup | ✅ Full access |
| NPI | NPI Registry MCP | Provider validation | ✅ Full access |
| NCD/LCD | CMS Coverage MCP | Medicare coverage policies | ✅ Full access |
| SAD | CMS Coverage MCP | Part B/D exclusion check | ✅ Full access |
| PubMed | PubMed MCP | Clinical evidence | ✅ Full access |
| AMA Knowledge Base | AMA KBAPI | CPT guidance articles | ⏸️ Disabled |
ICD-10 Search
Purpose
Map symptoms and conditions to diagnosis codes.
Usage
const results = await icd10.search({
query: "low back pain",
limit: 10
});
{
codes: [
{
code: "M54.5",
description: "Low back pain",
category: "Dorsalgia",
chapter: "Diseases of the musculoskeletal system"
},
{
code: "M54.50",
description: "Low back pain, unspecified",
...
}
]
}
Best Practices
- Start broad, then narrow: Search "back pain" then refine to "lumbar"
- Check specificity: Use most specific code available (M54.51 > M54.5)
- Consider laterality: Left vs right when applicable
- Check excludes: Some codes exclude others
Common Searches
| Symptom | Likely Codes |
|---|
| Back pain | M54.5, M54.50, M54.51 |
| Back pain with leg pain | M54.4, M54.41, M54.42 |
| Knee pain | M25.56, M25.561, M25.562 |
| Dizziness | R42, H81.1 |
| Shortness of breath | R06.02, R06.00 |
| Chest pain | R07.9, R07.89 |
| Fatigue | R53.83, R53.1 |
CPT Lookup (Local Medicare Codes)
Purpose
Map procedures to CPT codes using local Medicare-focused code mappings.
Primary Source: Local Code Database
import {
searchCPT,
getCPTCode,
getCPTDescription,
getCPTsForCondition,
getCPTsByCategory,
getRelatedDiagnoses,
isPreventiveCode,
commonlyRequiresPriorAuth,
} from "@/lib/medicare-lookup";
Usage
const results = searchCPT("MRI lumbar", 10);
const code = getCPTCode("72148");
const codes = getCPTsForCondition("back pain");
const cardioCodes = getCPTsByCategory("Cardiology");
const diagnoses = getRelatedDiagnoses("72148");
const isFree = isPreventiveCode("G0438");
const needsAuth = commonlyRequiresPriorAuth("27447");
Available Categories
- E/M (Evaluation & Management)
- Cardiology
- Diabetes
- Orthopedics
- Pulmonary
- Oncology
- Nephrology
- Neurology
- Ophthalmology
- GI (Gastroenterology)
- Mental Health
- Preventive
- DME (Durable Medical Equipment)
Best Practices
- Include modifiers: -RT (right), -LT (left), -50 (bilateral)
- Check for bundling: Some codes include others
- Verify category: Professional vs technical component
- Use condition mapping:
getCPTsForCondition() handles common synonyms
Common Procedures
| Description | CPT |
|---|
| MRI lumbar w/o contrast | 72148 |
| MRI lumbar w/ contrast | 72149 |
| MRI knee w/o contrast | 73721 |
| CT head w/o contrast | 70450 |
| Chest X-ray 2 views | 71046 |
| Office visit, established | 99213/99214 |
| Physical therapy eval | 97163 |
| Sleep study (polysomnography) | 95810 |
AMA API (Disabled)
The AMA Intelligent Platform API integration is temporarily disabled due to CPTAPI_Zip endpoint issues. The implementation is preserved in /app/src/lib/ama-client.ts for future use when KBAPI access is needed for detailed CPT guidance articles.
NPI Registry
Purpose
Search and validate healthcare providers.
Usage
const results = await npi.search({
last_name: "Smith",
first_name: "John",
state: "CA",
city: "Los Angeles",
specialty: "Orthopedic Surgery",
limit: 10
});
{
providers: [
{
npi: "1234567890",
name: {
first: "John",
last: "Smith",
credential: "MD"
},
specialty: {
primary: "Orthopedic Surgery",
secondary: []
},
address: {
line1: "123 Medical Center Dr",
city: "Los Angeles",
state: "CA",
zip: "90001"
},
phone: "310-555-1234",
accepts_medicare: true
}
]
}
Search Strategies
- Start with name + state: Most reliable combination
- Add city if too many results: Narrow down location
- Try without first name: Sometimes only last name is known
- Search by practice name: For clinics/hospitals
Validation
const provider = await npi.lookup({
npi: "1234567890"
});
if (provider.status === "active") {
}
CMS Coverage (NCD/LCD)
Purpose
Search Medicare coverage policies to determine if a service is covered.
Usage
const ncdResults = await cms.searchNCD({
procedure_code: "72148",
diagnosis_code: "M54.5"
});
const lcdResults = await cms.searchLCD({
procedure_code: "72148",
diagnosis_code: "M54.5",
state: "CA"
});
{
policies: [
{
type: "LCD",
id: "L35047",
title: "MRI of the Spine",
contractor: "Noridian",
effective_date: "2023-10-01",
coverage_criteria: [
"Pain duration > 6 weeks",
"Failed conservative treatment",
"Neurological deficit on examination"
],
covered_diagnoses: ["M54.5", "M54.4", "M47.816"],
covered_procedures: ["72148", "72149"],
documentation_requirements: [
"Duration of symptoms",
"Prior treatments attempted",
"Physical examination findings"
]
}
]
}
Search Strategy
- Check NCDs first: They apply nationally
- Then check LCDs: They're regional, more specific
- No policy found: Not necessarily not covered — at contractor discretion
Medicare Administrative Contractors (MACs)
| Region | Contractor | States |
|---|
| 1 | Noridian | CA, NV, HI, AS, GU, MP |
| 5 | WPS | IA, KS, MO, NE |
| 6 | NGS | CT, IL, MA, ME, MN, NH, NY, RI, VT, WI |
| ... | ... | ... |
SAD List Check
Purpose
Determine if a drug/biologic is Part B (medical) or Part D (pharmacy).
Usage
const sadResult = await cms.checkSAD({
hcpcs_code: "J1234"
});
{
hcpcs: "J1234",
drug_name: "Example Drug",
on_sad_list: true,
effective_date: "2024-01-01",
coverage: "Part D",
reason: "Self-administered drug, not incident-to physician service"
}
Interpretation
- On SAD list → Part D (pharmacy benefit)
- Not on SAD list → Part B (medical benefit, may need medical necessity)
PubMed Search
Purpose
Find clinical evidence to support medical necessity.
Usage
const results = await pubmed.search({
condition: "low back pain",
intervention: "MRI",
outcome: "diagnosis",
limit: 5
});
{
articles: [
{
pmid: "12345678",
title: "Diagnostic Value of MRI in Low Back Pain",
authors: ["Smith J", "Jones M"],
journal: "Spine",
year: 2023,
abstract: "...",
doi: "10.1000/example",
citation: "Smith J, Jones M. Diagnostic Value of MRI in Low Back Pain. Spine. 2023;48(5):301-310."
}
]
}
Search Strategies
- Use MeSH terms: More precise than keywords
- Filter by recency: Prefer recent studies (last 5-10 years)
- Filter by study type: RCTs > observational > case reports
- Focus on outcomes: What does the literature support?
For Appeals
When generating appeal letters, cite:
- Systematic reviews / meta-analyses
- Clinical guidelines (AHRQ, specialty societies)
- Large RCTs
- Cohort studies with clear outcomes
Tool Error Handling
Retry Logic
async function callWithRetry(tool, params, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await tool(params);
} catch (error) {
if (i === maxRetries - 1) throw error;
await sleep(1000 * (i + 1));
}
}
}
Fallback Behavior
| Tool | Fallback |
|---|
| ICD-10 | Use cached common mappings |
| CPT | Describe procedure without code |
| NPI | Continue without provider validation |
| NCD/LCD | Note "no specific policy found" |
| PubMed | Generate letter without citations |
Error Messages
if (error.code === 'TOOL_UNAVAILABLE') {
return "I'm having trouble accessing Medicare's policy database right now. Let me give you general guidance based on what I know...";
}
if (error.code === 'NO_RESULTS') {
return "I couldn't find a specific Medicare policy for this combination. That doesn't mean it's not covered — the decision may be made case-by-case...";
}
Tool Caching
Cache Durations
| Tool | Cache TTL | Reason |
|---|
| ICD-10 (MCP) | 30 days | Codes updated annually |
| CPT (Local) | N/A | In-memory, always fresh |
| NPI | 7 days | Providers can move/change |
| NCD/LCD | 24 hours | Policies can update |
| PubMed | 7 days | Articles don't change |
Cache Keys
`icd10:${query}`
`npi:${lastName}:${state}:${specialty}`
`coverage:${icd10}:${cpt}:${state}`
`pubmed:${condition}:${intervention}`
Rate Limits
| Tool | Rate Limit | Strategy |
|---|
| Local CPT/ICD-10 | Unlimited | In-memory, instant |
| NPI Registry | 20/sec | Queue requests |
| CMS Coverage | 10/sec | Cache aggressively |
| PubMed | 3/sec | Batch searches |
Security
- API keys stored in environment variables
- Never expose keys to client
- All tool calls go through Edge Functions
- Log tool usage for monitoring (no PII)