{
  "markdown": "# prawo-pl-mcp\n\n<!-- mcp-name: io.github.matematicsolutions/prawo-pl-mcp -->\n\nOne MCP server for Polish legal data.\n\nTen independent connectors - case law, legislation, the company register, tax\nrulings, public procurement, data-protection decisions, plus EU extras - behind\nfour tools. Each connector stays a separate package with its own repository;\nthis server spawns them on demand and translates between their conventions.\n\n\"Prawo\" is Polish for \"law\"; the name follows yargi-mcp's move of naming a\ncountry server in its own language.\n\n## Why an aggregator\n\nThe connectors cover Polish legal data well, but as separate MCP servers, one\nper database - ten installs and ten config entries before the first question.\n[yargi-mcp](https://github.com/saidsurucu/yargi-mcp) showed the fix for\nTurkish law: 16 institutions, one server. prawo-pl-mcp does the same for Poland:\n\n- Four tools instead of 42. `pl_list_sources`, `pl_search`, `pl_get_document`,\n  `pl_call` - fewer tool schemas means less context spent before the LLM starts\n  working.\n- One convention. The connectors grew organically: `dateFrom` here, `date_from`\n  there, pages counted from 0 or from 1 depending on the repo. Here `page` is\n  always 1-based and dates are always `date_from`/`date_to` (YYYY-MM-DD); the\n  translation happens inside. One name per concept applies to the aggregator's\n  own tools too: `page` is the page parameter of both `pl_search` and\n  `pl_get_document` (`page_number` still works as a deprecated alias), and\n  `pl_call` takes `arguments` or its alias `args`.\n- Native names on the table. Every catalog entry carries `native_params` - the\n  native parameter name each unified one maps to for that source, so\n  `article_number` (eu-compliance) is visible without spawning the connector or\n  reading an upstream error. `pl_call` checks the names it was given against\n  the connector's own schema and says which one it meant.\n- Nothing preinstalled. Connectors run as subprocesses via `npx -y` / `uvx`,\n  downloaded on the first call to a given source and kept alive afterwards.\n  A source that cannot start reports a readable error while the rest keep\n  working.\n- Paginated documents. Full judgment and act texts are chunked at ~5000\n  characters per page (yargi-mcp's pattern), so a 200-page ruling does not\n  flood the context window. Sources that paginate server-side (`isap`) get the\n  `page` forwarded natively and are reported as `pagination: \"native\"` - the\n  aggregator does not re-cut an already-cut page and does not invent a\n  `total_pages` it cannot know.\n\n## Coverage\n\n| Source id | What | Institution / database | Connector | Runtime |\n|---|---|---|---|---|\n| `saos` | Case law: common courts, Supreme Court, Constitutional Tribunal + citator | [SAOS](https://www.saos.org.pl) | [mcp-saos](https://github.com/matematicsolutions/mcp-saos) | npx |\n| `nsa` | Case law: administrative courts (NSA + 16 WSA) | [CBOSA](https://orzeczenia.nsa.gov.pl) | [mcp-nsa](https://github.com/matematicsolutions/mcp-nsa) | npx |\n| `isap` | Legislation: Dziennik Ustaw + Monitor Polski, 96k+ acts | [Sejm ELI API](https://api.sejm.gov.pl) | [mcp-isap](https://github.com/matematicsolutions/mcp-isap) | npx |\n| `krs` | Company register: extracts, history, board composition | [KRS API (Ministry of Justice)](https://api-krs.ms.gov.pl) | [mcp-krs](https://github.com/matematicsolutions/mcp-krs) | npx |\n| `eureka` | Tax rulings: 550k+ individual interpretations | [EUREKA (Ministry of Finance)](https://eureka.mf.gov.pl) | [mcp-eureka](https://github.com/matematicsolutions/mcp-eureka) | npx |\n| `kio` | Public procurement: National Appeal Chamber rulings | [orzeczenia.uzp.gov.pl](https://orzeczenia.uzp.gov.pl) | [kio-orzeczenia-mcp](https://github.com/matematicsolutions/kio-orzeczenia-mcp) | uvx |\n| `uodo` | GDPR enforcement: Polish DPA decisions, fines, stats | [orzeczenia.uodo.gov.pl](https://orzeczenia.uodo.gov.pl) | [uodo-orzeczenia-mcp](https://github.com/matematicsolutions/uodo-orzeczenia-mcp) | uvx |\n| `eu-sparql` | EU law: EUR-Lex by CELEX, CJEU by ECLI, GDPRhub | [Cellar SPARQL](https://op.europa.eu/en/web/cellar) | [mcp-eu-sparql](https://github.com/matematicsolutions/mcp-eu-sparql) | npx |\n| `eu-compliance` | 14 EU regulations offline (GDPR, AI Act, DORA, NIS2...) | Local SQLite corpus | [mcp-eu-compliance](https://github.com/matematicsolutions/mcp-eu-compliance) | npx |\n| `legalize` | Law-as-git: 32 jurisdictions, versioned by commit | [legalize-dev](https://github.com/legalize-dev) | [legalize-mcp](https://github.com/matematicsolutions/legalize-mcp) | uvx |\n\nPolish sources are tagged `group: pl`, EU extras `group: eu` - filter with\n`pl_list_sources(group=\"pl\")`.\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `pl_list_sources` | Catalog of sources (no subprocess spawned). With `source_id`: live tool schemas of one connector. |\n| `pl_search` | Search any source with normalized parameters; source-specific filters via `extra`. |\n| `pl_get_document` | Full document by identifier (judgment id, ELI, KRS number, signature...), paginated. |\n| `pl_call` | Any native tool of any connector: citator, DPA statistics, board composition, regulation comparison... |\n| `pl_coverage` | Declare what this connector covers, when each family was captured, and - explicitly - what it does NOT cover. Every gap carries a fallback. |\n\nThe typical flow an LLM follows (spelled out in the server's `instructions`):\n`pl_list_sources` → `pl_search` → `pl_get_document`, with `pl_call` for the\nspecialized tools each connector brings.\n\n## Install\n\nRequires Python ≥ 3.11 plus the runtimes of the sources you use: Node.js ≥ 18\nfor `npx` sources, [uv](https://docs.astral.sh/uv/) for `uvx` sources. If a\nruntime is missing, its sources report `source_unavailable` and the rest work.\n\n### Claude Code\n\n```bash\nclaude mcp add pl-legal -- uvx prawo-pl-mcp\n```\n\n### Claude Desktop / any MCP client (stdio)\n\n```json\n{\n  \"mcpServers\": {\n    \"pl-legal\": {\n      \"command\": \"uvx\",\n      \"args\": [\"prawo-pl-mcp\"]\n    }\n  }\n}\n```\n\n### Remote (Streamable HTTP)\n\n```bash\nuvicorn prawo_pl_mcp.asgi:app --host 0.0.0.0 --port 8000\n```\n\nOpen by default (public, read-only data). Set `PRAWO_PL_MCP_API_KEY` to require\n`X-API-Key: <key>` or `Authorization: Bearer <key>` on every request.\n\n## Configuration\n\n| Env | Default | Meaning |\n|---|---|---|\n| `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, `-` → `_`. |\n| `PRAWO_PL_MCP_INIT_TIMEOUT` | `180` | Seconds allowed for a connector's first start (includes package download). |\n| `PRAWO_PL_MCP_TIMEOUT` | `90` | Seconds per tool call after startup. |\n| `PRAWO_PL_MCP_AUDIT_DIR` | `~/.matematic/audit` | Where the JSONL audit log goes. |\n| `PRAWO_PL_MCP_API_KEY` | - | ASGI mode only: require this API key (dual-channel). |\n\n## Architecture\n\nThe aggregator is a thin proxy\n([ADR 0001](docs/adr/0001-proxy-nie-monorepo.md)). Connectors are not imported,\nvendored or forked; the aggregator speaks MCP to them over stdio the same way\nany client would. The whole layer is a source registry (one dataclass entry\nper connector), a lazy subprocess pool, a parameter translator and a paginator.\nAdding a source means adding a registry entry.\n\n```\nLLM client ──MCP──▶ prawo-pl-mcp ──MCP/stdio──▶ npx @matematicsolutions/mcp-saos\n                        │         ──MCP/stdio──▶ uvx kio-orzeczenia-mcp\n                        │         ──MCP/stdio──▶ ... (spawned on first use)\n                        └─ registry + param mapping + 5000-char pagination\n```\n\nEvery call lands in a JSONL audit log (timestamp, tool, source, parameter hash,\nlatency - never document content).\n\n## Development\n\n```bash\ngit clone https://github.com/matematicsolutions/prawo-pl-mcp && cd prawo-pl-mcp\nuv sync --extra dev\nuv run pytest          # offline tests: registry, dispatch mapping, pagination, drift\nuv run prawo-pl-mcp    # stdio server\n```\n\n## License\n\nApache-2.0. Individual connectors carry their own licenses (MIT or Apache-2.0),\ntheir own rate limits and their own terms toward upstream databases - the\naggregator adds no caching and no transformation beyond pagination, so each\nconnector's constraints apply unchanged.\n",
  "bytes": 8273,
  "sha": "901034d92104b6a34efc16bab175b2514f86789c3f1d24a04962a9430d2bc7a5",
  "repo_slug": "matematicsolutions/prawo-pl-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_matematicsolutions_prawo_pl_mc_e3441815/readme"
}