Skip to main content
Glama

mcp-eureka

MCP server dla polskich interpretacji indywidualnych (Dyrektor Krajowej Informacji Skarbowej) przez publiczne API systemu EUREKA Ministerstwa Finansów (eureka.mf.gov.pl).

Po co

mcp-eureka daje Claude'owi dostęp do realnych interpretacji indywidualnych — z sygnaturą, tezą, treścią i linkiem — zamiast zgadywania z pamięci.

Zakres: tylko interpretacje indywidualne (KATEGORIA_INFORMACJI = 1).

Related MCP server: CRU MCP Server

Instalacja jednym poleceniem (Claude Code)

claude mcp add eureka -- npx -y github:HelpToSave/mcp-eureka

Windows: jeśli npx nie odpala się bezpośrednio, użyj claude mcp add eureka -- cmd /c "npx -y github:HelpToSave/mcp-eureka". Wymagany Node 18+ i git w PATH; pierwsze uruchomienie buduje serwer (skrypt prepare).

Tooly

  • search(query, dateFrom?, dateTo?, searchInContent?, fullPhrase?, sort?, pageSize?, pageNumber?) — wyszukiwanie po słowach kluczowych, domyślnie sortowane po trafności. searchInContent=true i fullPhrase=true zawężają wynik (precyzja), sort="data_desc" przełącza na najnowsze. Zwraca top-N z sygnaturą (SYG), organem, datą wydania i tezą. Zob. Recall i precyzja.

  • get_interpretation(id, section?, offset?, maxChars?) — treść interpretacji po ID_INFORMACJI. Zwraca metadane, pełną tezę i fragment treści (domyślnie 15 000 znaków) wraz z mapą sekcji. Treść jest oczyszczana z HTML i sklejana w płynne akapity (reflowText) — bez „porozrywanych" pojedynczych wierszy. Zob. Długie dokumenty.

  • search_by_signature(signature) — skrót: szukaj po sygnaturze KIS (np. 0115-KDST2-2.4011.218.2026.2.KK).

  • suggest(phrase) — podpowiedzi fraz (autocomplete).

Każda zwrotka zawiera structuredContent.citations: title, url (eureka.mf.gov.pl/informacje/podglad/{id}), signature, date, author, snippet, doc_id.

get_interpretation dodatkowo zwraca structuredContent.interpretation (sygnatura, daty, teza, content_chunk, content_range, has_more, next_offset, sections, url) — bo część klientów MCP (m.in. konektory claude.ai) pokazuje modelowi wyłącznie structuredContent; bez tego treść ginęła mimo obecności w content.

Długie dokumenty: sekcje i offset

Interpretacje KIS bywają bardzo długie — 90 tys. znaków to norma — i mają stałą strukturę:

nagłówek → stan faktyczny → pytanie → stanowisko wnioskodawcy
        → OCENA STANOWISKA + uzasadnienie organu → pouczenie

Uzasadnienie organu leży ok. 60–70% długości dokumentu. Oznacza to, że fragment liczony od początku pokazuje wyłącznie stan faktyczny — czyli to, co napisał wnioskodawca, a nie to, jak organ uzasadnił rozstrzygnięcie. Dlatego get_interpretation przyjmuje:

Parametr

Działanie

section="uzasadnienie"

skok do oceny stanowiska i argumentacji organu

offset=N

przewinięcie o N znaków (wartość podpowiadana w odpowiedzi)

maxChars=N

rozmiar fragmentu, 500–50 000, domyślnie 15 000

Dostępne sekcje: stan_faktyczny, pytanie, stanowisko, uzasadnienie, rozstrzygniecie, pouczenie. Każda odpowiedź zawiera mapę wykrytych sekcji z pozycjami znakowymi oraz — gdy dokument się nie zmieścił — jawne [...] To FRAGMENT z gotowym offset do dalszego ciągu. Model dostaje więc informację, że widzi część dokumentu, i wie, jak sięgnąć po resztę.

