mcp-tk
This MCP server provides access to Polish Constitutional Tribunal (Trybunał Konstytucyjny) official judgments via MCP tools.
search(query, ...) – search judgments thematically in metadata or full text, with date/kind filters, pagination, inflection, and optional section (
where).search_by_signature(signature, ...) – find exact docket number (e.g.,
K 23/11).list_recent(pageSize, pageNumber) – retrieve latest judgments from the official IPO list.
get_judgment(id, ...) – fetch full text and metadata by IPO document ID or OTK ZU reference (e.g.,
2026/A/96), with section selection (sentencja, uzasadnienie, etc.), character offsets, chunked reading, andnext_offset/has_more.Responses include structured citations (title, URL, signature, date, doc_id, case_id) and official OTK ZU URLs/PDF links.
Provides multiple search modes (
auto,full_text,metadata,live) with safeguards and explicit errors for portal drift or upstream failures.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-tkPokaż najnowsze orzeczenia Trybunału Konstytucyjnego"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.gzNastępnie w ustawieniach MCP wybierz STDIO.
Windows:
polecenie:
cmd.exeargumenty:
/d,/s,/c,mcp-tk— każdy jako osobna pozycja
macOS/Linux:
polecenie:
mcp-tkbez 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-tkNa Windows, jeśli bezpośrednie uruchomienie nie działa:
codex mcp add tk -- cmd.exe /d /s /c mcp-tkGotowe pliki dist są wersjonowane w repozytorium, więc serwer nie
kompiluje TypeScriptu podczas startu.
Narzędzia
Tool | Działanie |
| Wyszukiwanie tematyczne. Domyślny |
| Dokładne wyszukiwanie po sygnaturze, np. |
| Najnowsze orzeczenia bezpośrednio z żywej listy IPO. |
| Pełny tekst i metadane. |
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ę przezwhere, ale jest wolny i awaryjny.
Stary parametr searchInContent pozostaje obsługiwany: true odpowiada full_text, a false — metadata. 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:
wszedziekomparycjasentencjauzasadnieniehistoriaprzed_rozprawana_rozprawieocena_prawnazdanie_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ść |
| cały dokument |
| skład orzekający |
| rozstrzygnięcie ( |
| całe uzasadnienie |
| część poprzedzająca własną ocenę TK |
| fragment od „Trybunał Konstytucyjny zważył…” |
| 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:
search({ query: "prawo do sądu" })get_judgment({ id: "25567", section: "ocena_trybunalu" })jeżeli
has_more=true: ponowne wywołanie z tym samymsectioni podanymnext_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, JSFViewStatei znanych pól,strukturę listy oraz pagera,
identyfikatory
dokumentisprawa,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 stdioTesty 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 toolsget_judgmentARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID dokumentu IPO albo referencja OTK ZU RRRR/A/POZ. | |
| caseId | No | Opcjonalny ID sprawy IPO zwrócony przez wyszukiwanie. | |
| offset | No | Przesunięcie od początku wybranej sekcji. | |
| section | No | calosc, sklad, sentencja, uzasadnienie, stanowiska_uczestnikow, ocena_trybunalu lub zdania_odrebne. | |
| maxChars | No |
TDQS
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.
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.
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.
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.
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.
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_recentARead-onlyIdempotent
Pobiera na żywo najnowsze orzeczenia z oficjalnej listy IPO TK.
| Name | Required | Description | Default |
|---|---|---|---|
| pageSize | No | ||
| pageNumber | No |
TDQS
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.
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.
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.
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.
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.
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.
searchARead-onlyIdempotent
Wyszukuje orzeczenia TK. Domyślnie przeszukuje szybki indeks oficjalnych metadanych IPO (sygnatura, rodzaj, data, pole „Dotyczy”). searchInContent=true uruchamia pełnotekstowy formularz oficjalnego IPO.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Dla indeksu: opcjonalny rodzaj, np. wyrok albo postanowienie. | |
| query | Yes | Fraza po polsku; w indeksie metadanych wszystkie słowa muszą wystąpić. | |
| where | No | Dla searchInContent: wszedzie, komparycja, sentencja, uzasadnienie, historia, przed_rozprawa, na_rozprawie, ocena_prawna lub zdanie_odrebne. | wszedzie |
| dateTo | No | Data orzeczenia do, RRRR-MM-DD. | |
| dateFrom | No | Data orzeczenia od, RRRR-MM-DD. | |
| pageSize | No | ||
| inflection | No | Dla searchInContent: uwzględniaj odmianę słów. | |
| pageNumber | No | ||
| searchInContent | No | true: szukaj w treści przez żywy formularz IPO; portal bywa wolny. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey read-only, idempotent, non-destructive behavior. The description adds non-obvious behavioral context by explaining that the default path uses a 'szybki indeks' of official metadata while searchInContent=true invokes the live full-text IPO form, implying different backends and performance profiles. This goes beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action, and no filler. The second sentence efficiently explains the key behavioral switch. Every clause contributes to understanding how the tool behaves.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 parameters, two operational modes, and no output schema, the description is serviceable but leaves gaps: it does not describe return values, result shape, or pagination behavior, and it does not point to sibling tools for specialized lookups. The schema and annotations compensate for many gaps, but the overall description is not fully complete for safe autonomous selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (78%) and the schema already explains most parameters. The description adds meaningful semantics by enumerating the metadata fields searched by default (sygnatura, rodzaj, data, 'Dotyczy') and clarifying that searchInContent changes the search backend, which helps agents understand query and searchInContent behavior beyond raw parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action and resource ('Wyszukuje orzeczenia TK') and distinguishes two search modes: default metadata index and full-text via searchInContent=true. It does not explicitly contrast with sibling tools like search_by_signature, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives practical guidance on when to use the default metadata index versus the full-text IPO form, and the schema notes the portal can be slow. However, it provides no guidance on when to prefer this tool over siblings such as search_by_signature or list_recent, and no when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_by_signatureARead-onlyIdempotent
Wyszukuje po dokładnej sygnaturze TK, np. K 23/11 albo SK 45/09, w indeksie z oficjalnego IPO.
| Name | Required | Description | Default |
|---|---|---|---|
| pageSize | No | ||
| signature | Yes | ||
| pageNumber | No |
TDQS
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.
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.
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.
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.
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.
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.
4 tool updates
v1.0.0- First observed
get_judgment - First observed
list_recent - First observed
search - First observed
search_by_signature
TDQS
Scored across 4 tools
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.
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.
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.
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
Related MCP Connectors
Semantic search over Polish law and case law, citing the exact in-force article.
Polish law: search statutes (ISAP), court rulings, verify citations. Free tier + paid plans + x402.
Resolve, search and verify legal citations against the official sources, with provenance.
Verified Polish open data for AI agents: debt, budget, 460 MPs, votings, judiciary search, RAG.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables 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.1321MIT
- AlicenseAqualityCmaintenanceProvides access to Polish court judgments from the SAOS database. Enables search and retrieval of judgments with full-text search, filtering, and detailed case information.320 npm1Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables semantic search over Polish court judgments and legislative acts via MCP. Allows LLMs to retrieve legal documents using natural language queries.Apache 2.0
- AlicenseAqualityBmaintenanceMCP 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.7Apache 2.0