prawo-pl-mcp
One MCP server for Polish legal data.
Ten independent connectors - case law, legislation, the company register, tax rulings, public procurement, data-protection decisions, plus EU extras - behind four tools. Each connector stays a separate package with its own repository; this server spawns them on demand and translates between their conventions.
"Prawo" is Polish for "law"; the name follows yargi-mcp's move of naming a country server in its own language.
Why an aggregator
The connectors cover Polish legal data well, but as separate MCP servers, one per database - ten installs and ten config entries before the first question. yargi-mcp showed the fix for Turkish law: 16 institutions, one server. prawo-pl-mcp does the same for Poland:
- Four tools instead of 42.
pl_list_sources,pl_search,pl_get_document,pl_call- fewer tool schemas means less context spent before the LLM starts working. - One convention. The connectors grew organically:
dateFromhere,date_fromthere, pages counted from 0 or from 1 depending on the repo. Herepageis always 1-based and dates are alwaysdate_from/date_to(YYYY-MM-DD); the translation happens inside. One name per concept applies to the aggregator's own tools too:pageis the page parameter of bothpl_searchandpl_get_document(page_numberstill works as a deprecated alias), andpl_calltakesargumentsor its aliasargs. - Native names on the table. Every catalog entry carries
native_params- the native parameter name each unified one maps to for that source, soarticle_number(eu-compliance) is visible without spawning the connector or reading an upstream error.pl_callchecks the names it was given against the connector's own schema and says which one it meant. - Nothing preinstalled. Connectors run as subprocesses via
npx -y/uvx, downloaded on the first call to a given source and kept alive afterwards. A source that cannot start reports a readable error while the rest keep working. - Paginated documents. Full judgment and act texts are chunked at ~5000
characters per page (yargi-mcp's pattern), so a 200-page ruling does not
flood the context window. Sources that paginate server-side (
isap) get thepageforwarded natively and are reported aspagination: "native"- the aggregator does not re-cut an already-cut page and does not invent atotal_pagesit cannot know.
Coverage
| Source id | What | Institution / database | Connector | Runtime |
|---|---|---|---|---|
saos |
Case law: common courts, Supreme Court, Constitutional Tribunal + citator | SAOS | mcp-saos | npx |
nsa |
Case law: administrative courts (NSA + 16 WSA) | CBOSA | mcp-nsa | npx |
isap |
Legislation: Dziennik Ustaw + Monitor Polski, 96k+ acts | Sejm ELI API | mcp-isap | npx |
krs |
Company register: extracts, history, board composition | KRS API (Ministry of Justice) | mcp-krs | npx |
eureka |
Tax rulings: 550k+ individual interpretations | EUREKA (Ministry of Finance) | mcp-eureka | npx |
kio |
Public procurement: National Appeal Chamber rulings | orzeczenia.uzp.gov.pl | kio-orzeczenia-mcp | uvx |
uodo |
GDPR enforcement: Polish DPA decisions, fines, stats | orzeczenia.uodo.gov.pl | uodo-orzeczenia-mcp | uvx |
eu-sparql |
EU law: EUR-Lex by CELEX, CJEU by ECLI, GDPRhub | Cellar SPARQL | mcp-eu-sparql | npx |
eu-compliance |
14 EU regulations offline (GDPR, AI Act, DORA, NIS2...) | Local SQLite corpus | mcp-eu-compliance | npx |
legalize |
Law-as-git: 32 jurisdictions, versioned by commit | legalize-dev | legalize-mcp | uvx |
Polish sources are tagged group: pl, EU extras group: eu - filter with
pl_list_sources(group="pl").
Tools
| Tool | What it does |
|---|---|
pl_list_sources |
Catalog of sources (no subprocess spawned). With source_id: live tool schemas of one connector. |
pl_search |
Search any source with normalized parameters; source-specific filters via extra. |
pl_get_document |
Full document by identifier (judgment id, ELI, KRS number, signature...), paginated. |
pl_call |
Any native tool of any connector: citator, DPA statistics, board composition, regulation comparison... |
pl_coverage |
Declare what this connector covers, when each family was captured, and - explicitly - what it does NOT cover. Every gap carries a fallback. |
The typical flow an LLM follows (spelled out in the server's instructions):
pl_list_sources → pl_search → pl_get_document, with pl_call for the
specialized tools each connector brings.
Install
Requires Python ≥ 3.11 plus the runtimes of the sources you use: Node.js ≥ 18
for npx sources, uv for uvx sources. If a
runtime is missing, its sources report source_unavailable and the rest work.
Claude Code
claude mcp add pl-legal -- uvx prawo-pl-mcp
Claude Desktop / any MCP client (stdio)
{
"mcpServers": {
"pl-legal": {
"command": "uvx",
"args": ["prawo-pl-mcp"]
}
}
}
Remote (Streamable HTTP)
uvicorn prawo_pl_mcp.asgi:app --host 0.0.0.0 --port 8000
Open by default (public, read-only data). Set PRAWO_PL_MCP_API_KEY to require
X-API-Key: <key> or Authorization: Bearer <key> on every request.
Configuration
| Env | Default | Meaning |
|---|---|---|
PRAWO_PL_MCP_CMD_<ID> |
- | Override the spawn command for a source, e.g. PRAWO_PL_MCP_CMD_SAOS="node C:/dev/mcp-saos/dist/index.js" for a local checkout. <ID> = source id, uppercase, - → _. |
PRAWO_PL_MCP_INIT_TIMEOUT |
180 |
Seconds allowed for a connector's first start (includes package download). |
PRAWO_PL_MCP_TIMEOUT |
90 |
Seconds per tool call after startup. |
PRAWO_PL_MCP_AUDIT_DIR |
~/.matematic/audit |
Where the JSONL audit log goes. |
PRAWO_PL_MCP_API_KEY |
- | ASGI mode only: require this API key (dual-channel). |
Architecture
The aggregator is a thin proxy (ADR 0001). Connectors are not imported, vendored or forked; the aggregator speaks MCP to them over stdio the same way any client would. The whole layer is a source registry (one dataclass entry per connector), a lazy subprocess pool, a parameter translator and a paginator. Adding a source means adding a registry entry.
LLM client ──MCP──▶ prawo-pl-mcp ──MCP/stdio──▶ npx @matematicsolutions/mcp-saos
│ ──MCP/stdio──▶ uvx kio-orzeczenia-mcp
│ ──MCP/stdio──▶ ... (spawned on first use)
└─ registry + param mapping + 5000-char pagination
Every call lands in a JSONL audit log (timestamp, tool, source, parameter hash, latency - never document content).
Development
git clone https://github.com/matematicsolutions/prawo-pl-mcp && cd prawo-pl-mcp
uv sync --extra dev
uv run pytest # offline tests: registry, dispatch mapping, pagination, drift
uv run prawo-pl-mcp # stdio server
License
Apache-2.0. Individual connectors carry their own licenses (MIT or Apache-2.0), their own rate limits and their own terms toward upstream databases - the aggregator adds no caching and no transformation beyond pagination, so each connector's constraints apply unchanged.
Metadata
Release files for prawo-pl-mcp 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| prawo_pl_mcp-0.2.4.tar.gz | 35.8 kB | Without provenance | Details for prawo_pl_mcp-0.2.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| prawo_pl_mcp-0.2.4-py3-none-any.whl | Python 3 | none | any | Details for prawo_pl_mcp-0.2.4-py3-none-any.whl |
Total release size: 67.1 kB
Release files / prawo_pl_mcp-0.2.4.tar.gz
| Download URL | prawo_pl_mcp-0.2.4.tar.gz |
|---|---|
| Size | 35.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ddba77e3aa0b64f79db19133b5e6a15417e8a4b9ca784ba2aa338791b68f000a
|
|
BLAKE2b-256 checksum How to use checksums |
db3c6cb26c11d2b4b9abbf296f02aac8da077b6bbba857c63efe3ae8328fe149
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / prawo_pl_mcp-0.2.4-py3-none-any.whl
| Download URL | prawo_pl_mcp-0.2.4-py3-none-any.whl |
|---|---|
| Size | 31.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
79958b80208be7e0265a2932f5bb9658b6000989a37184cdeb6d378480a348d8
|
|
BLAKE2b-256 checksum How to use checksums |
cc2049786a2e013110fee0cab859360cfca5ef99aa01cf172b286292a500b96b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for prawo-pl-mcp 0.2.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.