Limit istnieje z powodu budżetu tokenów: 90 tys. znaków to ok. 30 tys. tokenów na jeden dokument. Stronicowanie jest świadomym kompromisem — całość pozostaje dostępna, ale model pobiera ją porcjami.

Recall i precyzja: jak pytać EUREKĘ

Sam dostęp do bazy nie wystarcza — liczy się, czy agent dostaje wszystkie istotne interpretacje (recall) i czy nie dostaje nieistotnych (precyzja). Wyszukiwarka EUREKI to Elasticsearch z rozmytym dopasowaniem po rdzeniach słów, co daje kilka pułapek. Wszystkie poniższe liczby zmierzone na żywym API 2026-07-31 (skrypty w historii commitów):

1. Sortowanie po trafności, nie po dacie. To była najpoważniejsza wada wcześniejszych wersji. Zapytanie „50% koszty uzyskania przychodów aktor prawa autorskie" (2 622 dopasowania):

Sortowanie

Czołówka wyników

po dacie (data_desc)

licencje na oprogramowanie, UPO polsko-belgijska, IP Box, WHT — zero w temat

po trafności (domyślne)

„Czy wnioskodawca ma prawo zastosować 50% koszty uzyskania przychodu?", honorarium autorskie, art. 22 ust. 9 pkt 3 — wszystkie w temat

Przy tysiącach rozmytych dopasowań sortowanie po dacie zwracało 10 najnowszych zamiast 10 najtrafniejszych.

2. Polskie znaki są obowiązkowe. EUREKA nie normalizuje diakrytyków:

Zapytanie

Trafienia

podwyzszone koszty uzyskania

0

podwyższone koszty uzyskania

293 077

dzialalnosc badawczo-rozwojowa

99

działalność badawczo-rozwojowa

31 729

To najczęstsza cicha przyczyna pustego wyniku. Konektor wykrywa zapytania wyglądające na polskie bez diakrytyków i zwraca ostrzeżenie zamiast milczącego zera. Z tego samego powodu instrukcje dla modelu są pisane poprawną polszczyzną — model naśladuje język promptu, a wersja bez ogonków uczyła go formułować zapytania, które nie trafiają.

3. Liczba dopasowań jest zawyżona. aktor daje 14 322 dopasowania, co nie znaczy 14 322 interpretacji o aktorach. Przy wyniku > 1000 konektor dopisuje modelowi ostrzeżenie, żeby nie raportował tej liczby jako liczby trafnych interpretacji.

4. Krótkie zapytania i kilka podejść. 2–4 słowa kluczowe biją całe zdanie, a kilka wąskich zapytań bije jedno szerokie — terminologia KIS bywa inna niż potoczna (honorarium autorskie vs 50% koszty uzyskania vs prawa pokrewne artysty wykonawcy). Zero wyników to zwykle wada zapytania, nie brak interpretacji.

Bezpiecznik na dryf API (api_changed)

API EUREKI jest nieoficjalne i może się zmienić bez zapowiedzi. Konektor waliduje strukturę każdej odpowiedzi: gdy znikną krytyczne pola (ID_INFORMACJI, SYG/TEZA, dokument.fields, suggestion), zwraca jawny błąd [api_changed] z prośbą o zgłoszenie issue — zamiast cichego pustego wyniku, który kosztuje godziny zgadywania. Kosmetyczne zmiany kontraktu (nowe pola, przestawiona kolejność) nie wywracają konektora.

Stack

  • Node 18+, stdio, @modelcontextprotocol/sdk

  • https + czyste JSON API REST (bez scrapowania HTML)

  • Bez klucza API, bez logowania. Throttle ~350 ms (≈3 req/s).

  • Ważny certyfikat SSL (brak rejectUnauthorized:false).

Kontrakt API (nieoficjalny, odtworzony 2026-06)

Baza: https://eureka.mf.gov.pl/api/public/v1

  • POST /wyszukiwarka/informacje?size=&page=&sort=ID_INFORMACJI,DESC body: { filter:{KATEGORIA_INFORMACJI:[1]}, columns:[...], searchQuery, searchInContent, ... }

  • GET /informacje/{id} → pełny dokument (dokument.fields[]: SYG, TEZA, DT_WYD, TRESC_INTERESARIUSZ, …)

  • GET /wyszukiwarka/sugestie/{fraza} → podpowiedzi

  • GET /parametry-wyszukiwarki/all → słowniki filtrów (fasety)

