MCP server exposing 6 tools for prozorro.
This URL is a JSON-RPC 2.0 endpoint over HTTP. Issue POST requests with a JSON-RPC body. Browsers and search crawlers land here on GET.
POST https://gateway.pipeworx.io/prozorro/mcp
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
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, usually UAH), buyer (procuring entity), status, and procurement method. Titles and buyer names are in Ukrainian. Use for browsing current Ukrainian public tenders; for a specific tender use prozorro_get_tender.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 Ukrainian keywords for best recall. Filter by buyer EDRPOU, by SUPPLIER/bidder EDRPOU (`tenderer` — this is the one for supplier due diligence: every tender a company has bid on or won), CPV code, status, value range, and date. date_from/date_to ALONE (no query/tenderer/buyer/cpv) is also valid and is the only live way to BROWSE historical ProZorro tenders by date — e.g. "what did ProZorro buy in March 2015" — verified live: a bare 10-day 2015 window returns a correctly-dated, narrow result set, not the unfiltered corpus. Returns tenderID, title, value, buyer name + EDRPOU + region, status, and an `id` field (internal 32-hex id) that is NULL unless `resolve_ids` is passed — the search index itself never carries it (verified live); prozorro_get_tender with just the tenderID now attempts the same resolution automatically, so you usually don't need `resolve_ids` here. For an OLD tenderID found this way whose full award/contract detail prozorro_get_tender can't resolve (outside the recently-modified window), use prozorro_historical_release instead.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, but prozorro_search_tenders filters by EDRPOU — call this first, then pass the returned `edrpou` as `tenderer` (supplier side) or `buyer` to get that company's full tender history.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 fields — broad method vs ProZorro's specific type, e.g. aboveThresholdUA/aboveThresholdEU), tender_value (the ORIGINAL ASKING PRICE — not money spent), the buyer/procuring entity (name, EDR identifier, region, contact), tender period (start/end), enquiry period, number of bids, line items (description, CPV classification, quantity, unit, relatedLot), `lots` (id/title/status/value, when the tender is lotted), and the OCDS award/contract stage: `award` (operative award: status, date, value, winning supplier, lotID, bid_id — null if none) plus the full `awards` history (each with the FULL `suppliers[]` array — name + identifier scheme/id — alongside the single-supplier `supplier` field kept for backward compatibility), and `contract` (signed contract value/date, with its CURRENT status and amountPaid read from the contract record — the tender's own copy goes stale after signing; use prozorro_get_contract for amendments, termination and contract documents). An `interpretation` line states plainly whether the tender_value was ever actually spent. Pass `raw:true` to also get the complete, unshaped upstream OCDS tender object under `raw`, for any field not shaped above. Text is largely Ukrainian. Accepts the internal 32-char tender id OR a human tenderID ("UA-2026-09-20-000012-a") — for a tenderID this now tries to resolve the internal id by scanning the most-recently-modified feed records first (cheap, usually one call for anything modified in the last few hours) and returns FULL detail when that succeeds; it falls back to the search index's summary (detail_available:false, no awards) only when the tender wasn't modified recently enough to be found that way.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, current value (AFTER amendments — the API does not keep the original signed amount as a separate field; the change rationale usually states it) and amountPaid, terminationDetails, every contract change/amendment (rationale, rationaleTypes, date published, dateSigned), contract documents with their datePublished, and milestones. Use this — not the tender — for anything after signing: the copy of the contract embedded in a tender is frozen when the tender completes and keeps saying `active` after the contract is amended or terminated. Pass a tender id (32-hex or UA-… tenderID) to get all of its contracts, or a contract's 32-hex id. Optional `as_of` (YYYY-MM-DD) splits changes and documents into those published on/before vs after that date and states whether the record's status at that date is known: the public API keeps NO revision history, so if the record was modified after `as_of` the status at `as_of` is reported as not available rather than inferred. The API carries no termination date field; this tool never invents one.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 #2762/#2768), so a tenderID found via prozorro_search_tenders' date-range browsing (e.g. a 2015 tender) comes back `detail_available:false` there. An internal 32-hex id ALWAYS resolves immediately regardless of age (a direct lookup, no scan needed). For a human tenderID this tries TWO live strategies before giving up: the same recently-modified scan prozorro_get_tender uses, then a bounded forward scan seeded from the DATE THE TENDERID ITSELF ENCODES ("UA-2015-02-16-..." -> search from 2015-02-16) — this finds it when the tender's last modification happened reasonably soon after that date, and does not when a later amendment moved it far down the feed; both are live, keyless, no stored data (fleet #3244). `source` says which path answered; `detail_available:false` (never a crash, never an empty object) means neither reached it, and only the search-index summary is available.Code samples (curl / TypeScript / one-click client install), schemas, and the live playground are on the pack page:
https://pipeworx.io/packs/prozorro/
Pipeworx is an open MCP gateway connecting AI agents to live data. pipeworx.io