Skip to main content
Glama

SAOS MCP - Polish Court Judgments

npm version License: Apache-2.0 MCP

An MCP server that connects Claude (and other AI clients) to SAOS - the official public database of Polish court judgments (System Orzecznictwa Sądów Powszechnych i Sądu Najwyższego).

Who is this for? Polish lawyers, legal researchers, and law students who want to search and analyze Polish court decisions directly inside Claude, Cursor, or any MCP-compatible AI client. No API key required - SAOS is a public database.


Features

  • Full-text search across hundreds of thousands of Polish judgments from courts of appeal, regional courts, and district courts

  • Filter by case number, judge name, court type, judgment type, and date range

  • Retrieve full judgments - metadata, operative part (sentencja), and complete reasoning (uzasadnienie)

  • Local file archive - in stdio mode, saves each retrieved judgment as a .md file for offline reference

  • In-memory cache (15 min TTL) to avoid redundant API calls

  • Timeout protection - 15-second abort signal on all API requests

  • Dual transport - stdio for local Claude Desktop use, HTTP for remote/hosted deployment


Related MCP server: Entscheidsuche MCP Server

Dla polskich prawników

SAOS MCP pozwala Claude'owi przeszukiwać bazę orzeczeń sądowych i analizować je bezpośrednio w rozmowie. Nie musisz otwierać przeglądarki ani kopiować tekstów — wystarczy zapytać Claude'a.

Jak zacząć

Krok 1. Zainstaluj Node.js (wersja 20 lub nowsza). To jedyna techniczna rzecz do zrobienia.

Krok 2. Otwórz plik konfiguracyjny Claude Desktop:

  • Windows: naciśnij Win + R, wpisz %APPDATA%\Claude i otwórz plik claude_desktop_config.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Krok 3. Dodaj poniższy wpis do sekcji mcpServers (jeśli plik jest pusty, wklej całość):

{
  "mcpServers": {
    "SAOS": {
      "command": "npx",
      "args": ["-y", "@thescalablelegalmarketer/saos-mcp"]
    }
  }
}

Krok 4. Zapisz plik i zrestartuj Claude Desktop. Przy pierwszym uruchomieniu Claude automatycznie pobierze serwer.

Przykładowe zapytania

Znajdź w SAOS 3 orzeczenia z lat 2020-2025 dotyczące sporów
o nienależyte wykonanie umowy wdrożeniowej oprogramowania.
Dla każdego podaj:
- sentencję (dosłowny cytat)
- podstawę prawną
- główny argument sądu
Wyszukaj orzeczenia dotyczące praw autorskich do oprogramowania
stworzonego przez pracownika na rzecz pracodawcy. Jakie stanowisko
zajmowały sądy w kwestii własności kodu?

Uwaga: Orzeczenia w bazie SAOS mają zanonimizowane dane stron (zamiast nazwisk widnieje (...)). To cecha samej bazy danych, nie ograniczenie narzędzia.


Installation

Prerequisites: Node.js 20+ must be installed on your machine.

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "SAOS": {
      "command": "npx",
      "args": ["-y", "@thescalablelegalmarketer/saos-mcp"]
    }
  }
}

Restart Claude Desktop. The server starts automatically - no separate process needed.

Config file location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Remote HTTP (self-hosted)

{
  "mcpServers": {
    "SAOS": {
      "url": "https://your-domain.com/mcp"
    }
  }
}

See Deployment for instructions on hosting your own instance.

From source (development)

git clone https://github.com/pawelojdowski/saos-mcp
cd saos-mcp
npm install
npm run build
{
  "mcpServers": {
    "SAOS": {
      "command": "node",
      "args": ["C:\\PATH\\TO\\saos-mcp\\dist\\index.js"]
    }
  }
}

Environment variable (stdio mode only):

  • SAOS_OUTPUT_DIR - directory for saved .md judgment files (default: ~/Documents/saos-orzeczenia)


