@pipeworx/mcp-medicare-pricing 0.1.4 → 0.1.6

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 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 1831+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
7
+ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1856+ 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
 
@@ -14,6 +14,7 @@ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents
14
14
  | `medicare_lab_rate` | "What does a comprehensive metabolic panel reimburse?" — national CLFS rate. |
15
15
  | `medicare_lab_test_lookup` | "What does Medicare pay for Signatera, and which MolDX LCD applies?" — brand name → PLA code, current CLFS rate, and the MolDX LCDs/articles for the test's category. |
16
16
  | `medicare_dmepos_rate` | "How much does Medicare pay for a CPAP machine (E0601) in Texas?" — state-priced, rural vs non-rural. |
17
+ | `medicare_opps_rate` | "What does Medicare pay a hospital outpatient department for CPT 33289 (CardioMEMS implant)?" — status indicator, APC, relative weight, national payment rate, copay, device/drug pass-through status. |
17
18
  | `medicare_code_units_limit` | "How many units of this code will they pay for in one day?" — NCCI MUE. |
18
19
  | `check_code_pair` | "Can I bill 00142 and 64474 together?" — NCCI PTP edit + modifier indicator for a code pair. |
19
20
  | `explain_ncci_edit` | "What is bundled into (or bundles into) this code?" — every recorded PTP edit for one code. |
@@ -31,6 +32,7 @@ All from CMS, all downloadable files with no API:
31
32
  - **Physician Fee Schedule relative value files** (RVUs + GPCIs) — annual
32
33
  - **Clinical Laboratory Fee Schedule** — quarterly
33
34
  - **DMEPOS fee schedule** (durable medical equipment, prosthetics, orthotics, supplies) — quarterly (as necessary): A=Jan, B=Apr, C=Jul, D=Oct
35
+ - **OPPS Addendum B** (Hospital Outpatient Prospective Payment System payment rates by HCPCS code) — quarterly: Q1=Jan, Q2=Apr, Q3=Jul, Q4=Oct
34
36
  - **NCCI Medically Unlikely Edits** — quarterly
35
37
  - **NCCI PTP quarterly additions/deletions/revisions files** — quarterly (see below — a narrower source than the other three)
36
38
  - **FQHC Prospective Payment System base payment rate** — annual (see below — a hand-maintained table, not a downloaded file)
@@ -49,9 +51,20 @@ prior_year_rate_usd, transmittal, change_request, publication}` in
49
51
  directly off its own primary CMS transmittal.
50
52
 
51
53
  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.
54
+ Adjustment Factor (GAF) CMS applies on top. The GAF-adjusted amount for a
55
+ locality is `medicare_fqhc_gaf` (below).
56
+
57
+ ## Geographic adjustment: `medicare_gpci_lookup` and `medicare_fqhc_gaf` (fleet #3398)
58
+
59
+ `medicare_gpci_lookup` returns the work / practice-expense / malpractice GPCIs
60
+ for a locality or a whole state with no procedure code (years 2024-2026 loaded;
61
+ 2024 and 2025 were backfilled with `scripts/ingest-medicare-pricing.mjs
62
+ --gpci-only`). `medicare_fqhc_gaf` returns CMS's own published FQHC GAF per
63
+ locality for CY2018-2026 (each year from CMS's own GAF publication for that year; 2018 uses CMS's February 2018 updated table, 2021 and 2020 the updated releases) and the GAF-adjusted per-visit rate (2022-2026; null for 2018-2021, whose national base rate is not carried). The GAF table is
64
+ CMS's published number, not derived here, and is a small generated source file
65
+ (`src/fqhc-gaf.ts`, 109-112 localities per year; ~50 KB). **Refresh** each January: download
66
+ the new year's FQHC GAF file from CMS and run
67
+ `node scripts/build-fqhc-gaf-table.mjs 2018=<file> ... 2026=<file> 2027=<file>` (ascending; the script finds columns by header name because CMS's layout changes yearly).
55
68
 
56
69
  **Refresh**: CMS issues the following year's transmittal in Nov/Dec (the
57
70
  CY2026 update was dated 2025-12-05 for a Jan 1, 2026 effective date). Add a
@@ -237,6 +250,48 @@ which is AMA copyright. The DMEPOS source file's own DMEREAD/DMEBACK
237
250
  documentation carries no AMA/copyright notice anywhere (checked), so
238
251
  `medicare_dmepos_rate` DOES return the code description.
239
252
 
253
+ ## OPPS — what a hospital outpatient department is paid
254
+
255
+ `medicare_opps_rate` answers the same "what does Medicare pay" question for a
256
+ **hospital outpatient department** claim, as opposed to a physician office
257
+ (`medicare_physician_payment`) or a lab (`medicare_lab_rate`). Source: CMS,
258
+ OPPS Addendum B, the quarterly national payment-rate file by HCPCS code.
259
+ Measured size: 19,278 rows for the CY2026 October release — small, loaded
260
+ whole, same shape as `clfs_rates`/`dmepos_rates` already in this pack.
261
+
262
+ **Device and drug/biological pass-through is the status indicator, not a
263
+ separate column.** CMS's own "Drug and Device Pass-Through Expiration during
264
+ Calendar Year" column in Addendum B is, in practice, not a usable date field —
265
+ checked against the CY2026 October release, every non-blank value in that
266
+ column was a stray change-marker rather than a date. The reliable signal is
267
+ the status indicator itself: **SI='H'** is a pass-through device category
268
+ (paid separately, outside the standard APC amount, for as long as the device
269
+ holds that status — typically 2-3 years from market entry, after which CMS
270
+ reprices it, often to packaged SI='N'), and **SI='G'** is a pass-through
271
+ drug/biological. `device_pass_through`/`drug_or_biological_pass_through` on
272
+ every response are derived from SI, not from the expiration column.
273
+
274
+ A **packaged** code (SI='N', among several other status indicators) returns a
275
+ valid `status_indicator` and `status_indicator_meaning` but `apc: null` and no
276
+ payment rate — that is a correct, normal answer: OPPS pays for that code only
277
+ as part of whatever procedure it is billed alongside, never on its own.
278
+ CardioMEMS (C2624, the implantable pulmonary-artery pressure sensor) is a
279
+ worked example of exactly this: it has been on the market long enough that it
280
+ is no longer pass-through (SI='N', packaged into the implant procedure
281
+ 33289's payment), which is the expected, current state — not a missing-data
282
+ gap.
283
+
284
+ ## No OPPS short descriptors — a mixed-code-type file
285
+
286
+ Addendum B's own header states *"CPT codes and descriptions only are
287
+ copyright ... American Medical Association"*, and the file mixes AMA-
288
+ copyright CPT (HCPCS Level I, numeric codes like 33289) with CMS-owned HCPCS
289
+ Level II codes (like C2624) under **one shared** descriptor column, with no
290
+ per-row schema signal to tell which is which. Unlike `medicare_dmepos_rate`
291
+ (Level II only, so the description is safely CMS-owned), `medicare_opps_rate`
292
+ follows the stricter `pfs_rvu` convention instead: no descriptor is stored at
293
+ all, for any code in this table. A caller passes a code they already hold.
294
+
240
295
  ## DMEPOS pays by state, not locality
241
296
 
242
297
  Medicare pays DMEPOS by **state** (not by the physician-fee-schedule
@@ -271,15 +326,30 @@ node scripts/ingest-ncci-ptp-baseline.mjs --dir /path/to/8-zips # full PTP base
271
326
 
272
327
  node scripts/ingest-dmepos.mjs # newest DMEPOS release (default: 2026 release C)
273
328
  node scripts/ingest-dmepos.mjs --year 2026 --release D # add a new release when CMS posts one
329
+
330
+ node scripts/ingest-opps.mjs # newest OPPS Addendum B release (default: 2026 October)
331
+ node scripts/ingest-opps.mjs --year 2026 --month january # add a new quarterly release when CMS posts one
274
332
  ```
