@pipeworx/mcp-medicare-pricing 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -2
- package/package.json +4 -4
- package/server.json +2 -2
- package/src/index.ts +108 -1
- package/src/server.ts +5 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ What Medicare **pays** — physician fee schedule, lab rates, and per-day unit
|
|
|
4
4
|
limits. The companion to `medicare-coverage`, which answers whether something is
|
|
5
5
|
covered but not what it is worth.
|
|
6
6
|
|
|
7
|
-
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to
|
|
7
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1831+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
|
|
8
8
|
|
|
9
9
|
## Tools
|
|
10
10
|
|
|
@@ -17,6 +17,7 @@ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents
|
|
|
17
17
|
| `medicare_code_units_limit` | "How many units of this code will they pay for in one day?" — NCCI MUE. |
|
|
18
18
|
| `check_code_pair` | "Can I bill 00142 and 64474 together?" — NCCI PTP edit + modifier indicator for a code pair. |
|
|
19
19
|
| `explain_ncci_edit` | "What is bundled into (or bundles into) this code?" — every recorded PTP edit for one code. |
|
|
20
|
+
| `medicare_fqhc_pps_rate` | "What is the FQHC PPS base rate for 2026?" — CMS's national Federally Qualified Health Center per-visit base rate, by year. |
|
|
20
21
|
| `medicare_pricing_coverage` | Which vintages are loaded, including the PTP baseline vintage. |
|
|
21
22
|
|
|
22
23
|
## Auth
|
|
@@ -32,6 +33,31 @@ All from CMS, all downloadable files with no API:
|
|
|
32
33
|
- **DMEPOS fee schedule** (durable medical equipment, prosthetics, orthotics, supplies) — quarterly (as necessary): A=Jan, B=Apr, C=Jul, D=Oct
|
|
33
34
|
- **NCCI Medically Unlikely Edits** — quarterly
|
|
34
35
|
- **NCCI PTP quarterly additions/deletions/revisions files** — quarterly (see below — a narrower source than the other three)
|
|
36
|
+
- **FQHC Prospective Payment System base payment rate** — annual (see below — a hand-maintained table, not a downloaded file)
|
|
37
|
+
|
|
38
|
+
## FQHC PPS base payment rate — a hand-maintained table, and why
|
|
39
|
+
|
|
40
|
+
`medicare_fqhc_pps_rate` is different from the rest of this pack: it is not
|
|
41
|
+
backed by Supabase or a downloaded bulk file, because there is neither. CMS
|
|
42
|
+
publishes the FQHC PPS national base rate exactly once a year, as a single new
|
|
43
|
+
dollar figure inside a CMS Manual System "Recurring Update Notification"
|
|
44
|
+
Change Request PDF — one number, one PDF, once a year. Standing up an ingest
|
|
45
|
+
pipeline for that is not proportionate, so the pack carries a small table of
|
|
46
|
+
`{year, base_rate_usd, effective_date, market_basket_update_pct,
|
|
47
|
+
prior_year_rate_usd, transmittal, change_request, publication}` in
|
|
48
|
+
`src/index.ts` (`FQHC_PPS_BASE_RATES`), five rows (CY2022–CY2026), each read
|
|
49
|
+
directly off its own primary CMS transmittal.
|
|
50
|
+
|
|
51
|
+
This is the national BASE rate only — before the per-FQHC Geographic
|
|
52
|
+
Adjustment Factor (GAF) CMS applies on top. The GAF table itself is not
|
|
53
|
+
loaded; an agent that needs the GAF-adjusted dollar amount for a specific FQHC
|
|
54
|
+
still needs that separately.
|
|
55
|
+
|
|
56
|
+
**Refresh**: CMS issues the following year's transmittal in Nov/Dec (the
|
|
57
|
+
CY2026 update was dated 2025-12-05 for a Jan 1, 2026 effective date). Add a
|
|
58
|
+
row to `FQHC_PPS_BASE_RATES` each year once it posts — search CMS's own
|
|
59
|
+
transmittals (Pub 100-04 Medicare Claims Processing, or Pub 100-02 Medicare
|
|
60
|
+
Benefit Policy) for "FQHC PPS Calendar Year".
|
|
35
61
|
|
|
36
62
|
## ADLT list — brand name to billing code
|
|
37
63
|
|
|
@@ -311,7 +337,7 @@ directly, instead of just this one's:
|
|
|
311
337
|
}
|
|
312
338
|
```
|
|
313
339
|
|
|
314
|
-
Both URLs reach the same gateway and the same
|
|
340
|
+
Both URLs reach the same gateway and the same 1831+ data sources. The
|
|
315
341
|
only difference is which pack's tools are listed **directly**; `ask_pipeworx`
|
|
316
342
|
reaches all of them from either one.
|
|
317
343
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipeworx/mcp-medicare-pricing",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "What does Medicare PAY — physician fee schedule, lab rates, and per-day unit",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "What does Medicare PAY — physician fee schedule, lab rates, and per-day unit limits.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"types": "src/index.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@cloudflare/workers-types": "^4.20260405.1"
|
|
27
27
|
},
|
|
28
28
|
"pipeworx": {
|
|
29
|
-
"sourceHash": "v1-
|
|
30
|
-
"sourceCommit": "
|
|
29
|
+
"sourceHash": "v1-65f2f81a2d58d5024e9845e0238d0a24b75f7fa653f412494f5054bb6cfc84dd",
|
|
30
|
+
"sourceCommit": "514e3efb42b8d81082c07e01d3ae7654bbf91f52"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/server.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.pipeworx-io/medicare-pricing",
|
|
4
4
|
"title": "Medicare Pricing",
|
|
5
|
-
"description": "What does Medicare PAY — physician fee schedule, lab rates, and per-day unit",
|
|
6
|
-
"version": "0.1.
|
|
5
|
+
"description": "What does Medicare PAY — physician fee schedule, lab rates, and per-day unit limits.",
|
|
6
|
+
"version": "0.1.4",
|
|
7
7
|
"websiteUrl": "https://pipeworx.io/packs/medicare-pricing",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/pipeworx-io/mcp-medicare-pricing",
|
package/src/index.ts
CHANGED
|
@@ -864,6 +864,94 @@ const STATUS: Record<string, string> = {
|
|
|
864
864
|
X: 'Statutorily excluded from the fee schedule',
|
|
865
865
|
};
|
|
866
866
|
|
|
867
|
+
// ── FQHC PPS base payment rate (fleet #3241) ──────────────────────────────
|
|
868
|
+
//
|
|
869
|
+
// CMS publishes this ONE number a year, in a CMS Manual System TRANSMITTAL
|
|
870
|
+
// (a "Recurring Update Notification" Change Request PDF) — there is no API
|
|
871
|
+
// and no bulk file, just a yearly PDF with a single new figure in it. A
|
|
872
|
+
// hand-maintained table of a handful of values is the documented shape for
|
|
873
|
+
// that case (house rule for fleet #3241: "a PDF fact sheet with one number
|
|
874
|
+
// per year... a tiny dated table is acceptable"), not a Supabase ingest
|
|
875
|
+
// pipeline for five numbers. Every row below was read directly off its own
|
|
876
|
+
// primary CMS transmittal (not a summary site) — see transmittal/change
|
|
877
|
+
// request/pub per row.
|
|
878
|
+
//
|
|
879
|
+
// REFRESH: CMS issues the next year's transmittal in Nov/Dec for the
|
|
880
|
+
// following Jan 1 (the CY2026 one was dated 2025-12-05) — add a row here
|
|
881
|
+
// each year when it posts. Search "FQHC PPS Calendar Year" among CMS's own
|
|
882
|
+
// transmittals (Pub 100-04 Medicare Claims Processing or Pub 100-02 Medicare
|
|
883
|
+
// Benefit Policy) to find the next one.
|
|
884
|
+
interface FqhcPpsRow {
|
|
885
|
+
year: number;
|
|
886
|
+
base_rate_usd: number;
|
|
887
|
+
effective_date: string;
|
|
888
|
+
market_basket_update_pct: number;
|
|
889
|
+
prior_year_rate_usd: number;
|
|
890
|
+
transmittal: string;
|
|
891
|
+
change_request: string;
|
|
892
|
+
publication: string;
|
|
893
|
+
}
|
|
894
|
+
const FQHC_PPS_BASE_RATES: FqhcPpsRow[] = [
|
|
895
|
+
{ year: 2022, base_rate_usd: 180.16, effective_date: '2022-01-01', market_basket_update_pct: 2.1, prior_year_rate_usd: 176.45, transmittal: 'Transmittal 11057', change_request: 'CR 12490', publication: 'Pub 100-04 Medicare Claims Processing' },
|
|
896
|
+
{ year: 2023, base_rate_usd: 187.19, effective_date: '2023-01-01', market_basket_update_pct: 3.9, prior_year_rate_usd: 180.16, transmittal: 'Transmittal 11677', change_request: 'CR 12961', publication: 'Pub 100-04 Medicare Claims Processing' },
|
|
897
|
+
{ year: 2024, base_rate_usd: 195.99, effective_date: '2024-01-01', market_basket_update_pct: 4.7, prior_year_rate_usd: 187.19, transmittal: 'Transmittal 12267', change_request: 'CR 13398', publication: 'Pub 100-04 Medicare Claims Processing' },
|
|
898
|
+
{ year: 2025, base_rate_usd: 202.65, effective_date: '2025-01-01', market_basket_update_pct: 3.4, prior_year_rate_usd: 195.99, transmittal: 'Transmittal 12951', change_request: 'CR 13867', publication: 'Pub 100-04 Medicare Claims Processing' },
|
|
899
|
+
{ year: 2026, base_rate_usd: 207.72, effective_date: '2026-01-01', market_basket_update_pct: 2.5, prior_year_rate_usd: 202.65, transmittal: 'Transmittal 13506', change_request: 'CR 14309', publication: 'Pub 100-02 Medicare Benefit Policy' },
|
|
900
|
+
];
|
|
901
|
+
const FQHC_SOURCE = 'Centers for Medicare & Medicaid Services (CMS), Federally Qualified Health Center (FQHC) Prospective Payment System base payment rate';
|
|
902
|
+
|
|
903
|
+
function fqhcStatement(r: FqhcPpsRow): string {
|
|
904
|
+
return `CMS FQHC PPS base payment rate for CY ${r.year}: $${r.base_rate_usd.toFixed(2)}, effective ${r.effective_date} — a ${r.market_basket_update_pct}% FQHC market basket increase over CY ${r.year - 1}'s $${r.prior_year_rate_usd.toFixed(2)} (${r.transmittal}, ${r.change_request}, ${r.publication}). This is the national base rate before any per-FQHC Geographic Adjustment Factor (GAF).`;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
function fqhcPpsRate(args: Record<string, unknown>) {
|
|
908
|
+
const askedYear = typeof args.year === 'number' ? Math.floor(args.year) : null;
|
|
909
|
+
const rows = FQHC_PPS_BASE_RATES;
|
|
910
|
+
if (askedYear == null) {
|
|
911
|
+
const latest = rows[rows.length - 1];
|
|
912
|
+
return {
|
|
913
|
+
found: true,
|
|
914
|
+
source: FQHC_SOURCE,
|
|
915
|
+
year: latest.year,
|
|
916
|
+
year_was_defaulted: true,
|
|
917
|
+
base_rate_usd: latest.base_rate_usd,
|
|
918
|
+
effective_date: latest.effective_date,
|
|
919
|
+
market_basket_update_pct: latest.market_basket_update_pct,
|
|
920
|
+
prior_year_rate_usd: latest.prior_year_rate_usd,
|
|
921
|
+
transmittal: latest.transmittal,
|
|
922
|
+
change_request: latest.change_request,
|
|
923
|
+
publication: latest.publication,
|
|
924
|
+
statement: fqhcStatement(latest),
|
|
925
|
+
per_visit_not_per_code: 'This is a per-DAY encounter rate (lesser of actual charges or this PPS rate), not a fee per HCPCS/CPT code.',
|
|
926
|
+
history: rows,
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
const row = rows.find((r) => r.year === askedYear);
|
|
930
|
+
if (!row) {
|
|
931
|
+
return {
|
|
932
|
+
found: false,
|
|
933
|
+
reason: 'year_not_loaded',
|
|
934
|
+
loaded_years: rows.map((r) => r.year),
|
|
935
|
+
hint: `No FQHC PPS base payment rate loaded for CY ${askedYear}. Loaded years: ${rows.map((r) => r.year).join(', ')}.`,
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
return {
|
|
939
|
+
found: true,
|
|
940
|
+
source: FQHC_SOURCE,
|
|
941
|
+
year: row.year,
|
|
942
|
+
year_was_defaulted: false,
|
|
943
|
+
base_rate_usd: row.base_rate_usd,
|
|
944
|
+
effective_date: row.effective_date,
|
|
945
|
+
market_basket_update_pct: row.market_basket_update_pct,
|
|
946
|
+
prior_year_rate_usd: row.prior_year_rate_usd,
|
|
947
|
+
transmittal: row.transmittal,
|
|
948
|
+
change_request: row.change_request,
|
|
949
|
+
publication: row.publication,
|
|
950
|
+
statement: fqhcStatement(row),
|
|
951
|
+
per_visit_not_per_code: 'This is a per-DAY encounter rate (lesser of actual charges or this PPS rate), not a fee per HCPCS/CPT code.',
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
|
|
867
955
|
const tools: McpToolExport['tools'] = [
|
|
868
956
|
{
|
|
869
957
|
name: 'medicare_physician_payment',
|
|
@@ -967,6 +1055,18 @@ const tools: McpToolExport['tools'] = [
|
|
|
967
1055
|
required: ['code'],
|
|
968
1056
|
},
|
|
969
1057
|
},
|
|
1058
|
+
{
|
|
1059
|
+
name: 'medicare_fqhc_pps_rate',
|
|
1060
|
+
description:
|
|
1061
|
+
'What does Medicare pay a Federally Qualified Health Center (FQHC) per visit? Returns the CMS FQHC Prospective Payment System (PPS) national BASE payment rate for a calendar year — the figure CMS publishes once a year, before any per-FQHC Geographic Adjustment Factor (GAF) is applied. Answers "what is the FQHC PPS base rate", "how much does Medicare pay an FQHC per encounter", "FQHC PPS rate for 2025 vs 2026". '
|
|
1062
|
+
+ 'Medicare pays an FQHC the LESSER of its actual charges or this PPS rate for all FQHC services furnished to a beneficiary on a day with a qualifying face-to-face visit — it is a per-DAY encounter rate, not a fee per procedure code (unlike medicare_physician_payment/medicare_lab_rate). This tool does NOT compute the GAF-adjusted, FQHC-specific amount — only the national base rate before that adjustment; the GAF table is not loaded here. Omit year for the newest loaded year plus the full known history (small — CMS publishes one number a year); pass year for one row.',
|
|
1063
|
+
inputSchema: {
|
|
1064
|
+
type: 'object' as const,
|
|
1065
|
+
properties: {
|
|
1066
|
+
year: { type: 'number', description: 'Calendar year, e.g. 2026. Omit to get the newest loaded year AND the full history table.' },
|
|
1067
|
+
},
|
|
1068
|
+
},
|
|
1069
|
+
},
|
|
970
1070
|
{
|
|
971
1071
|
name: 'medicare_pricing_coverage',
|
|
972
1072
|
description:
|
|
@@ -1042,6 +1142,12 @@ async function resolveLocality(cfg: Cfg, q: unknown, year: number): Promise<{ ch
|
|
|
1042
1142
|
}
|
|
1043
1143
|
|
|
1044
1144
|
async function callTool(name: string, args: Record<string, unknown>): Promise<unknown> {
|
|
1145
|
+
// FQHC PPS is a hand-maintained constant table (see FQHC_PPS_BASE_RATES
|
|
1146
|
+
// above) — not Supabase-backed like the rest of this pack — so it is
|
|
1147
|
+
// dispatched before the credential check below, which every OTHER tool
|
|
1148
|
+
// here needs.
|
|
1149
|
+
if (name === 'medicare_fqhc_pps_rate') return fqhcPpsRate(args);
|
|
1150
|
+
|
|
1045
1151
|
const url = (args._supabaseUrl as string | undefined)?.trim();
|
|
1046
1152
|
const key = (args._supabaseKey as string | undefined)?.trim();
|
|
1047
1153
|
if (!url || !key) {
|
|
@@ -1430,6 +1536,7 @@ async function callTool(name: string, args: Record<string, unknown>): Promise<un
|
|
|
1430
1536
|
geographic_localities: gpciN.length ? { year: gpciN[0].year } : null,
|
|
1431
1537
|
clinical_lab_fee_schedule: clfsN.length ? { year: clfsN[0].year, quarter: clfsN[0].quarter } : null,
|
|
1432
1538
|
dmepos_fee_schedule: dmeN.length ? { year: dmeN[0].year, release: dmeN[0].release, release_month: DME_RELEASE_MONTH[dmeN[0].release] ?? null, priced_by: 'state (not Medicare locality), with separate rural/non-rural amounts' } : null,
|
|
1539
|
+
fqhc_pps_base_rate: { newest_loaded_year: FQHC_PPS_BASE_RATES[FQHC_PPS_BASE_RATES.length - 1].year, loaded_years: FQHC_PPS_BASE_RATES.map((r) => r.year), source: FQHC_SOURCE },
|
|
1433
1540
|
medically_unlikely_edits: mueN.length ? { effective_from: mueN[0].effective_date } : null,
|
|
1434
1541
|
procedure_to_procedure_edits: ptpRange.length ? {
|
|
1435
1542
|
baseline_vintage: '2026q3 (v322r0, effective 2026-07-01) — CMS\'s FULL NCCI PTP edit baseline, AMA-CPT-licence-gated; licence accepted on the company\'s behalf by Bruce, 2026-09-07 (fleet #1293)',
|
|
@@ -1439,7 +1546,7 @@ async function callTool(name: string, args: Record<string, unknown>): Promise<un
|
|
|
1439
1546
|
refresh_cadence: 'Physician fee schedule annually (with intra-year releases); lab fee schedule, DMEPOS fee schedule, MUE units edits, and PTP pair-edit changes all quarterly (as necessary).',
|
|
1440
1547
|
no_descriptions_note:
|
|
1441
1548
|
'CPT procedure descriptions (physician fee schedule, lab schedule) are not returned — American Medical Association copyright. DMEPOS is the exception: it uses HCPCS Level II codes, which CMS itself maintains, so medicare_dmepos_rate DOES return the code description.',
|
|
1442
|
-
source: 'CMS Physician Fee Schedule, Clinical Laboratory Fee Schedule, DMEPOS fee schedule, and National Correct Coding Initiative (MUE + PTP quarterly change files)',
|
|
1549
|
+
source: 'CMS Physician Fee Schedule, Clinical Laboratory Fee Schedule, DMEPOS fee schedule, FQHC PPS base payment rate, and National Correct Coding Initiative (MUE + PTP quarterly change files)',
|
|
1443
1550
|
};
|
|
1444
1551
|
}
|
|
1445
1552
|
|
package/src/server.ts
CHANGED
|
@@ -8,8 +8,9 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
8
8
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import pack from './index.js';
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
const server = new Server(
|
|
12
|
-
{ name: '@pipeworx/mcp-medicare-pricing', version: '0.1.
|
|
13
|
+
{ name: '@pipeworx/mcp-medicare-pricing', version: '0.1.4' },
|
|
13
14
|
{ capabilities: { tools: {} } },
|
|
14
15
|
);
|
|
15
16
|
|
|
@@ -24,7 +25,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
24
25
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
25
26
|
const { name, arguments: args } = request.params;
|
|
26
27
|
try {
|
|
27
|
-
const
|
|
28
|
+
const callArgs = { ...((args ?? {}) as Record<string, unknown>) };
|
|
29
|
+
|
|
30
|
+
const result = await pack.callTool(name, callArgs);
|
|
28
31
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
29
32
|
} catch (err) {
|
|
30
33
|
return {
|