Tools

saos_search_judgments

Search for judgments in the SAOS database. Results sorted by date (newest first). All parameters optional.

Parameter

Type

Description

query

string

Full-text search across all fields (content + metadata)

caseNumber

string

Exact case number, e.g. VIII GC 23/24

judgeName

string

Judge's full name

keyword

string

SAOS thematic keyword, e.g. odszkodowanie (damages)

ccCourtType

string

APPEAL / REGIONAL / DISTRICT

judgmentType

string

SENTENCE / DECISION / RESOLUTION

dateFrom

string

Format YYYY-MM-DD

dateTo

string

Format YYYY-MM-DD

pageSize

number

Max 20, default 10

pageNumber

number

Starting from 0

Tip: SAOS full-text search requires all keywords to appear in the text. Use multiple specific terms rather than quoted phrases, e.g. umowa wdrożeniowa oprogramowanie nienależyte wykonanie.


saos_get_judgment

Retrieve a full judgment by ID. Returns metadata, verbatim operative part (sentencja), and full reasoning (uzasadnienie). In stdio mode, also saves a .md file to SAOS_OUTPUT_DIR.

Parameter

Type

Description

id

number

Required. Judgment ID from saos_search_judgments results


saos_list_courts

Returns a list of common courts (ID, name, type). Use this to find court IDs for filtering.


Example prompt

Use SAOS to find 3 judgments from 2024–2025 concerning disputes over
defective implementation of ERP software contracts.
For each judgment call saos_get_judgment and provide:

1. Operative part - quote verbatim from the [VERBATIM QUOTE] section
2. Ratio decidendi - summarize the main reason for the ruling from the
   "Sąd zważył" section of the reasoning
3. Legal basis - which provisions did the court invoke

Development

npm run dev          # stdio server (TypeScript, no build needed)
npm run dev:http     # HTTP server on port 3000
npm run build        # type-check + esbuild bundle → dist/
npm run start        # run compiled stdio bundle
npm run start:http   # run compiled HTTP server

Deployment

Build and run with Docker:

docker build -t saos-mcp .
docker run -p 3000:3000 saos-mcp

MCP endpoint: http://localhost:3000/mcp Health check: http://localhost:3000/health

Deploy to Railway, Render, or Fly.io using the included Dockerfile.


Project structure

