Skip to main content
Glama

mcp-tk

Serwer MCP dla polskiego orzecznictwa Trybunału Konstytucyjnego. Korzysta wyłącznie z oficjalnych serwisów TK:

Nie używa SAOS ani komercyjnych baz, nie wymaga konta i nie wymaga klucza API.

Po co

mcp-tk daje modelowi rzeczywiste orzeczenia TK: sygnaturę, datę, rodzaj, przedmiot, skład, pełny tekst, bezpośredni link i pozycję OTK ZU. Długie dokumenty można pobierać sekcjami i porcjami, zamiast zużywać cały budżet kontekstu naraz.

Related MCP server: SAOS MCP

Instalacja

Wymagany jest Node.js 18+. Serwer nie wymaga konta ani klucza API.

ChatGPT desktop — zalecany sposób

Zainstaluj serwer jednorazowo w terminalu:

npm install -g https://github.com/tramer222888-alt/mcp-tk/archive/refs/heads/main.tar.gz

Następnie w ustawieniach MCP wybierz STDIO.

Windows:

  • polecenie: cmd.exe

  • argumenty: /d, /s, /c, mcp-tk — każdy jako osobna pozycja

macOS/Linux:

  • polecenie: mcp-tk

  • bez argumentów

Instalacja przed dodaniem MCP jest celowa: ChatGPT ma krótki limit startu procesu, a pobieranie pakietu przez npx może go przekroczyć.

Codex CLI

Po wykonaniu powyższego npm install -g:

codex mcp add tk -- mcp-tk

Na Windows, jeśli bezpośrednie uruchomienie nie działa:

codex mcp add tk -- cmd.exe /d /s /c mcp-tk

Gotowe pliki dist są wersjonowane w repozytorium, więc serwer nie kompiluje TypeScriptu podczas startu.

Narzędzia

Tool

Działanie

search(query, searchMode?, searchInContent?, where?, inflection?, dateFrom?, dateTo?, kind?, pageSize?, pageNumber?)

Wyszukiwanie tematyczne. Domyślny searchMode=auto przeszukuje lokalny indeks pełnej treści oficjalnych dokumentów IPO, bez czekania na formularz portalu.

search_by_signature(signature, pageSize?, pageNumber?)

Dokładne wyszukiwanie po sygnaturze, np. K 23/11.

list_recent(pageSize?, pageNumber?)

Najnowsze orzeczenia bezpośrednio z żywej listy IPO.

get_judgment(id, caseId?, section?, offset?, maxChars?)

Pełny tekst i metadane. id może być ID IPO (25657) albo pozycją OTK ZU (2026/A/96).

Każda odpowiedź zawiera structuredContent.citations. get_judgment umieszcza pobrany fragment również w structuredContent.judgment.content_chunk, ponieważ część klientów MCP pokazuje modelowi tylko dane strukturalne.

Cztery tryby wyszukiwania

Domyślny searchMode=auto przeszukuje lokalnie pełną treść orzeczeń pobraną z oficjalnego IPO. Dzięki temu skróty i nazwy występujące dopiero w uzasadnieniu — np. BGK — nie znikają tylko dlatego, że nie ma ich w polu „Dotyczy”. Wyszukiwanie nie czeka na wolny formularz JSF portalu.

Tryby:

  • searchMode=auto — zalecany; szybki lokalny indeks pełnej treści, z prostym uwzględnianiem odmiany słów;

  • searchMode=full_text — ten sam pełnotekstowy indeks, jawnie wymagany;

  • searchMode=metadata — tylko sygnatura, rodzaj, data i pole „Dotyczy”; najszybszy, ale o słabej kompletności;

  • searchMode=live — żywy formularz JSF IPO; pozwala ograniczyć sekcję przez where, ale jest wolny i awaryjny.

Stary parametr searchInContent pozostaje obsługiwany: true odpowiada full_text, a falsemetadata. Nowe wywołania powinny używać searchMode.

Indeksy są automatycznie odświeżane przez GitHub Actions co tydzień. Każda odpowiedź podaje index_generated_at. Jeśli podczas pierwszej publikacji brakuje jeszcze indeksu pełnej treści, auto jawnie zwraca tymczasowe metadane; nie uruchamia w tle wielominutowego formularza.

searchMode=live uruchamia pełnotekstowy formularz JSF oficjalnego IPO. Parametr where pozwala ograniczyć wyszukiwanie do:

  • wszedzie

  • komparycja

  • sentencja

  • uzasadnienie

  • historia

  • przed_rozprawa

  • na_rozprawie

  • ocena_prawna

  • zdanie_odrebne

Formularz TK bywa przeciążony i może odpowiadać znacznie wolniej niż pobieranie dokumentów. Błąd [upstream_error] oznacza jawną awarię lub timeout źródła, nie „zero wyników”.

Przykład kwerendy nastawionej na kompletność:

search(query="BGK", searchMode="auto", inflection=false, pageSize=50)

Długie orzeczenia: sekcje i offset

get_judgment wykrywa następujące sekcje:

Sekcja

Zawartość

calosc

cały dokument

sklad

skład orzekający

sentencja

rozstrzygnięcie (orzeka / postanawia)

uzasadnienie

całe uzasadnienie

stanowiska_uczestnikow

część poprzedzająca własną ocenę TK

ocena_trybunalu

fragment od „Trybunał Konstytucyjny zważył…”

zdania_odrebne

zdania odrębne

maxChars przyjmuje 500–50 000 znaków (domyślnie 15 000). offset jest liczony od początku wybranej sekcji. Odpowiedź zawiera bezwzględny zakres znaków, mapę sekcji, has_more i gotowy next_offset.

Przykładowy tok pracy:

  1. search({ query: "prawo do sądu" })

  2. get_judgment({ id: "25567", section: "ocena_trybunalu" })

  3. jeżeli has_more=true: ponowne wywołanie z tym samym section i podanym next_offset

Pozycje OTK ZU

Można podać bezpośrednio identyfikator publikacji:

get_judgment(id="2026/A/96")

Serwer pobiera oficjalną stronę OTK ZU, odczytuje z niej powiązane identyfikatory IPO, a następnie pobiera tekst na żywo. W odpowiedzi zachowuje oddzielnie:

  • url — strona dokumentu IPO,

  • otkzu_url — pozycja Zbioru Urzędowego,

  • otkzu_pdf_url — urzędowy PDF, gdy jest dostępny.

Obsługiwany jest nowy format RRRR/A/POZ oraz starszy RRRR/NR-A/POZ.

Cytowania

structuredContent.citations[] zawiera:

{
  "title": "Wyrok K 7/18 z 2026-06-24",
  "url": "https://...",
  "signature": "K 7/18",
  "date": "2026-06-24",
  "author": "Trybunał Konstytucyjny",
  "snippet": "...",
  "doc_id": "25567",
  "case_id": "20793"
}

Dla pobranego orzeczenia preferowanym URL cytowania jest bezpośrednia pozycja OTK ZU, jeżeli metadane pozwalają ją jednoznacznie wyznaczyć; w pozostałych przypadkach używany jest oficjalny dokument IPO.

Bezpiecznik na dryf portali

Oba serwisy są publiczne, ale ich kontrakt techniczny nie jest dokumentowany. Konektor sprawdza między innymi:

  • obecność formularza wyszukiwanie, JSF ViewState i znanych pól,

  • strukturę listy oraz pagera,

  • identyfikatory dokument i sprawa,

  • kontener pełnego tekstu tekst_{id},

  • odsyłacz OTK ZU → IPO.

Zniknięcie krytycznego elementu daje [api_changed] z linkiem do issues. Awaria sieci lub HTTP daje [upstream_error]. Brak dokumentu lub sekcji daje [not_found]. Konektor nie zamienia błędu portalu w pozornie poprawny pusty wynik.

Transport i bezpieczeństwo

  • Node.js 18+, TypeScript, @modelcontextprotocol/sdk, stdio.

  • Natywny node:http2: host IPO przy połączeniu HTTP/1.1 potrafi przyjąć połączenie i nie wysłać odpowiedzi.

  • Bez wyłączania weryfikacji TLS.

  • Stała allowlista dwóch hostów TK i ścieżek portali; argument użytkownika nie staje się dowolnym URL.

  • Limit długości zapytań i rozmiaru fragmentów.

  • Około 2–3 żądania na sekundę, retry tylko dla błędów przejściowych.

  • Brak telemetrii i danych uwierzytelniających.

Zakres danych

Szybki indeks metadanych odzwierciedla listę dostępną w IPO (elektroniczny korpus portalu, w praktyce od końca lat 90.). Sam OTK ZU ma szerszy katalog historyczny; znaną starszą pozycję można pobrać przez jej identyfikator. Brak wyniku indeksowego nie dowodzi, że bardzo stare orzeczenie nie istnieje.

Build, testy i indeks

npm install
npm run build
npm run test:parse   # testy offline parserów, sekcji, offsetów i drift guardów
npm run smoke        # test LIVE: lista + pełny tekst z oficjalnego IPO
npm run index        # przebudowa data/ipo-index.json z oficjalnej listy
npm run index:fulltext # przebudowa skompresowanego indeksu pełnej treści
npm run verify:index  # kontrola regresji: co najmniej 7 dokumentów dla BGK
node dist/index.js   # serwer MCP na stdio

Testy offline używają małych fixture'ów odtwarzających rzeczywistą strukturę HTML portali. Live smoke jest uruchamiany ręcznie, aby zwykłe CI nie zależało od chwilowej dostępności TK.

Konfiguracja ręczna

{
  "mcpServers": {
    "tk": {
      "command": "node",
      "args": ["/ścieżka/do/mcp-tk/dist/index.js"]
    }
  }
}

Uwaga prawna

Konektor udostępnia źródła, nie udziela porady prawnej. Przy powoływaniu orzeczenia sprawdź jego pełną treść, datę, sentencję, późniejsze orzecznictwo oraz skutki wynikające z art. 190 Konstytucji. Wynik wyszukiwania tematycznego jest kandydatem do analizy, a nie automatycznie „linią orzeczniczą”.

Podziękowania

Układ MCP, structuredContent.citations, porcjowanie i jawna obsługa dryfu są rozwinięciem wzorca z HelpToSave/mcp-eureka, który z kolei wskazuje konektory mcp-nsa Wiesława Mazura. Rozpoznanie stabilnych elementów publicznego HTML IPO porównano także z otwartym projektem worldwidelaw/legal-sources; implementacja w tym repozytorium jest niezależna.

Licencja

MIT © 2026 Mateusz Bednarski. Zobacz LICENSE.

Available Tools

4 tools
get_judgmentA
Read-onlyIdempotent

Pobiera na żywo pełny tekst orzeczenia z oficjalnego IPO. id może być numerem dokumentu IPO albo pozycją OTK ZU, np. 2026/A/96. Obsługuje sekcje, offset i porcje 500–50 000 znaków.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesID dokumentu IPO albo referencja OTK ZU RRRR/A/POZ.
caseIdNoOpcjonalny ID sprawy IPO zwrócony przez wyszukiwanie.
offsetNoPrzesunięcie od początku wybranej sekcji.
sectionNocalosc, sklad, sentencja, uzasadnienie, stanowiska_uczestnikow, ocena_trybunalu lub zdania_odrebne.
maxCharsNo

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the description does not need to repeat them. It adds useful behavioral details: the data is fetched live, sections are supported, and large results are returned in chunks of 500–50,000 characters. No contradiction with annotations.

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?

Two sentences convey the core purpose, accepted ID formats, an example, and the main paging/section features. No filler or repetition of schema details; it is front-loaded and every sentence earns its place.

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 read-only retrieval tool with rich schema descriptions and clear annotations, the description covers the essential calling concepts: ID forms, sections, offset, and character limits. It does not mention how `caseId` affects behavior or what the exact return structure looks like, but these are minor given the absence of an output schema and the clarity of the rest.

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 80%, so the baseline is 3. The description adds real value by explaining that `id` can be either an IPO document number or an OTK ZU reference, with an example, and by summarizing the section/offset/chunking behavior that maps to `section`, `offset`, and `maxChars` — including the 500–50,000 character range.

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 verb and resource: it fetches the full text of a judgment live from the official IPO. It also clarifies what `id` can be and gives a concrete example, making the tool's scope unmistakable and distinct from the search/list siblings.

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

Usage Guidelines3/5

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

The description implies the usage context: use this when you have a specific ID or OTK reference and want the full judgment text. However, it does not explicitly contrast with sibling tools like `search` or `list_recent`, nor does it state when not to use this tool.

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

list_recentA
Read-onlyIdempotent

Pobiera na żywo najnowsze orzeczenia z oficjalnej listy IPO TK.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageSizeNo
pageNumberNo

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already cover read-only, idempotent, open-world, and non-destructive behavior. The description adds useful context by saying the data is fetched 'na żywo' (live) and from the 'oficjalnej listy' (official list), but it discloses nothing about pagination behavior, data freshness guarantees, or result shape. No contradiction with annotations.

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 a single short sentence with no filler. Every element contributes: live retrieval, recency, subject, and source. It is front-loaded and easy to parse.

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 low-complexity read-only list tool, the description plus schema constraints is mostly sufficient. The main missing piece is an explicit note about pagination or the response format, but the parameter names and the word 'list_recent' make the expected behavior reasonably inferable.

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

Parameters2/5

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

Schema description coverage is 0%, and the description does not mention pageSize or pageNumber. The parameter names and schema bounds give some clues, but the description itself adds no semantic meaning to help an agent understand pagination behavior or how values should be used.

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 states an explicit action ('Pobiera na żywo' = fetches live), a specific resource ('najnowsze orzeczenia z oficjalnej listy IPO TK' = latest rulings from the official IPO TK list), and a distinct scope ('najnowsze' = latest). This clearly differentiates it from sibling tools like search, search_by_signature, and get_judgment.

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?

No guidance is given about when to prefer this tool over the siblings search, search_by_signature, or get_judgment. The description implies a use case through 'najnowsze', but it does not state when to use it, when not to, or which alternative fits other scenarios.

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

search_by_signatureA
Read-onlyIdempotent

Wyszukuje po dokładnej sygnaturze TK, np. K 23/11 albo SK 45/09, w indeksie z oficjalnego IPO.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageSizeNo
signatureYes
pageNumberNo

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds the source (official IPO index) and exact-match semantics, which is useful but does not go deeper into pagination or match behavior. No contradiction with annotations.

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?

One efficient sentence with the action, key examples, and data source front-loaded. No filler or repeated 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 simple exact-lookup tool with strong annotations, the description covers the core query and source. It could mention pagination behavior or explicitly contrast with 'search', but those are minor gaps given the tool's simplicity.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate. It adds meaning for 'signature' by explaining exact TK signature format and giving examples, but it says nothing about 'pageSize' or 'pageNumber', leaving two parameters under-described.

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 ('Wyszukuje'), identifies the resource (the official IPO index), and states the exact criterion (TK signature) with concrete format examples. This clearly differentiates it from the broader sibling 'search'.

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?

It clearly implies when to use the tool: when the exact TK signature is known, reinforced by examples. It does not explicitly name alternatives or exclusions, but the context is specific enough for an agent to select it appropriately.

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. 4 tool updatesv1.0.0
    • First observedget_judgment
    • First observedlist_recent
    • First observedsearch
    • First observedsearch_by_signature

TDQS

A4.1/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: general search, signature-specific search, recent listings, and full-text retrieval. No two tools are likely to be confused for one another.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern (search, search_by_signature, list_recent, get_judgment), making the API predictable and intuitive.

Tool Count5/5

With 4 tools, the server is well-scoped for a focused domain of retrieving Polish Constitutional Tribunal judgments. Every tool earns its place without redundancy.

Completeness5/5

The tool surface covers the full lifecycle for a read-only lookup service: general search, specific signature lookup, listing recent entries, and fetching full texts. No obvious gaps remain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables AI-powered legal research and analysis of Polish legal acts from the Sejm API. Provides comprehensive search, document retrieval, metadata analysis, and content access for legal documents from Dziennik Ustaw and Monitor Polski.
    13
    21
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Provides access to Polish court judgments from the SAOS database. Enables search and retrieval of judgments with full-text search, filtering, and detailed case information.
    3
    20 npm
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search over Polish court judgments and legislative acts via MCP. Allows LLMs to retrieve legal documents using natural language queries.
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    MCP server for querying live Polish court case law (orzecznictwo) via the SAOS API, offering tools to search judgments, fetch full cases, find judgments citing specific statutory provisions, and check Constitutional Tribunal citations.
    7
    Apache 2.0