@pipeworx/patent-maintenance-fees
Connect: https://pipeworx.io/mcp — every tool in the catalog, including @pipeworx/patent-maintenance-fees’s. Install: one-click buttons
Connect to just the @pipeworx/patent-maintenance-fees pack
https://gateway.pipeworx.io/patent-maintenance-fees/mcp — only @pipeworx/patent-maintenance-fees’s own tools, nothing else in the catalog.
No MCP client? Skip the connection: POST https://gateway.pipeworx.io/v1/tools/search_packs {"query":"..."} to find a tool below, GET /v1/tools/<name> for its schema, POST the same URL with arguments for the data — see For AI agents.
Tools: 2
Tell whether a US patent is still in force, or has lapsed for non-payment of
maintenance fees — the one question the patents pack cannot answer, because
its prosecution-event data has no fee field at all.
Tools
get_patent_maintenance_status(patent_number)— every recorded maintenance-fee event for one patent (payments, surcharges, expiration for non-payment, reinstatement, entity-status changes), a computedstatus, and a 4th/8th/12th-year fee-window breakdown (due date, grace-period end, whether paid). Design (D-prefixed) and plant (PP-prefixed) patents are statutorily exempt from maintenance fees and reportsubject_to_maintenance_fees:falseinstead of a bare no-match.search_maintenance_fee_events(event_code?, patent_number_prefix?, date_from?, date_to?, limit?)— an exacttotal_matchingcount first, then a capped, newest-first sample of the matching events. Useful for questions like “how many patents expired for non-payment last quarter” — passevent_code: "EXP."and a date range.
Auth
Keyless.
Data source
USPTO, Patent Maintenance Fee Events — the Open Data Portal’s bulk-data product recording every maintenance-fee event for US patents granted 1981-09-01 to present. US federal data, public domain.
Why this is a local-copy pack, not a live proxy
Checked first, per CLAUDE.md’s local-copy rule: the ODP’s Patent File
Wrapper search/get-by-number API — the one mcps/patents already calls —
returns prosecution events (eventDataBag: filing, publication, grant,
office actions) but has no maintenance-fee field at all. Maintenance-fee
history is published only as the “PTMNFEE2” bulk product, a single
weekly-cumulative file, with no per-patent query endpoint. The legacy keyless
host this product used to publish from (bulkdata.uspto.gov) no longer
resolves in DNS as of 2026-10-17, confirmed against two independent public
resolvers (NXDOMAIN/NODATA, not a transient block) — the product is
reachable today only through ODP’s own authenticated bulk-data API, which
answers every /api/v1/* path 401/403 without an API key (the same
credential type as the patents pack’s PLATFORM_USPTO_KEY). A bulk file
with no per-record API is exactly the case CLAUDE.md’s sourcing rule calls
for a refreshed backing store rather than a per-call upstream fetch.
This pack reads a Supabase mirror (uspto_maintenance_fee_events, schema in
supabase/migrations/260_uspto_maintenance_fee_events.sql), loaded by
scripts/ingest-uspto-maintenance-fees.mjs
(.github/workflows/uspto-maintenance-fees-refresh.yml, dispatch-only — see
below). Every response carries data_as_of from the mirror’s own
loaded_at.
Not yet provisioned (as of the commit that added this pack)
Two things still need to happen before uspto_maintenance_fee_events has any
rows, and both are outside what a commit-only build session can do:
- An ODP API key as the
USPTO_ODP_API_KEYrepo secret. Get one free at https://data.uspto.gov/myodp (same credential type the gateway already holds server-side asPLATFORM_USPTO_KEYfor thepatentspack — stored again here because the refresh job runs outside the gateway Worker). - The first dispatch of
uspto-maintenance-fees-refresh.yml. The ingest script’s fetch/discovery step (finding and downloading the latestMaintFeeEvents_*.zipvia the ODP bulk-data API) follows the documented shape of that API but has never run against the live endpoint — no key was available in the build session that wrote it. It fails loudly and names the actual response shape if that shape doesn’t match, rather than mis-parsing silently; see the script’s header. The fixed-width record layout it parses afterward (57 bytes/record, USPTO’s own documented column offsets) is independently corroborated and covered by unit tests inscripts/__tests__/ingest-uspto-maintenance-fees.test.mjs.
Until both land, every tool call fails loudly with a dataset_unavailable
error rather than silently reporting every patent as having no fee
events — see “Empty-mirror guard” below.
Scale and load posture
The full file is ~27M event rows (one row per event, not per patent) as of
2026-10. The refresh workflow does a full TRUNCATE + psql \copy reload
every run — the file is cumulative, so reprocessing it in full reproduces
the correct complete history every time, the same “no delta logic to get
subtly wrong” posture as scripts/ingest-faa-aircraft-registry.mjs. Because
a 27M-row reload is a big load, the workflow is workflow_dispatch only
(same shape as sec-13f-load.yml), not a cron — the first backfill should be
run as a monitored one-off with a Supabase latency/PGRST002 check before
and after, per Bruce’s 2026-09-30 “supa stagger” ruling for SEC 13F.
Empty-mirror guard
Same silent-zero class fixed for faa_reg_aircraft (fleet #2790): an empty
backing table still answers REST queries successfully with zero rows, so a
naive read would report every patent as having no maintenance-fee events —
indistinguishable from a genuine miss against good data. Both tools check
for at least one loaded row first and throw a loud dataset_unavailable
error naming the real condition instead.
Scope — what this pack does NOT determine
Maintenance-fee lapse is one way a patent can stop being enforceable, not the only one. This pack does not determine:
- Full-term (20-years-from-filing) expiration. A patent with a perfect fee-payment record still expires at the end of its statutory term.
- Invalidity, reexamination outcomes, or litigation status.
- Design and plant patents at all — see below.
Pair with the patents pack for prosecution history and the epo-ops pack
for non-US patents.
Design and plant patent exemption
35 U.S.C. 41(b) applies maintenance fees to utility and reissue patents
only. Design (D-prefixed) and plant (PP-prefixed) patent numbers never
generate a maintenance-fee event and never appear in this dataset.
get_patent_maintenance_status detects the prefix and reports
subject_to_maintenance_fees:false with an explanation, rather than a bare
“no events found” that would read identically to a real gap.
Leading zeros — an open normalization question
Whether the file’s fixed-width patent-number column keeps or strips leading
zeros has not been verified against a live file sample (no API key was
available while building this pack — see “Not yet provisioned” above).
get_patent_maintenance_status queries both the normalized form and the
same value with leading zeros stripped, rather than assuming one.
Event codes
USPTO’s own long-stable maintenance-fee event codes (payments by
window/entity-size/public-law era, surcharges, EXP./EXPX
expiration/reinstatement, entity-status changes, petitions) are decoded in
src/index.ts’s EVENT_CODES table with the raw code always included
alongside the description — an uncommon or future code not in the table
comes back with the raw code and a null description rather than a guess.
Tools
- get_patent_maintenance_status — Look up a US patent’s maintenance-fee history and in-force/expired status: every recorded maintenance-fee event (payments, surcharges, expiration for non-payment, reinstatement, entity-status changes)
- search_maintenance_fee_events — Search USPTO maintenance-fee events across patents by event code, patent-number prefix, and/or event-date range — e.g. all ‘EXP.’ (expired for non-payment) events in a date window. Returns an exact to
Tools
get_patent_maintenance_status— Look up a US patent's maintenance-fee history and in-force/expired status: every recorded maintenance-fee event (payments, surcharges, expiration for non-payment, reinstatement, entity-status changes)search_maintenance_fee_events— Search USPTO maintenance-fee events across patents by event code, patent-number prefix, and/or event-date range — e.g. all 'EXP.' (expired for non-payment) events in a date window. Returns an exact to