saos-mcp/
├── src/
│   ├── types.ts        ← SAOS API TypeScript interfaces
│   ├── api.ts          ← SAOS API client + in-memory cache
│   ├── format.ts       ← HTML parsing, text formatting, file saving
│   ├── server.ts       ← createMcpServer() factory - tool registration
│   ├── index.ts        ← stdio entry point
│   └── http-server.ts  ← HTTP entry point + /health endpoint
├── dist/               ← build output (gitignored)
│   ├── index.js        ← stdio bundle (with #!/usr/bin/env node shebang)
│   └── http-server.js  ← HTTP bundle
├── build.mjs           ← esbuild config (two outputs in parallel)
├── tsconfig.json       ← type-check only (noEmit), bundling via esbuild
├── server.json         ← MCP marketplace manifest
├── Dockerfile          ← multi-stage build → image with http-server.js
├── icon.svg
└── package.json

Known limitations

  • Partial coverage - SAOS indexes mainly courts of appeal and regional courts; district courts are less complete

  • Anonymized parties - the API returns (...) instead of party names; this is a feature of the SAOS database

  • decision field - available mainly for Supreme Court judgments; for common courts the operative part is extracted via HTML parsing

  • In-memory cache - 15 min TTL, resets on process restart

  • HTTP mode - does not save .md files (no access to the user's file system)


About SAOS

SAOS (System Analizy Orzeczeń Sądowych - System of Analysis of Court Judgments) is an open academic project led by the Interdisciplinary Centre for Mathematical and Computational Modelling (ICM) at the University of Warsaw, funded by the National Centre for Research and Development (grant IS-1/040/NCBR/2014).

The platform aggregates judgments from Polish common courts, administrative courts, the Supreme Court (Sąd Najwyższy), the Constitutional Tribunal (Trybunał Konstytucyjny), and the National Appeals Chamber (KIO). Data is imported automatically from official court portals. Personal data appearing in judgments is processed under GDPR Art. 6(1)(e) (public interest); responsibility for its publication rests with the source court systems.

The API is freely accessible with no authentication required.

Disclaimer: This tool is intended for legal research only and is not a substitute for professional legal advice. Always verify citations against primary sources before relying on them in legal proceedings.


License

Apache-2.0 © Paweł Ojdowski

Available Tools

3 tools
saos_get_judgmentA

Pobiera pełne orzeczenie z SAOS po ID. Zwraca metadane + sentencję dosłownie + pełne uzasadnienie. W trybie lokalnym zapisuje też plik .md z kopią archiwalną.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesID orzeczenia z wyników saos_search_judgments

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses a notable side effect: in local mode, it saves an .md archival file. It also explicitly details the return content (metadata, verbatim sententia, full justification). Given no annotations exist, this is valuable behavioral disclosure, though it leaves 'local mode' and permissions unspecified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long, front-loaded with the main action and followed by concrete details about returns and side effects. There is no filler or unnecessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter retrieval tool with no output schema and no annotations, the description adequately covers what is returned and the side effect. It leaves a gap in explicitly linking to the search workflow, but the schema parameter description fills that gap, overall making the description complete enough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single 'id' parameter, which already explains the ID comes from search results. The description only adds the redundant 'po ID' phrase, so it contributes no additional semantic meaning beyond the schema baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Pobiera' (retrieves) and resource 'pełne orzeczenie z SAOS' (full judgment from SAOS), scoped by ID. This clearly distinguishes it from siblings such as saos_search_judgments (search) and saos_list_courts (list courts).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention that it should be used after obtaining an ID from saos_search_judgments, nor does it address exclusions or alternatives. Usage context is only implied by the schema parameter description, not the description text.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saos_list_courtsA

Zwraca listę sądów powszechnych (ID, nazwa, typ). Użyj żeby znaleźć ID sądu do filtrowania w saos_search_judgments.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses the output structure (ID, name, type) and the fact that it returns a list. Since it's a simple read-only list operation with no side effects, this is sufficient. It doesn't mention auth or rate limits, but they are not critical for this tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short, focused sentences. Every word earns its place, providing the return type and usage context without any fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with no parameters, no annotations, and no output schema. The description fully covers what is returned and when to use it, making it complete for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the schema coverage is 100% and the baseline is 4. The description adds no parameter details, but none are needed since no parameters exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns a list of common courts with ID, name, and type, using a specific verb and resource. It also differentiates from siblings by explicitly mentioning its role in providing court IDs for filtering in saos_search_judgments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit usage guidance: 'Use to find the court ID for filtering in saos_search_judgments.' This tells exactly when to use the tool and references a sibling tool, making the context clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saos_search_judgmentsA

Wyszukuje orzeczenia sądowe w bazie SAOS (sortowanie: najnowsze pierwsze).

ZASADA NACZELNA — frazy prawne zawsze w cudzysłowie: • query: "umowa o dzieło" → szuka tej dokładnej frazy (wysokа precyzja) • query: umowa o dzieło (bez cudzysłowu) → AND po słowach osobno = fałszywe trafienia

STRATEGIA — stosuj warstwowo:

  1. Główne pojęcie w cudzysłowie: "umowa o dzieło", "rękojmia za wady", "bezpodstawne wzbogacenie"

  2. Dodaj keyword= z hasłem tematycznym SAOS — to kuratorowana taksonomia niezależna od treści, np. keyword: "umowa o dzieło"

  3. Połączenie query + keyword daje najlepszą precyzję

  4. Dodaj judgmentType=SENTENCE gdy szukasz wyroków merytorycznych (nie postanowień)

PRZYKŁADY: • query: "umowa o dzieło" "wynagrodzenie", judgmentType: SENTENCE • query: "nienależyte wykonanie", keyword: "umowa o dzieło" • query: "odstąpienie od umowy" "wada", ccCourtType: APPEAL • caseNumber: "VIII GC 23/24" → konkretna sygnatura

Jeśli wyniki są nieistotne: dodaj cudzysłowy, dołącz keyword, zawęź typ sądu lub daty.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryNoFull-text search. Frazy prawne ZAWSZE w cudzysłowie: "umowa o dzieło", "nienależyte wykonanie". Bez cudzysłowu = AND po słowach osobno = niski precision. Można łączyć frazy: "umowa o dzieło" "wynagrodzenie"
dateToNoFormat YYYY-MM-DD
keywordNoHasło tematyczne z kuratorowanej taksonomii SAOS — niezależne od FTS, filtruje po klasyfikacji redakcyjnej. Przykłady: 'umowa o dzieło', 'odszkodowanie', 'rękojmia'. Łącz z query dla najwyższej precyzji.
dateFromNoFormat YYYY-MM-DD
pageSizeNoLiczba wyników (max 20, domyślnie 10)
judgeNameNoImię i nazwisko sędziego
caseNumberNoDokładna sygnatura akt, np. 'VIII GC 23/24'
pageNumberNoNumer strony (od 0)
ccCourtTypeNoTyp sądu: APPEAL (apelacyjny) | REGIONAL (okręgowy) | DISTRICT (rejonowy)
judgmentTypeNoSENTENCE (wyrok) | DECISION (postanowienie) | RESOLUTION (uchwała)

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses key behavioral traits: exact phrases require quotes, unquoted queries become AND across words causing false hits, keyword is an editorial taxonomy independent of content, and judgmentType=SENTENCE targets substantive judgments. This goes beyond the schema and provides valuable operational nuances.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (golden rule, strategy, examples) and front-loaded with the main purpose. Although somewhat long, each section earns its place by offering actionable guidance for a search tool with 10 parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex search tool (10 params, no output schema), the description covers the most critical parameters: query semantics, keyword behavior, judgmentType, ccCourtType, caseNumber, and date narrowing. It also provides troubleshooting. It omits minor details like pagination or judgeName, but those are self-explanatory from the schema, so the description is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds substantial semantic value by explaining how to format queries (quoting), the meaning of keyword as a curated taxonomy, and how to combine parameters for better precision. Examples illustrate query+keyword and query+judgmentType combinations, exceeding baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Wyszukuje orzeczenia sądowe w bazie SAOS' which is a specific verb+resource (searches court judgments in SAOS) and adds sort order. This clearly distinguishes it from sibling tools like saos_get_judgment (retrieval) and saos_list_courts (court list).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context and a detailed layered strategy for when to use quotes, combine query with keyword, and add judgmentType or ccCourtType. It also includes concrete examples and troubleshooting advice. However, it does not explicitly contrast with alternative tools, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.0.6
    • First observedsaos_get_judgment
    • First observedsaos_list_courts
    • First observedsaos_search_judgments

TDQS

A4.4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: searching judgments, fetching a specific judgment by ID, and listing courts. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tool names follow a consistent pattern: saos_ + verb + noun (search_judgments, get_judgment, list_courts). This makes the API predictable and easy to navigate.

Tool Count5/5

With only 3 tools, the server is tightly scoped to its purpose of accessing court judgments. This is an appropriate size for a focused legal database, avoiding unnecessary complexity.

Completeness5/5

The tool set covers the complete workflow: find courts for filtering, search for judgments with rich query options, and retrieve full details for a specific judgment. There are no obvious gaps for typical use cases.

Maintenance

ActivityStale
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers