kio-orzeczenia-mcp
Query and retrieve Polish public-procurement case law (KIO rulings) from the UZP database orzeczenia.uzp.gov.pl, with citable signatures, dates and URLs.
kio_search— keyword/phrase search across KIO rulings with optional filters: signature,date_from/date_to,pzp_article(client-side post-filter),subject_index,inflection,content_search, plus paging (page,sizeup to 100).kio_get_orzeczenie— fetch a full ruling by signature ("KIO 2924/21") or internal int id (15903); returns text, sentence/reasoning (if parseable), parties,pzp_articles,doc_type,outcome(issue_datemay be null).kio_recent— list the newest rulings from the last N days (default 30, limit up to 100), newest first.kio_by_pzp_article— find rulings citing a given PZP article (e.g."226","224 ust. 1 pkt 1"); done via phrase search plus post-filter since UZP has no server-side article filter.kio_get_pdf_url— get the UZP-hosted PDF link for a ruling (returns a URL only, does not download bytes).All tools are read-only, idempotent, non-destructive, open-world; results benefit from server-side caching and a ~1 req/s rate limit (large lists can be slow).
Note: the README documents a 6th tool,
kio_coverage(declares coverage gaps/fallbacks), but it is absent from this schema — only the 5 tools above are actually available.
kio-orzeczenia-mcp
MCP server (Model Context Protocol) for the case law of the Krajowa Izba Odwolawcza (KIO) (National Appeals Chamber) at the Urzad Zamowien Publicznych (Public Procurement Office) - the public database orzeczenia.uzp.gov.pl.
It lets Claude / Cursor / VS Code MCP agents consume KIO rulings with verifiable citations (signature + URL + date).
Status: POC v0.1.0 | License: Apache-2.0 | Maintainer: MateMatic
Preliminary warning. The v0.1.0 connector is a proof-of-concept release. It fetches data from the public UZP case law database via HTML (no official REST API). Full legal disclaimer - see the "Legal disclaimer" section below. A dedicated smoke test and notification to UZP are required before production deployment.
What KIO is
The Krajowa Izba Odwolawcza (National Appeals Chamber) is an administrative (quasi-judicial) body operating at the Urzad Zamowien Publicznych (Public Procurement Office) - KIO members are independent when adjudicating (art. 471 PZP) - which hears appeals against contracting authorities' decisions in public procurement proceedings (the Act of 11 September 2019 - Public Procurement Law). KIO rulings are made publicly available by UZP under the Act on access to public information.
KIO rulings are not a source of law within the meaning of art. 87 of the Constitution of the Republic of Poland - they are reference material widely used in the practice of law firms dealing with public procurement.
Related MCP server: mcp-saos
Quickstart
# Clone and enter the directory
git clone https://github.com/matematicsolutions/kio-orzeczenia-mcp.git
cd kio-orzeczenia-mcp
# Virtualenv
python -m venv .venv
.\.venv\Scripts\Activate.ps1
# Install
pip install -e ".[dev]"
# Offline test (signature parser)
pytest tests/test_signature.py -v
# Smoke test (online - hits UZP, rate-limited 1 req/s)
pytest tests/test_smoke.py -v -m smoke
# Run the server (stdio)
python -m kio_orzeczenia_mcp.serverWiring into Claude Code
Add to ~/.claude.json (or .mcp.json in the project):
{
"mcpServers": {
"kio-orzeczenia": {
"command": "python",
"args": ["-m", "kio_orzeczenia_mcp.server"],
"env": {
"KIO_MCP_RATE_LIMIT": "1.0",
"KIO_MCP_CACHE_DIR": "~/.matematic/cache/kio"
}
}
}
}Restart Claude Code. After startup, 6 tools should be visible.
Windows 11 with Smart App Control
Smart App Control blocks unsigned executables, which covers uvx.exe, pip.exe
and the kio-orzeczenia-mcp.exe launcher that pip writes at install time. The python.exe and
py.exe from the python.org installer are signed by the Python Software
Foundation, so running the module through the interpreter works:
python -m pip install kio-orzeczenia-mcp
python -m kio_orzeczenia_mcppip.exe is blocked for the same reason, so install with python -m pip, not
pip install. If python is not on PATH, use the Windows launcher: py -3 -m kio_orzeczenia_mcp.
{ "mcpServers": { "kio-orzeczenia-mcp": { "command": "python", "args": ["-m", "kio_orzeczenia_mcp"] } } }Do not turn Smart App Control off to work around this - it cannot be re-enabled without reinstalling Windows.
6 MCP tools
1. kio_search(query: SearchQuery) -> SearchResult
Search over KIO case law. All fields optional.
// Arguments:
{
"phrase": "razaco niska cena",
"signature": null,
"date_from": "2024-01-01",
"date_to": "2024-12-31",
"pzp_article": "226",
"subject_index": null,
"inflection": true,
"page": 1,
"size": 20
}Returns {total, page, items: [OrzeczenieSummary]}.
2. kio_get_orzeczenie(signature_or_id: str | int) -> Orzeczenie
Fetches the full text of a single ruling.
// Arguments:
"KIO 2924/21" // string -> first search by signature to resolve internal_id (+1 req)
15903 // int -> directly GET /Home/Details/15903 + /Home/ContentHtml/15903Returns the full Orzeczenie with content_text, sentence, reasoning (if the parser can extract them), pzp_articles, subject_index, doc_type, outcome, chamber_composition, parties.
issue_date may be null - UZP has no issue date for some older records. We do not substitute a placeholder date.
3. kio_recent(days: int = 30, limit: int = 20) -> list[OrzeczenieSummary]
The most recent rulings from the last N days, sorted by date descending.
// Arguments:
{ "days": 30, "limit": 20 }4. kio_by_pzp_article(article: str, limit: int = 20) -> list[OrzeczenieSummary]
Rulings citing a specific PZP article. Uses the UZP server-side Art filter, which matches the provisions dictionary and is format-sensitive ("art. 226 ust. 1 pkt 5" hits, plain "226" does not). On an empty result the tool falls back to a full-text phrase search.
// Arguments:
{ "article": "art. 226 ust. 1 pkt 5", "limit": 20 }
{ "article": "224 ust. 1", "limit": 50 } // "art. " prefix added automatically5. kio_get_pdf_url(signature_or_id: str | int) -> dict
Returns the URL to the PDF (rendered by UZP from .docx via Qt 4.8.7). Does not fetch bytes - we link to it.
// Returns:
{
"pdf_url": "https://orzeczenia.uzp.gov.pl/Home/PdfContent/15903?Kind=KIO",
"signature": "KIO 2924/21",
"internal_id": 15903,
"human_readable_citation": "Wyrok KIO z 2021-10-28, sygn. KIO 2924/21"
}6. kio_coverage() -> Coverage
Declares what this connector covers, where it comes from, and what it does NOT cover. Every gap carries a stable id and a fallback. Call it before telling a user a ruling "does not exist" - the absence may be a gap in this connector, not in KIO case law.
3 usage examples (natural language)
Example 1: "KIO rulings on abnormally low price from the past year"
The agent calls kio_search:
{
"phrase": "razaco niska cena",
"date_from": "2025-05-20",
"date_to": "2026-05-20",
"inflection": true,
"size": 50
}Result: a list of OrzeczenieSummary with human_readable_citation ready to insert into a court filing.
Example 2: "KIO rulings citing art. 226 sec. 1 point 5 PZP"
The agent calls kio_by_pzp_article:
{ "article": "226 ust. 1 pkt 5", "limit": 30 }Example 3: "Ruling KIO 2924/21 - who were the parties and was the appeal upheld"
The agent calls kio_get_orzeczenie:
"KIO 2924/21"Result: the full Orzeczenie with parties, sentence, reasoning.
Limitations (POC)
Mapping signature -> internal_id requires a search - if you query by signature, we make +1 req
Server-side PZP article filter is dictionary-based -
Artmatches entries of the UZP provisions dictionary, so the format matters ("art. 226 ust. 1 pkt 5", not"226"); on a miss we fall back to a phrase search, which is broader and needs verificationPDF not fetched - only a link to the UZP page (product decision)
The sentence/reasoning parser is shallow - in the POC we return
content_textas plain text. Splitting into sections -> v1.0Rate limit 1 req/s - large lists may be slow. A 7-day cache for rulings (immutable) mitigates this.
UZP serves a fixed 10 results per page -
size > 10is stitched client-side from consecutive pages, i.e. +1 request per extra pageScraping, not an API - UZP rebuilt the search engine in July 2026 and every endpoint moved (see
DISCOVERY.md). Runpytest -m smokeafter any UZP-side change;tests/test_parser_regression.pyguards the parser offline.
Cache
Rulings (immutable): 7 days
Search result lists: 6 hours
PZP dictionary (once implemented): 30 days
Cache location: ~/.matematic/cache/kio/ (configurable via KIO_MCP_CACHE_DIR).
Audit log
Location: ~/.matematic/audit/kio-orzeczenia-mcp.jsonl
JSONL format (one entry per tool call). See CONSTITUTION.md Art. 3.
What is NOT logged: the full text of a ruling (content_text, reasoning). We log only signatures and metadata.
Legal disclaimer
The data comes from the public UZP case law database (orzeczenia.uzp.gov.pl), made available under the Act of 6 September 2001 on access to public information and the Act of 11 September 2019 - Public Procurement Law.
The connector:
does not modify the source data,
does not de-anonymize the parties to a proceeding beyond what UZP publishes,
does not circumvent any technical protections,
identifies itself with the User-Agent header
matematic-kio-mcp/{version} (+https://matematic.co).
Pre-release blocker. Before publishing the repository on GitHub, a notification to UZP (kontakt@uzp.gov.pl) about launching the connector is planned - User-Agent, query limit, nature of access. Status: TODO.
In case of objections from UZP or other parties - contact: kontakt@matematic.co.
License
Apache-2.0. See LICENSE.
Project constitution
See CONSTITUTION.md - 4 governance principles (public data, rate limit, audit log, citations).
Other open connectors for Polish law
Open-source connectors by MateMatic that complement the scope of this repository:
mcp-saos- SAOS (Supreme Court, Supreme Administrative Court, common courts)mcp-eu-sparql- EU law via Cellar SPARQLmcp-isap- Journal of Laws, Monitor Polski, ministerial gazettes (Sejm ELI API)
External catalog of legal sources: worldwidelaw/legal-sources (bulk harvest scripts, MIT).
Available Tools
5 toolskio_by_pzp_articleARead-onlyIdempotent
Orzeczenia KIO cytujace konkretny artykul PZP.
UWAGA: filtr post-process (brak server-side article filter w UZP). Realizowane przez phrase search "art. {article}" + post-filter na pzp_articles.
Inputs: article (required), limit. Returns: result
kio_get_orzeczenieARead-onlyIdempotent
Pobiera pelne orzeczenie KIO.
Inputs: signature_or_id (required). Returns: object
kio_get_pdf_urlARead-onlyIdempotent
Zwraca URL do PDF orzeczenia (NIE pobiera bytes).
Inputs: signature_or_id (required). Returns: object
kio_recentARead-onlyIdempotent
Najnowsze orzeczenia KIO z ostatnich N dni.
Inputs: days, limit. Returns: result
kio_searchARead-onlyIdempotent
Wyszukuje orzeczenia KIO w bazie orzeczenia.uzp.gov.pl.
Wszystkie parametry opcjonalne. pzp_article to filtr post-process (brak server-side).
Inputs: phrase, signature, date_from, date_to, +6 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Each tool serves a distinct purpose: search by article, fetch full decision, get PDF URL, recent decisions, and general search. There is no overlap or ambiguity.
All names use snake_case and start with 'kio_', but the verbs are inconsistent: 'get' and 'search' are actions, while 'recent' is an adjective and 'by_pzp_article' is a prepositional phrase.
With 5 tools covering search, retrieval, and specialized queries, the set is well-scoped for accessing procurement decisions without being too sparse or cluttered.
The toolset covers core operations: search, get full decision, get PDF URL, recent decisions, and article-specific search. Minor gaps like advanced filters or bulk listing are acceptable.
Maintenance
Related MCP Connectors
Poland public procurement MCP — official e-Zamówienia notice feed (keyless).
TED MCP Server: Real-time EU public tenders access. https://www.lexsocket.ai/
simap MCP — Swiss public procurement tenders and awards (keyless).
MCP server for Polish political polls, averages, seat projections, and regional estimates.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for Polish administrative case-law (NSA + regional administrative courts, CBOSA) with ECLI and verifiable citations.3111 npmMIT
- AlicenseAqualityBmaintenanceMCP server for Polish case-law (SAOS) — Supreme Court, Constitutional Tribunal, common courts and KIO — with ECLI and verifiable citations.3125 npm2MIT
- AlicenseAqualityCmaintenanceMCP server for Polish legislation (ISAP / Sejm) — search acts (Dz.U., M.P.) and fetch full texts with ELI identifiers and verifiable citations.3103 npm1MIT
- FlicenseAqualityDmaintenanceMCP server for searching and retrieving contracts from the Polish Central Register of Contracts (CRU) via its API.2-