To nieoficjalne API SPA — może się zmienić bez zapowiedzi.

Build + uruchomienie

npm install
npm run build
node dist/index.js   # serwer na stdio

Testy

npm run test:parse   # offline - parsowanie/formattery/drift guard na realnych
                     # fixture'ach API (nie wymaga sieci)
npm run smoke        # LIVE - pelny przebieg 4 tooli po stdio przeciwko
                     # eureka.mf.gov.pl (throttled; EUREKA miewa przerwy)

Skrypt pomocniczy: porządkowanie plików .md

scripts/format-md.mjs skleja „porozrywany" tekst interpretacji zapisany do pliku Markdown (każda wizualna linia źródła bywa osobnym łamaniem) w płynne akapity, zachowując wypunktowania. Działa wyłącznie na sekcji pod nagłówkiem ## Pełna treść; nagłówek z metadanymi pozostaje nietknięty. Bez zależności, czysty Node (UTF-8 natywnie).

node scripts/format-md.mjs sciezka/do/pliku.md      # jeden plik
node scripts/format-md.mjs sciezka/do/folderu        # wszystkie .md w folderze

Konfiguracja ręczna (alternatywa)

W .mcp.json projektu (obok innych serwerów). Podaj ścieżkę do dist/index.js:

{
  "mcpServers": {
    "eureka": {
      "command": "node",
      "args": ["/sciezka/do/mcp-eureka/dist/index.js"]
    }
  }
}

Windows: jeśli node nie jest w PATH, podaj pełną ścieżkę do node.exe, np. "command": "C:\\Program Files\\nodejs\\node.exe" oraz "args": ["C:\\Users\\TwojUser\\mcp-servers\\mcp-eureka\\dist\\index.js"].

Uwaga prawna

Interpretacja indywidualna chroni tylko wnioskodawcę i tylko w jego stanie faktycznym. To nie źródło prawa ani linia orzecznicza sensu stricto. Cytuj z tą świadomością.

Podziękowania

Architektura (transport stdio, kontrakt structuredContent.citations, układ tooli i obsługa błędów) wzorowana na mcp-nsa autorstwa Wiesława Mazura — zestawie konektorów MateMatic do polskiego orzecznictwa.

Licencja

MIT © 2026 Mateusz Bednarski. Zobacz LICENSE.

Available Tools

4 tools
get_interpretationA
Read-onlyIdempotent

Pobiera pelna interpretacje indywidualna po ID (z wynikow 'search'). Zwraca metadane (sygnatura, data wydania/publikacji, teza) oraz pelna tresc (stan faktyczny, stanowisko wnioskodawcy, ocena organu, uzasadnienie) - pierwsze 4000 znakow.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesID interpretacji (ID_INFORMACJI) z wynikow search, np. '694514'.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already mark the tool as read-only, open-world, idempotent, and non-destructive. The description adds useful behavioral details: it returns first 4000 characters of content and lists specific metadata fields. No contradictions.

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, front-loaded with the verb 'Pobiera' (Fetches), and contains no superfluous information. Every sentence adds value.

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?

No output schema, but the description adequately explains what is returned (metadata fields and first 4000 characters of content). It is sufficient for a fetch operation, though error handling is not mentioned.

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 description adds value by providing a concrete example ('694514') and linking the parameter to search results, clarifying its origin beyond the schema.

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's purpose: retrieving a full individual interpretation by ID from search results, returning metadata and content. It distinguishes itself from siblings (search, search_by_signature, suggest) by specifying the ID-based retrieval from search results.

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 indicates usage after obtaining an ID from the 'search' tool, providing context for when to use this tool. It does not explicitly state when not to use it or list alternatives, but the context is clear.

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

