mcp-nsa
This server provides access to 2,390,000+ rulings from Polish administrative courts (NSA + 16 WSA) via the CBOSA database (orzeczenia.nsa.gov.pl), covering case law from 1981 to today.
Search for rulings (
search) — query by keywords (e.g.,RODO art 6,tajemnica skarbowa), returning the top 5 results with metadata: case number, court, date, judicial panel, thematic keywords, legal basis, and a content excerpt.Filter searches — narrow results by court (NSA or any of the 16 regional WSA courts), date range (
dateFrom/dateTo), case number (caseNumber), or page for pagination.Retrieve a full judgment by document ID (
get_judgment) — fetch a complete ruling using its 10-character hexdoc_id, returning full metadata plus up to 2,000 characters of the ruling text.Search by case number (
search_by_case) — a shortcut to find a ruling directly by its case signature (e.g.,III OSK 1377/23,I SA/Gl 659/22).
Every response includes structured citations with fields (title, url, case_number, court, judgment_date, decision_type, snippet, doc_id) for easy integration. Key legal areas covered include GDPR/data protection, tax law, customs, administrative permits, and review of public administration activity.
mcp-nsa
Installation (one command)
Published on npm + the MCP Registry (io.github.matematicsolutions/mcp-nsa). Run without cloning:
npx -y @matematicsolutions/mcp-nsaMCP client configuration (stdio):
{ "mcpServers": { "mcp-nsa": { "command": "npx", "args": ["-y", "@matematicsolutions/mcp-nsa"] } } }(Building from source - below.)
MCP server for the case law of the Polish administrative courts -
Naczelny Sad Administracyjny / NSA (Supreme Administrative Court) + 16 Wojewodzkie Sady Administracyjne / WSA (regional administrative courts) - via CBOSA (Centralna Baza Orzeczen Sadow Administracyjnych - the administrative courts' central case-law database)
(orzeczenia.nsa.gov.pl).
Related MCP server: mcp-isap
Why
SAOS (the common-courts case-law analysis system) does not index the administrative courts. Yet that is exactly where the substantive case law lives:
GDPR / data protection - decisions of the President of UODO appealed to the WSA, cassation appeals to the NSA
Taxes - individual tax rulings, decisions of tax authorities
Customs and excise
Administrative permits, concessions
Review of public-administration activity
mcp-nsa closes this gap. Coverage: 2,390,000+ rulings (verified live 2026-07-08 across the full date range), from 1981 to today.
Tools
search(query, caseNumber?, court?, dateFrom?, dateTo?, pageNumber?)search by keyword, case number, court, date. Fetches the top 5 full rulings (case number, court, date, panel, keywords, legal basis, excerpt).
get_judgment(doc_id)- full ruling by 10-character hex doc_id (from the CBOSA URL, e.g.7E50984BB7).search_by_case(caseNumber)- shortcut: search by case number (e.g.III OSK 1377/23,I SA/Gl 659/22).
Every response contains structuredContent.citations with the fields:
title, url (CBOSA), case_number, court, judgment_date,
decision_type, snippet, doc_id. Patron reads this field automatically
and surfaces it in the UI panel as the section "Rulings from CBOSA (NSA / WSA - administrative courts)".
Stack
Node 18+
@modelcontextprotocol/sdkStdio transport
https+ regex HTML parser (zero external deps beyond the SDK)500 ms throttle between requests (2 req/s)
SSL:
rejectUnauthorized: false- the CBOSA chain is sometimes incomplete on some machines; public rulings, no PII, MITM risk negligible against the benefit. See: LDH issue #167.
Build + run
npm install
npm run build
node dist/index.js # starts the server on stdioWiring into Patron
In patron/backend/mcp-servers.json (alongside mcp-saos and mcp-eu-sparql):
{
"name": "nsa",
"transport": "stdio",
"command": "node",
"args": ["C:/Users/<YOUR-USERNAME>/mcp-nsa/dist/index.js"],
"enabled": true
}Smoke test
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"s","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search","arguments":{"query":"RODO art 6"}}}' \
| node dist/index.jsShould return ~1500 hits + the top 5 with Polish NSA/WSA case numbers + CBOSA URLs
structuredContent.citations.
Lineage
Implementation rewritten in TypeScript on the basis of the HTTP/HTML contract from
legal-data-hunter/sources/PL/NSA
(Python + BeautifulSoup, MIT). It does not import the source code - it reproduces the
query pattern and HTML parsing.
License
MIT.
Part of the MateMatic legal stack
This server is one of five MCP connectors covering Polish jurisdiction + EU law, used by Patron (AGPL-3.0) and any other MCP-aware legal AI agent.
mcp-nsa (this repo) - NSA + 16 WSA administrative courts (CBOSA)
mcp-saos - common courts, SN, TK, KIO
mcp-isap - Polish legislation (Dz.U. + M.P.)
mcp-krs - Polish company registry (KRS)
mcp-eu-sparql - EU law + CJEU (EUR-Lex)
All five MCP servers share the same structuredContent.citations
contract: each tool returns an array of {title, url, snippet?, ...metadata}
that legal agents can render directly in their citation panel.
See matematicsolutions/.github for the full org profile.
Available Tools
3 toolsget_judgmentARead-onlyIdempotent
Pobiera pelne orzeczenie z CBOSA po jego doc_id (10-znakowy hex). Zwraca metadane (sygnatura, sad, data, sklad, hasla tematyczne, podstawe prawna, typ orzeczenia) + pierwsze 2000 znakow tresci (sentencja + uzasadnienie). doc_id pochodzi z wynikow narzedzia 'search'.
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes | 10-znakowy hex doc_id z URL CBOSA, np. '7E50984BB7'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and description confirms it is a read operation. Adds behavioral detail that only first 2000 characters of content are returned.
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, no wasted words. Action verb 'pobiera' front-loaded, structure clear.
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?
Without output schema, description adequately lists returned metadata fields and states content truncation at 2000 characters. Sufficient for agent to use tool.
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?
Single parameter doc_id with schema description providing format example. Description reinforces the format and source, adding value beyond schema.
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?
Description clearly states it retrieves a full judgment by doc_id, specifies the format (10-znakowy hex), and notes the doc_id comes from the 'search' tool, distinguishing it from 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?
Explicitly says doc_id comes from 'search' results, implying usage after search. Does not explicitly state when not to use, but context of sibling tools provides differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-onlyIdempotent
Przeszukuje Centralna Baze Orzeczen Sadow Administracyjnych (CBOSA) - Naczelny Sad Administracyjny + 16 wojewodzkich sadow administracyjnych. TU zyje merytoryczne orzecznictwo RODO/UODO, podatkowe, celne, kontrola decyzji administracji publicznej. SAOS NIE indeksuje tego pionu. Dla MVP zwraca top-N wynikow z pelnymi metadanymi (sygnatura, sad, data, sklad, hasla tematyczne, podst. prawna, fragment tresci). Max 5 dokumentow pobranych w jednym zapytaniu - kazda kolejna szczegolowa lektura przez get_judgment z konkretnym doc_id.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Slowa kluczowe (pole 'wszystkieSlowa' w CBOSA), np. 'RODO art 6' albo 'tajemnica skarbowa'. | |
| caseNumber | No | Sygnatura akt, np. 'III OSK 1377/23' (NSA) albo 'I SA/Gl 659/22' (WSA). | |
| court | No | Nazwa sadu (pelna). Domyslnie wszystkie sady administracyjne. | |
| dateFrom | No | Data orzeczenia od (YYYY-MM-DD). | |
| dateTo | No | Data orzeczenia do (YYYY-MM-DD). | |
| pageSize | No | Liczba wynikow na strone z CBOSA (10-100). Domyslnie 20. Tylko z pierwszych 5 pobierane sa pelne dane. | |
| pageNumber | No | Numer strony (od 1). Do paginacji. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds value by explaining the return behavior (top-N results with full metadata, max 5 documents per query, and the MVP nature). No contradictions 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 paragraph of four sentences in Polish. It includes some domain-specific commentary that, while informative, could be trimmed for conciseness. It is front-loaded with the primary action.
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?
The description covers the database scope, return metadata, result limit, and relationship with get_judgment. It is fairly complete for an MVP tool, though it could clarify the interaction between pageSize and the max 5 limit. The schema descriptions help fill in the gaps.
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 100% with each parameter having a description. The tool description does not add parameter-specific semantics beyond what is in the schema, so baseline score of 3 applies.
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 tool searches the CBOSA database of administrative court judgments, specifies the courts included, and notes the domain (GDPR, tax, etc.). It differentiates from siblings by mentioning that detailed reading should use get_judgment and implies that search_by_case is for case number searches.
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 provides clear context on when to use the tool (for broad searches) and explicitly instructs to use get_judgment for detailed document retrieval. However, it does not explicitly state when not to use it or compare with search_by_case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_by_caseARead-onlyIdempotent
Skrot: szuka orzeczenia po sygnaturze. Odpowiednik search z parametrem caseNumber. Jesli orzeczenie nie znajdzie sie - sygnatura moze byc z sadu powszechnego/SN/TK/KIO (uzyj wtedy saos__search_by_case).
| Name | Required | Description | Default |
|---|---|---|---|
| caseNumber | Yes | Sygnatura akt, np. 'III OSK 1377/23'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true. The description adds value by explaining this is a shortcut equivalent to search with caseNumber, and that it may not find judgments from certain courts, prompting a fallback. 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?
Very concise: two sentences convey purpose, equivalence, and fallback advice. Every sentence earns its place with no fluff.
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?
Given the tool's simplicity (one parameter, no output schema, safe annotations), the description is nearly complete. It states what it searches, the input format, and provides error handling guidance. Minor gap: no mention of the output structure, but it implies a judgment object. Almost complete.
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 100% with one parameter 'caseNumber' described with an example. The description adds that if the judgment is not found, the case number might be from other courts, but this is contextual rather than direct parameter semantics. Baseline 3 is appropriate.
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 it searches for a judgment by case number ('szuka orzeczenia po sygnaturze'). It distinguishes from siblings by being a shortcut for 'search' with the caseNumber parameter and provides a fallback alternative (saos__search_by_case) for other court types.
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?
Explicitly tells when to use: as a shortcut for search with caseNumber. Also gives guidance on when not to: if judgment not found, case number might be from other courts (common, Supreme, etc.), then use saos__search_by_case. This clear when-to-use and alternative advice is excellent.
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.
3 tool updates
v1.1.0- First observed
get_judgment - First observed
search - First observed
search_by_case
TDQS
Tools are mostly distinct: search for general queries, search_by_case for case number lookup, and get_judgment for full retrieval by ID. The only minor overlap is that search_by_case is described as a shortcut for search with a case number, which could cause slight confusion but is clearly documented.
All tool names use a consistent snake_case pattern with verbs (get, search) followed by nouns or qualifiers. The naming is uniform and predictable across the set.
With 3 tools covering search, retrieval, and case-specific lookup, the set is minimal but reasonable for a focused legal database. The scope is narrow (administrative courts), so no heavy tool count is needed.
The tools cover basic search and retrieval, but notable gaps exist: lack of filtering by date, court level, or other metadata in search, and get_judgment only returns the first 2000 characters, limiting full-text access. Agents may need workarounds for deeper queries.
Maintenance
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
MCP server for 3M+ Polish companies — KRS & CEIDG financials, ownership, and industry search.
Slovak court decisions as MCP tools. 12,000+ decisions, GDPR-compliant, pseudonymized, SLA-backed.
TED MCP Server: Real-time EU public tenders access. https://www.lexsocket.ai/
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for Polish case-law (SAOS) — Supreme Court, Constitutional Tribunal, common courts and KIO — with ECLI and verifiable citations.3642MIT
- AlicenseAqualityAmaintenanceMCP server for Polish legislation (ISAP / Sejm) — search acts (Dz.U., M.P.) and fetch full texts with ELI identifiers and verifiable citations.31081MIT
- AlicenseAqualityAmaintenanceMCP server for Polish public-procurement rulings (KIO / Krajowa Izba Odwoławcza) with verifiable citations.51Apache 2.0
- AlicenseAqualityBmaintenanceUnified 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.41Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/matematicsolutions/mcp-nsa'
If you have feedback or need assistance with the MCP directory API, please join our Discord server