275
333
 
276
334
  Loaded as of writing: 19,226 RVU rows, 109 localities, 2,081 lab rates, 3,531
277
- DMEPOS code/modifier rows (2026 release C, 53 states/territories each), 33,354
335
+ DMEPOS code/modifier rows (2026 release C, 53 states/territories each), 19,278
336
+ OPPS Addendum B rows (CY2026 October / Q4), 33,354
278
337
  MUEs, **4,109,749 distinct NCCI PTP pairs** — the FULL CMS baseline (2026q3,
279
338
  v322r0) with the 2025q1..2026q3 quarterly change files layered on top (fleet
280
339
  #1293, 2026-09-07; superseded the prior 182,286-pair change-window-only
281
340
  coverage). All loaders refuse rather than reporting an empty parse as success.
282
341
 
342
+ `ingest-opps.mjs` resolves the current download from the OPPS Addendum B
343
+ release landing page, same pattern as `ingest-dmepos.mjs`. The landing page's
344
+ own link routes through CMS's `/apps/ama/license.asp?file=...` AMA licence
345
+ click-through page — but, unlike the NCCI PTP baseline elsewhere in this pack,
346
+ the underlying file is NOT actually gated: fetching the plain
347
+ `https://www.cms.gov/files/zip/<name>.zip` URL directly (bypassing
348
+ license.asp entirely) returns the zip with no click-through, no cookie, and no
349
+ Referer needed — verified live, 2026-10-21. The script extracts that direct
350
+ URL from the landing page and fetches it, rather than going through
351
+ license.asp at all.
352
+
283
353
  `ingest-dmepos.mjs` resolves the current download from the DMEPOS release
284
354
  subpage rather than guessing the zip filename — CMS's DMEPOS naming is not
285
355
  stable (a release page 404s before it is posted, and old release URLs have
@@ -337,7 +407,7 @@ directly, instead of just this one's:
337
407
  }
338
408
  ```
339
409
 
340
- Both URLs reach the same gateway and the same 1831+ data sources. The
410
+ Both URLs reach the same gateway and the same 1856+ data sources. The
341
411
  only difference is which pack's tools are listed **directly**; `ask_pipeworx`
342
412
  reaches all of them from either one.
343
413
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeworx/mcp-medicare-pricing",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
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",
@@ -26,7 +26,7 @@
26
26
  "@cloudflare/workers-types": "^4.20260405.1"
27
27
  },
28
28
  "pipeworx": {
29
- "sourceHash": "v1-65f2f81a2d58d5024e9845e0238d0a24b75f7fa653f412494f5054bb6cfc84dd",
30
- "sourceCommit": "514e3efb42b8d81082c07e01d3ae7654bbf91f52"
29
+ "sourceHash": "v1-32efb7ed0c4d3e07bb87e0c09fa0d3f646b4bf25458c73e8f350a248a1e66888",
30
+ "sourceCommit": "f54ad77e789f27fe393978f9c080b5b18c87bb4f"
31
31
  }
32
32
  }
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.pipeworx-io/medicare-pricing",
4
4
  "title": "Medicare Pricing",
5
5
  "description": "What does Medicare PAY — physician fee schedule, lab rates, and per-day unit limits.",
6
- "version": "0.1.4",
6
+ "version": "0.1.6",
7
7
  "websiteUrl": "https://pipeworx.io/packs/medicare-pricing",
8
8
  "repository": {
9
9
  "url": "https://github.com/pipeworx-io/mcp-medicare-pricing",