# Polish Law MCP Server API – ELI Acts & SAOS Judgments (`enterprising_hamster/polish-law-mcp-server`) Actor

MCP server for Polish law (akty prawne, orzeczenia sądów). AI assistants search Dziennik Ustaw and Monitor Polski via Sejm ELI, read consolidated act text by article, and search and read court judgments from SAOS. Works with Claude, Cursor and other MCP clients.

- **URL**: https://apify.com/enterprising_hamster/polish-law-mcp-server.md
- **Developed by:** [Kamil Kaczmarek](https://apify.com/enterprising_hamster) (community)
- **Categories:** MCP servers, AI, Developer tools
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 tool calls

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Polish Law MCP Server API – ELI Acts & SAOS Judgments

**Polish law MCP server API**: give AI assistants **Polish law from official public sources** — **akty prawne** from Dziennik Ustaw and Monitor Polski via the [Sejm ELI API](https://api.sejm.gov.pl/eli), current consolidated wording (**tekst jednolity**) article by article, and Polish **orzeczenia sądów** from [SAOS](https://www.saos.org.pl/). Works with Claude, Cursor and other MCP clients over streamable HTTP. Runs on Apify in Standby mode: nothing to install or host. Polski opis: **serwer MCP z polskim prawem** — wyszukiwanie aktów w Dzienniku Ustaw i Monitorze Polskim (ELI), tekst jednolity po artykułach oraz orzeczenia sądów z SAOS; Claude, Cursor i inni klienci MCP.

Keywords: polish law MCP, akty prawne API, Dziennik Ustaw, Monitor Polski, Sejm ELI, tekst jednolity, orzeczenia sądów, SAOS, Kodeks cywilny, Claude MCP, Cursor MCP.

### What makes it different

- **Current wording by default.** Ask for the Civil Code (Dz.U. 1964 nr 16 poz. 93) and you get the newest consolidated text (tekst jednolity), not the 1964 original. The answer also lists amendments published after that consolidated text.
- **One article at a time.** `article: "415"` returns just Art. 415, also for `23a`, `449^1` or `§ 5` of a regulation. It works on PDF-only texts too, which is how most recent consolidated texts are published.
- **Small, token-efficient answers.** Compact JSON, empty fields dropped, and text in windows of up to 50,000 characters with an explicit `[truncated: N more characters; call again with offset=X]` marker.
- **Citations in, citations out.** Pass an ELI id (`DU/2018/1000`) or a citation as written in Polish documents (`Dz. U. z 1964 r. Nr 16, poz. 93`). Judgments list the regulations they cite with ELI ids, so the assistant can open the statute in one step.
- **Clean judgment data.** SAOS contains impossible dates such as 3013-12-04. Newest-first searches stop at today, and any remaining impossible date is flagged with `date_invalid`.
- **Honest failures.** Source outages, maintenance pages, unknown ids and empty searches return a clear error or an empty result, and you are not charged for them.

### Tools

| Tool | What it does | Event |
|---|---|---|
| `search_legal_acts` | Search acts by title words, publisher (DU or MP), year, act type, ELI keywords, in-force status and a date range (promulgation, announcement or entry into force). Newest or oldest first. | `tool-call` |
| `get_legal_act` | Metadata of one act: status, in-force flag, key dates, keywords, issuing body, EU acts it implements, newest consolidated text, and references (amending, amended, repealed, implementing acts). | `tool-call` |
| `get_legal_act_text` | Plain text of an act or one article of it, from the newest consolidated text by default. Paging with `offset`, `max_chars` and `find`. | `tool-call-with-text` |
| `list_changed_legal_acts` | Acts whose ELI record changed since a time: new publications, amendments and status updates. | `tool-call` |
| `search_court_judgments` | Search judgments by full-text query, court type, date range, case number, judge, keywords, legal basis or cited regulation. Newest, oldest or most cited first. | `tool-call` |
| `get_court_judgment` | Full judgment: metadata, legal bases, cited regulations with ELI ids, cited cases and the text in windows. | `tool-call-with-text` |

Every tool is read-only. Argument names, types and limits are published to your client in `tools/list`.

### Connect your MCP client

The server URL is:

```
https://enterprising-hamster--polish-law-mcp-server.apify.actor/mcp
```

Authenticate with your [Apify API token](https://console.apify.com/settings/integrations) as a Bearer token. The server speaks MCP over streamable HTTP.

#### Claude Desktop

Claude Desktop starts local servers from its config file, so use the `mcp-remote` bridge (needs Node.js). In `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "polish-law": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://enterprising-hamster--polish-law-mcp-server.apify.actor/mcp",
        "--header", "Authorization:${AUTH_HEADER}"
      ],
      "env": { "AUTH_HEADER": "Bearer your-apify-token" }
    }
  }
}
```

#### Cursor

In `~/.cursor/mcp.json` or `.cursor/mcp.json` of a project:

```json
{
  "mcpServers": {
    "polish-law": {
      "url": "https://enterprising-hamster--polish-law-mcp-server.apify.actor/mcp",
      "headers": { "Authorization": "Bearer your-apify-token" }
    }
  }
}
```

#### OpenAI API and other clients

Any client that can call a remote MCP server over streamable HTTP with a custom `Authorization` header works the same way. For example, the OpenAI Responses API takes a tool of type `mcp` with `server_url` set to the URL above and `headers` set to `{"Authorization": "Bearer your-apify-token"}`. Claude Code: `claude mcp add --transport http polish-law <url> --header "Authorization: Bearer your-apify-token"`.

### Example prompts

- "What does Art. 415 of the Polish Civil Code say today? Quote it and give the Dz.U. citation."
- "Find the current Polish personal data protection act and list amendments not yet in its consolidated text."
- "Which Supreme Court judgments on art. 415 k.c. are cited most often? Summarise the top three."
- "Find 2026 Regional Court judgments about CHF-indexed mortgages and summarise the reasoning of the newest one."
- "Which acts published in Dziennik Ustaw changed in the last 7 days?"

### Example answer

`get_legal_act_text` with `{"eli": "DU/1964/93", "article": "415"}` returns two text blocks. The first is metadata:

```json
{"eli":"DU/2026/795","citation":"Dz.U. 2026 poz. 795","title":"Obwieszczenie Marszałka Sejmu Rzeczypospolitej Polskiej z dnia 27 maja 2026 r. w sprawie ogłoszenia jednolitego tekstu ustawy - Kodeks cywilny","type":"Obwieszczenie","status":"obowiązujący","in_force":true,"promulgated":"2026-06-17","text_of":"DU/1964/93","legal_status_date":"2026-05-19","source":"pdf","article":"415","offset":161596,"chars":90,"total_chars":486017}
```

The second is the text: `Art. 415. Kto z winy swej wyrządził drugiemu szkodę, obowiązany jest do jej naprawienia.`

### Input

One-shot (non-Standby) run — current Civil Code Art. 415 text (`get_legal_act_text`):

```json
{"tool": "get_legal_act_text", "arguments": {"eli": "Dz.U. 1964 nr 16 poz. 93", "article": "415"}}
```

Supreme Court judgments citing art. 415 k.c., most cited first (`search_court_judgments`):

```json
{"tool": "search_court_judgments", "arguments": {"query": "art. 415 k.c.", "court_type": "SUPREME", "sort": "most_cited", "limit": 5}}
```

For Standby / MCP clients, set the server URL and Bearer token (see Connect your MCP client). More inputs are in `examples/`.

### Pricing (pay per event)

| Event | Charged when | Price |
|---|---|---|
| `tool-call` | A search, metadata or change-list call returns at least one result | TBD |
| `tool-call-with-text` | A call returns the text of an act or judgment (up to 50,000 characters) | TBD |

You are not charged for failed calls, invalid arguments, unknown ids or empty results. In Standby mode Apify also bills the platform usage of the server run. If a run's maximum total charge is reached, the server answers with a clear error and fetches nothing.

### Coverage and limits

- **Legal acts:** everything in the Sejm ELI database for Dziennik Ustaw and Monitor Polski. Texts come as HTML or PDF from the source. Scanned PDFs of some old acts have no text layer; the server says so and links the PDF.
- **Judgments (measured 2026-10-18):** common courts are up to date. Supreme Court data in SAOS ends in 2016-06, the Constitutional Tribunal in 2015-12 and the National Appeal Chamber (KIO) in 2018-09. Administrative court judgments are not available through SAOS.
- **Speed:** ELI answers in about a second. The first article of the Civil Code (a 119-page PDF) took 3 seconds; later calls on the same text are instant while the server stays warm. SAOS searches take 1 to 20 seconds, and SAOS takes 15 to 60 seconds to serve one full judgment.
- Title search in ELI matches substrings, so use word stems: `ochron danych` finds "ochronie danych".

### FAQ

**Is there an MCP server / API for Polish law / akty prawne?** Yes. This Actor is a hosted MCP server for Polish legal acts (Dziennik Ustaw, Monitor Polski via Sejm ELI) and court judgments (SAOS). Connect Claude, Cursor or any MCP client over streamable HTTP, or run one tool call without MCP.

**How do I connect Claude Desktop or Cursor?** Use the Standby URL `https://enterprising-hamster--polish-law-mcp-server.apify.actor/mcp` with your Apify API token as `Authorization: Bearer …`. See Connect your MCP client for `claude_desktop_config.json` and `mcp.json` examples.

**Do you return personal data from judgments?** Courts and SAOS anonymise parties. Judge names published in their official role are kept. The server never outputs SAOS publisher, reviser or court reporter names.

**What is the difference vs scraping ISAP/SAOS sites or separate ELI/SAOS Actors?** Scrapers hit HTML UIs and break easily. This MCP server calls the official Sejm ELI and SAOS APIs, returns consolidated text by article, and exposes six tools to AI assistants in one Standby endpoint. Dedicated ELI/SAOS Actors on the same account are dataset scrapers for bulk export; this one is for interactive MCP tool calls.

**Is this legal advice?** No. It returns official texts and metadata. Check the source and a qualified lawyer before relying on them.

**Where does the data come from?** Legal acts: the public [Sejm ELI API](https://api.sejm.gov.pl/eli) run by the Chancellery of the Sejm, with links to [ISAP](https://isap.sejm.gov.pl/). Judgments: the public [SAOS API](https://www.saos.org.pl/help/index.php/dokumentacja-api). No source API key is needed. Under Article 4 of the Polish Copyright Act, normative acts and official documents are not protected by copyright.

**What about personal data?** Courts and SAOS anonymise judgments. Judge names are published in their official role and are kept. The server never outputs SAOS publisher, reviser or court reporter names.

**How fresh is it?** Every call reads the live source. Nothing is pre-indexed. A running server reuses a document text it already downloaded, so paging through a long act does not download it again.

**Can I use it without MCP?** Yes. A normal (non-Standby) run takes `tool` and `arguments` as input, makes one tool call and stores the result in the dataset. See `examples/`.

### Development

Python 3.13, Apify SDK 4.1, the official `mcp` SDK, httpx and pypdfium2.

```bash
python -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytest -q
```

The tests block network access and use responses recorded from the live APIs. They cover every tool, upstream failures, charging and the MCP protocol through the official client. `scripts/live_smoke.py [proxy-url]` calls each tool once against the live APIs. `scripts/standby_check.py <url> [proxy-url]` checks a deployed server with the official MCP client, using `APIFY_TOKEN`.

Run the server locally on port 4321 (`/mcp`):

```bash
ACTOR_WEB_SERVER_PORT=4321 APIFY_META_ORIGIN=STANDBY .venv/bin/python -m src
```

Simulate pay-per-event prices in a local run:

```bash
export ACTOR_TEST_PAY_PER_EVENT=true
export APIFY_ACTOR_PRICING_INFO="$(cat examples/pricing_info.local.json)"
export APIFY_CHARGED_ACTOR_EVENT_COUNTS='{"tool-call":0,"tool-call-with-text":0}'
export ACTOR_MAX_TOTAL_CHARGE_USD=0.05
apify run --input-file examples/civil-code-article.json
```

The charges appear in the named `charging-log` dataset. `APIFY_CHARGED_ACTOR_EVENT_COUNTS` needs explicit zero counts; with an empty `{}` the SDK ignores the prices.

### Disclaimer

This is an unofficial tool. It is not affiliated with or endorsed by the Chancellery of the Sejm, SAOS or any court.

### 🇵🇱 Po polsku

Serwer MCP z polskim prawem dla asystentów AI. Wyszukuje akty w Dzienniku Ustaw i Monitorze Polskim (API ELI Sejmu), zwraca aktualny tekst jednolity z podziałem na artykuły i listę nowelizacji po tekście jednolitym, a także wyszukuje i zwraca orzeczenia sądów z SAOS. Działa na Apify w trybie Standby: wystarczy podać w kliencie MCP adres `https://enterprising-hamster--polish-law-mcp-server.apify.actor/mcp` i token Apify jako `Authorization: Bearer`. Opłata za udane wywołanie narzędzia (`tool-call`) albo za wywołanie zwracające tekst aktu lub orzeczenia (`tool-call-with-text`). Błędy, puste wyniki i nieznane identyfikatory są bezpłatne.

# Changelog

This Actor's version history is a separate document: https://apify.com/enterprising_hamster/polish-law-mcp-server/changelog.md

# Actor input Schema

## `tool` (type: `string`):

The MCP tool to call once.

## `arguments` (type: `object`):

Arguments for the tool as a JSON object, exactly as an MCP client would send them. See the README for every tool's parameters.

## Actor input object example

```json
{
  "tool": "search_legal_acts",
  "arguments": {
    "title": "ochronie danych osobowych",
    "limit": 5
  }
}
```

# Actor output Schema

## `results` (type: `string`):

The result of the tool call made by a normal run, stored in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tool": "search_legal_acts",
    "arguments": {
        "title": "ochronie danych osobowych",
        "limit": 5
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("enterprising_hamster/polish-law-mcp-server").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "tool": "search_legal_acts",
    "arguments": {
        "title": "ochronie danych osobowych",
        "limit": 5,
    },
}

# Run the Actor and wait for it to finish
run = client.actor("enterprising_hamster/polish-law-mcp-server").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tool": "search_legal_acts",
  "arguments": {
    "title": "ochronie danych osobowych",
    "limit": 5
  }
}' |
apify call enterprising_hamster/polish-law-mcp-server --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,enterprising_hamster/polish-law-mcp-server"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/SyVENlNtQqEgPQPxb/builds/XVb8VYmaYB0XeNVAu/openapi.json