Skrot: szuka interpretacji po sygnaturze KIS, np. '0115-KDST2-2.4011.218.2026.2.KK'. Odpowiednik search z fraza = sygnatura.

ParametersJSON Schema
NameRequiredDescriptionDefault
signatureYesSygnatura interpretacji KIS, np. '0115-KDST2-2.4011.218.2026.2.KK'.

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows it's safe. The description adds that it's a 'shortcut' and equivalent to a search operation, providing minor behavioral context beyond annotations. No contradictions.

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 consists of two concise sentences that front-load the core purpose and example, then clarify the relationship to a sibling tool. Every sentence adds value with no redundant 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?

Given the tool's simplicity (one parameter, no output schema), the description is mostly complete. It explains the tool's purpose and equivalence to search, but does not describe the return format or output. Since the sibling search likely has a known output, this is a minor gap.

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% with a well-described 'signature' parameter. The description adds that this parameter is used as the phrase in a search equivalent, but this does not significantly add meaning beyond the schema's own description. Baseline 3 is appropriate.

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 searches for interpretations (interpretacji KIS) by signature, with an example. It distinguishes itself from the sibling 'search' by being a shortcut equivalent to searching with the phrase equal to the signature, making the specific resource and verb clear.

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 explicitly relates to sibling 'search' by saying it's equivalent to 'search with phrase = signature', providing clear context for when to use this tool (when you have a signature). However, it does not explicitly state when not to use it or mention alternatives like 'get_interpretation' or 'suggest'.

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

suggestA
Read-onlyIdempotent

Podpowiedzi fraz (autocomplete) z EUREKI dla czesciowego zapytania - pomaga doprecyzowac slowa kluczowe przed wlasciwym search.

ParametersJSON Schema
NameRequiredDescriptionDefault
phraseYesCzesciowa fraza, np. 'ulga na'.

TDQS

A4.1/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, covering safety and idempotency. Description adds EUREKI source and autocomplete purpose, but no major behavioral detail beyond 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?

Single sentence that is efficient and front-loaded with the core purpose, no wasted words.

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?

Given the tool's simplicity (one parameter, no output schema, rich annotations), the description adequately explains its purpose and usage context without requiring additional detail.

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% with a single parameter 'phrase' having a description. The tool description adds no new meaning beyond what the schema provides ('partial phrase' vs 'Partial phrase, e.g., ulga na').

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 it provides phrase suggestions (autocomplete) from EUREKI for partial queries, distinguishing it from sibling tools like search which is the actual 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?

Implies usage before actual search to refine keywords, but lacks explicit when-not or alternative conditions. Contextually clear given sibling tools.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv1.1.0
    • First observedget_interpretation
    • First observedsearch
    • First observedsearch_by_signature
    • First observedsuggest

TDQS

A4.3/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: search for general queries, get_interpretation for retrieving full text, search_by_signature for direct lookup by signature, and suggest for autocomplete. No overlap or ambiguity.

Naming Consistency5/5

All tool names use lowercase verbs with underscores (search, get_interpretation, search_by_signature, suggest) following a consistent and predictable pattern.

Tool Count5/5

With 4 tools, the server is well-scoped for its purpose of searching and retrieving Polish tax interpretations. The number of tools is appropriate and not excessive.

Completeness4/5

The tool set covers the core workflows: search (including by signature), retrieval of full text, and query suggestion. Minor gaps like filtering by date or pagination are absent but not critical for basic use.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    MCP server for searching and retrieving over 550,000 Polish tax documents from the EUREKA system, providing verifiable citations with signatures and URLs.
    4
    66
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    MCP server providing access to Polish business registers (KRS, CRBR) via the rejestr.io API, enabling search, retrieval of organizations, beneficial owners, financial documents, and more.
    12
    -
  • A
    license
    A
    quality
    B
    maintenance
    Unified MCP server for Polish legal data, enabling search and retrieval across case law, legislation, company register, tax rulings, public procurement, and EU sources through four aggregated tools.
    4
    1
    Apache 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HelpToSave/mcp-eureka'

If you have feedback or need assistance with the MCP directory API, please join our Discord server