▲ hc-source · CLI + MCP server
CMS changed a file. Your build noticed.
SourceLock pins your healthcare data inputs the way a lockfile pins your dependencies. Coverage policy, provider enrollment, code sets, HCC models, exclusions: every answer carries an evidence receipt, and hc-source doctor fails CI when an upstream source drifts.
Open CLI, MIT license. Public typed parameters only — there is no field to put a patient in.
$ HC_SOURCE_PROVIDER_NPPES_FILES_URL="file://$PWD/tests/fixtures/provider/npi_files_v1_only.html" \ hc-source doctor --source provider hc-source doctor (source-lock.json) ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓ ┃ canary ┃ status ┃ via ┃ observed ┃ expected ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩ │ provider.npi_api_contract │ ok │ authority │ v2.1:10030… │ v2.1:10030… │ │ provider.nppes_v2_files │ drift │ authority │ NPPES_Data… │ NPPES_Data… │ │ provider.pecos_ppef │ ok │ authority │ ppef-2026.… │ ppef-2026.… │ └───────────────────────────┴────────┴───────────┴─────────────┴─────────────┘ 2 ok, 1 drift, 0 unreachable, 0 schema_changed, 0 unpinned, 0 stale, 0 error note provider.npi_api_contract: anchor NPI record and response shape provider.nppes_v2_files [drift]: NPPES retired the V1 bulk files on 2026-03-03; only *_V2.zip names are published now (V2 extends the First Name and Legal Business Name field lengths). The listing this canary just read carries a V1-style name with no _V2 suffix, which means the page has regressed, a stale mirror is being served, or something upstream renamed the grammar again. Fix: open https://download.cms.gov/nppes/NPI_Files.html, read the 'Important Information' block (where CMS announced the V1 retirement), confirm the current version suffix, make sure nothing in your pipeline still generates V1 filenames (NPPES_Data_Dissemination_<Month>_<YYYY>.zip silently 404s), then re-pin with `hc-source lock init`. note provider.nppes_v2_files: 1 monthly, 3 weekly, 1 deactivation file(s) listed note provider.pecos_ppef: latest-alias snapshot id, row count, and column set
The receipt
Answers you can hand to an auditor
Agents quote codes and scores with confidence and no provenance. Every SourceLock tool call returns the answer plus a receipt: which release it came from, when it was effective, the hash of the raw bytes behind it, and what the answer does not prove.
$ hc-source call codes.valid_on --param code=E11.9 --param date=2026-07-15 { "code": "E11.9", "code_nodot": "E119", "code_system": "ICD-10-CM", "date": "2026-07-15", "valid": true, "description": "Type 2 diabetes mellitus without complications", "release": "fy2026-april", "release_effective_from": "2026-04-01", "release_effective_to": "2026-09-30" } receipt ┌───────────────────┬──────────────────────────────────────────────────────────────────┐ │ source │ codes │ │ route │ codes.valid_on │ │ source_version │ fy2026-april │ │ effective │ 2026-04-01 .. 2026-09-30 │ │ retrieved_at │ 2026-08-01T16:53:44.551404+00:00 │ │ upstream_status │ None │ │ raw_sha256 │ 44a789704dc44246388df49bcdb3a03cb65ea235bcbdae1ee4b318c02e4cf7c1 │ │ transform_version │ 2 │ │ fallback │ no (authority used) │ └───────────────────┴──────────────────────────────────────────────────────────────────┘ does not prove: - PHI_NOT_EXPECTED: this tool accepts only public typed parameters. - DOES_NOT_INCLUDE_CPT_DESCRIPTORS: no HCPCS Level I (CPT) record and no ADA CDT record is vendored here, and no AMA- or ADA-authored descriptor text is reproduced. What is served is government-authored: NCHS ICD-10-CM codes and descriptions, and CMS HCPCS Level II codes, modifiers and descriptions from the ANWEB master file, verified to contain zero numeric-leading CPT and zero D#### CDT records. 17 of those CMS descriptions cite CPT code numbers inside the government's own definition text -- G0317 reads "list separately in addition to cpt codes 99306, 99310" -- and the complete set is AT, G0279, G0316, G0317, G0318, G0500, G0561, G2058, G2212, M1483, M1485, QP, S8055, S9034, S9123, V2530, V2531. Those digits ship exactly as CMS published them, carry no AMA descriptor with them, and are listed on the record by codes.hcpcs_lookup. CPT is copyright the American Medical Association: nothing here conveys a licence to it. - DOES_NOT_PROVE_COVERAGE: a code being valid for a date of service says nothing about whether any payer covers, prices, or pays for it. - DOES_NOT_PROVE_CURRENCY: answers come from the release train vendored at build time; CMS reposts corrections in place at the same URLs, so the vendored tables may lag an unannounced correction. `hc-source doctor` checks the train.
source_version · effective
The exact release the answer came from and the dates it applies. An HCC coefficient from the wrong model year is a wrong answer with extra steps.
retrieved_at
Stamped when the bytes were read, not when the receipt was printed. A cached answer says so by carrying its original retrieval time, which is the only version of the field an auditor can use.
raw_sha256 · fallback
The hash of the raw upstream bytes, and whether the authority or a mirror answered. When a tool reads more than one artifact, every one of them gets its own URL, status, hash and retrieval time rather than hiding behind the first.
does not prove
Explicit non-claims, printed on every receipt. A code existing in a release does not mean a payer covers it. A LEIE candidate match is not identity verification. The tool says so itself.
How it works
Contract, receipt, CI gate
Pin your sources
hc-source lock init observes every source and pins what it saw to source-lock.json. Commit it. If any canary cannot be observed, it refuses to write and keeps every existing pin: an offline run can never quietly delete the pins that would have caught drift.
$ hc-source lock init wrote source-lock.json -- 6 source(s), 23 canary expectation(s)
Answer with receipts
Call tools from the CLI, or serve them to your agent over MCP with hc-source mcp. Same tools, same receipts. Parameters are public and typed; patient-shaped input is refused before any adapter runs.
$ hc-source call demo.lookup_code \ --param code=DEMO001 {...} + receipt + non-claims
Gate your CI
hc-source doctor runs cheap canaries against the lockfile. Five exit codes, because “upstream moved”, “CMS is down”, “nothing pinned this” and “this data is out of date” need four different responses from you. The bundled GitHub Action turns each failing canary into an annotation carrying its remediation verbatim.
$ hc-source doctor 2 ok, 1 drift, 0 unreachable, 0 schema_changed, 0 unpinned, 0 stale, 0 error → exit 1
Routes
One interface over the sources that break healthcare builds
Each route is an adapter with its own contract, canaries, and fixtures. Six adapters ship today: 22 tools and 23 pinned canaries. Every chip below is the latest committed hc-source doctor verdict for that source.
| Source | Tools | Authority | Status |
|---|---|---|---|
| Provider evidenceprovider.*3 tools · 3 canaries | NPI Registry lookups, PECOS enrollment records, and an evidence ladder that reports NPI existence and Medicare enrollment as separate facts with separate provenance. | passing | |
| CMS coverage policycoverage.*6 tools · 6 canaries | NCD and LCD/article lookups, companion-article crosswalk, keyword search, weekly MCD snapshot identity, and what changed in the last N days. | passing | |
| ICD-10 / HCPCS releasescodes.*4 tools · 5 canaries | ICD-10-CM and HCPCS Level II validity and descriptions on a date of service, against pinned annual and quarterly release trains. | passing | |
| CMS-HCC risk modelshcc.*4 tools · 3 canaries | V24/V28 condition-category mapping, hierarchy explanation, community continuing-enrollee scoring, and a live probe of the published model-software zips. | passing | |
| OIG exclusionsleie.*3 tools · 4 canaries | NPI-exact exclusion checks, name-based candidate matching, and snapshot freshness against OIG's monthly cadence. Never identity verification. | passing | |
| Reference adapterdemo.*2 tools · 2 canaries | Pinned demo release and code lookups. Ships with the CLI as the adapter contract's working example. | passing |
Live chips come from hc-source doctor --json against this repo's lockfile. Full canary detail on the status page.
Pricing
The CLI is free. The watching is the product.
Anyone can pin sources and run doctor locally. Source Watch is the hosted service that keeps watching after your CI run ends.
The CLI
Everything the tool does today, on your machine and in your CI.
- ·
hc-sourceCLI: tools, call, lock, doctor, receipt - ·MCP server for your agents, stdio transport
- ·Evidence receipts with hashes and non-claims
- ·
source-lock.jsonpinning and drift detection - ·Ed25519 manifest signing, and a GitHub Action that annotates each failing canary with its remediation
- ·Adapter interface for writing your own routes
Source Watch, founding plan
5 of 5 seats remainingFounding-plan service scope. The signing and the CI gate are already in the CLI; what you buy is us running them, so a CMS publish at 6am is your PR by 9.
- 01Ed25519-signed manifests for every watched source, verified against the lockfile your build actually reads
- 02Daily hosted canaries, independent of your CI
- 03The bundled GitHub Action wired into your repos, tuned so it fails on what matters and stays quiet otherwise
- 04Drift alerts and update PRs against your lockfile
- 0590-day snapshot history of watched sources
- 067-day repair target when an upstream breaks a route
Cancel any time in the first 30 days for a full refund.
PHI, licensing, limits
The boring questions, answered plainly
Does any PHI pass through SourceLock?
It has no reason to. Every tool parameter is public and typed: an NPI, a code, a release id. Logs and receipts carry no payloads, and every receipt states PHI_NOT_EXPECTED.
The guard that enforces this is a structural best-effort refusal of patient-shaped input, not a HIPAA compliance control and not a guarantee. It refuses HL7 v2 and X12 segments, FHIR objects, SSN and MBI patterns, and a date of birth beside a name, before pydantic validation and before anything is logged. A clean scan means “nothing patient-shaped was detected”, never “this input contains no PHI”. hc_source/guard.py lists the evasion classes it does not close, including semantic-only PHI, a lone name or address, and identifiers with no universal shape. And when a legitimate value trips a detector, HC_SOURCE_GUARD_ALLOW suppresses that detector by name so a false positive is a config change rather than an abandoned pipeline.
What about CPT codes?
No HCPCS Level I (CPT) record and no ADA CDT record is vendored, and no AMA- or ADA-authored descriptor text is reproduced. Only the CMS ANWEB Level II master file is ingested, verified to contain zero CPT and zero CDT records.
One honest caveat, because the old wording got it wrong: excluding CPT records and descriptors does not exclude CPT code numbers. CMS writes part of its own Level II definitions as cross-references, so the shipped text of G0317 reads “list separately in addition to cpt codes 99306, 99310”. Seventeen vendored records read that way; they ship exactly as CMS published them, the complete list is named in the DOES_NOT_INCLUDE_CPT_DESCRIPTORS non-claim printed on every codes receipt, and codes.hcpcs_lookup lists the cited identifiers on the record itself. A test re-derives that set from the vendored tables on every run, so a re-vendoring that adds or moves one fails the build until a person decides which kind it is. CPT is copyright the AMA; nothing here conveys a licence to it.
Is a LEIE match proof someone is excluded?
No, and an NPI miss is not proof they are clear either: about 89.5% of LEIE records carry no NPI at all, so leie.check_npi returns a warning telling you to run a candidate search and verify at OIG rather than treat the miss as clearance.
When the snapshot is incomplete or a reinstatement date is populated, the tool returns screen_result: indeterminate and omits the verdict fields entirely. It refuses to answer rather than answer wrongly, because a screen that reads as “not excluded” when it simply could not parse a row is the one failure mode that gets somebody paid on a claim they should not have billed.
What exactly happens when upstream changes?
Doctor compares live canary observations to source-lock.json and exits non-zero with the observed value, the expected value, and the exact remediation. The exit code tells you which kind of problem you have: 1 drift or schema change, 2 unreachable or an adapter error, 3 observed but never pinned, 4 matched but reading out-of-date data. On the founding plan, hosted canaries run daily, you get an alert, and an update PR re-pins the lockfile once you have reviewed the diff.
What is the software license?
The CLI and MCP server are MIT-licensed. Source data carries its own terms, recorded per-adapter in SourceContract.license_notes.