@pipeworx/prozorro
Connect: https://pipeworx.io/mcp — every tool in the catalog, including @pipeworx/prozorro’s. Install: one-click buttons
Connect to just the @pipeworx/prozorro pack
https://gateway.pipeworx.io/prozorro/mcp — only @pipeworx/prozorro’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: 6
Ukraine’s national public procurement system — tender search, full OCDS detail (buyer, value, awards, contracts), and best-effort resolution for historical tenders too old for the live feed to reach directly.
Tools
prozorro_recent_tenders(limit?)— the most recently updated tenders from the live change-feed.prozorro_search_tenders(query?, tenderer?, buyer?, cpv?, status?, date_from?, date_to?, sort_by?, order?, page?, resolve_ids?)— full-text search over all tenders back to 2015, keyless. A date range ALONE (no other filter) is a valid call and is the only live way to browse tenders by historical date — e.g.date_from:"2015-03-01", date_to:"2015-03-10".prozorro_search_organizations(name, role?)— resolve a company/buyer name to its EDRPOU code.prozorro_get_tender(id, raw?)— full detail for one tender (title, value, buyer, periods, line items, awards, contract). Fast for an internal 32-hex id; bounded for a human tenderID (recently-modified window only — seeprozorro_historical_releasefor a second attempt on an older one).prozorro_get_contract(id, as_of?)— the authoritative post-award contract record(s), since a tender’s own embedded copy goes stale after signing.prozorro_historical_release(id)— for a human tenderIDprozorro_get_tendercan’t resolve, tries a second live strategy (see Notes) before honestly reporting a search-index summary only.
Every response is classified (not_found / upstream_throttled / upstream_down / user_error) on an upstream failure, and a tender id that can’t be resolved to full detail always carries detail_available: false with whatever summary fields ARE known — never a bare empty object.
Auth
Keyless.
Data sources
- ProZorro / OpenProcurement, Ukraine public procurement register — tender and contract detail, and the full-text search index.
Notes for the next person
The 60 req/min search budget is shared between prozorro_search_tenders and prozorro_search_organizations on the same upstream host — see the file header for the KV cache-aside and bounded retry that absorb it.
prozorro_get_tender’s tenderID→internal-id resolution is bounded to recently-modified tenders (it scans the change-feed, which has no date-seek for an arbitrary bulk walk). An OLD tenderID — one found via prozorro_search_tenders’s date-range browsing, say — comes back detail_available:false from that tool.
prozorro_historical_release adds a SECOND, independent live attempt for exactly that case, with no stored data at all (fleet #3244): it seeks the same feed to the date the tenderID ITSELF ENCODES (“UA-2015-02-16-…” → search from 2015-02-16) and scans forward a bounded distance for an exact match. This works when the tender’s last modification happened reasonably soon after that date, and misses when a later amendment moved it far down the feed — there is no live way to know that drift in advance, so this is a genuinely unreliable-by-design second attempt, cheap when it hits, honestly reported as a miss when it doesn’t (detail_available: false, never a crash, never empty). A CONSTRUCTED feed offset — not one the API itself handed back — in the shape <unix_ts>.0.1.<32-char suffix> IS honoured as a real date seek (verified live); a garbage-shaped offset is rejected outright (HTTP 400). This capability was found and used here specifically because it does NOT require persisting anything.
A date filter on prozorro_search_tenders drops any matching record with no tender period — combined with a keyword/tenderer/buyer it can hide real matches; used alone it is reliable (verified live: a bare 10-day 2015 window returns a correctly-dated, narrow result set, not the unfiltered corpus — the upstream’s own silent-ignore trap applies to a MISSHAPED param, not a present one).
Tools
- prozorro_recent_tenders — Most recently updated tenders from Ukraine’s ProZorro national procurement system (via the keyless OpenProcurement public feed). Returns each tender with id, tenderID, title, value (amount+currency, u
- prozorro_search_tenders — Full-text search over ALL Ukraine ProZorro tenders back to 2015 (keyless). Searches ProZorro’s own analyzed index, so Ukrainian queries stem correctly (“школа” also matches “школи”, “шкільний”)
- prozorro_search_organizations — Resolve a Ukrainian company or public buyer NAME to its EDRPOU code, using ProZorro’s organization index (keyless). This is the entry point for supplier due diligence: a user knows the company’s name,
- prozorro_get_tender — Full detail for a single Ukraine ProZorro tender by id (via the keyless OpenProcurement public API). Returns tenderID, title, description, status, procurementMethod + procurementMethodType (raw OCDS f
- prozorro_get_contract — The authoritative post-award contract record(s) for a Ukraine ProZorro tender (keyless OpenProcurement contracting API): current status (active | terminated | cancelled), dateSigned, contract period,
- prozorro_historical_release — Detail for a Ukraine ProZorro tender that prozorro_get_tender can’t resolve from a human tenderID — its tenderID-to-internal-id lookup only scans the most-recently-modified few thousand records (fleet
Tools
prozorro_get_contract— The authoritative post-award contract record(s) for a Ukraine ProZorro tender (keyless OpenProcurement contracting API): current status (active | terminated | cancelled), dateSigned, contract period,prozorro_get_tender— Full detail for a single Ukraine ProZorro tender by id (via the keyless OpenProcurement public API). Returns tenderID, title, description, status, procurementMethod + procurementMethodType (raw OCDS fprozorro_historical_release— Detail for a Ukraine ProZorro tender that prozorro_get_tender can't resolve from a human tenderID — its tenderID-to-internal-id lookup only scans the most-recently-modified few thousand records (fleetprozorro_recent_tenders— Most recently updated tenders from Ukraine's ProZorro national procurement system (via the keyless OpenProcurement public feed). Returns each tender with id, tenderID, title, value (amount+currency, uprozorro_search_organizations— Resolve a Ukrainian company or public buyer NAME to its EDRPOU code, using ProZorro's organization index (keyless). This is the entry point for supplier due diligence: a user knows the company's name,prozorro_search_tenders— Full-text search over ALL Ukraine ProZorro tenders back to 2015 (keyless). Searches ProZorro's own analyzed index, so Ukrainian queries stem correctly ( школа also matches школи , шкільний ) — pass Uk