fi-eli-mcp
This server provides read-only access to Finnish statutes from the Finlex open-data API, returning structured metadata and full legal text in Akoma Ntoso 3.0 XML format. No API key is required.
Tools available:
fi_list_acts— List all Finnish statutes published in a given year, returning titles, ELI URIs, statute numbers, subtypes, dates, and human-readable citations (e.g.,Tietosuojalaki (1050/2018)).fi_get_act— Fetch metadata for a specific statute by year and number, including ELI URI, FRBR URI, title (Finnish/Swedish), subtype, and source URL.fi_get_text— Download the complete Akoma Ntoso 3.0 XML text of a statute by year and number, along with its byte size, ELI URI, and citation.
Key notes:
Every response includes verifiable ELI URIs and source URLs for independent verification.
Covers Finnish statutes (saadokset) only — case law is not supported.
Statute titles may appear in Finnish or Swedish (bilingual country).
An audit log of every tool call is maintained locally.
Click on "Install 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., "@fi-eli-mcplist all Finnish statutes from 2023"
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.
fi-eli-mcp
Install (one command)
Published on PyPI + MCP Registry (io.github.matematicsolutions/fi-eli-mcp). Run without cloning:
uvx fi-eli-mcpConfigure your MCP client (stdio):
{ "mcpServers": { "fi-eli-mcp": { "command": "uvx", "args": ["fi-eli-mcp"] } } }Windows 11 with Smart App Control
Smart App Control blocks unsigned executables, which covers uvx.exe, pip.exe
and the fi-eli-mcp.exe launcher that pip writes at install time. The python.exe and
py.exe from the python.org installer are signed by the Python Software
Foundation, so running the module through the interpreter works:
python -m pip install fi-eli-mcp
python -m fi_eli_mcppip.exe is blocked for the same reason, so install with python -m pip, not
pip install. If python is not on PATH, use the Windows launcher: py -3 -m fi_eli_mcp.
{ "mcpServers": { "fi-eli-mcp": { "command": "python", "args": ["-m", "fi_eli_mcp"] } } }Do not turn Smart App Control off to work around this - it cannot be re-enabled without reinstalling Windows.
Building from source: see Install.
An MCP server for the Finnish Finlex open-data API (opendata.finlex.fi). It fetches
consolidated Finnish statutes as Akoma Ntoso 3.0 XML, with verifiable ELI identifiers and
Finnish citations.
Part of the MateMatic eu-legal-mcp production line - after PL, DE, AT and ES. Same citation
contract, Finlex source.
Scope. This MVP covers Finnish statutes (saadokset). Discovery is by year (
fi_list_acts) or by year + number; the open-data API is path-based, not keyword search. Finland is bilingual, so titles may be Finnish or Swedish. Every response carries adataset_note.Licence. Finnish legislation in Finlex is official public information published as open data (keyless). This connector relays it with attribution and a
source_url.
Related MCP server: lu-eli-mcp
The tools
Tool | What it does |
| List the statutes of a year (discovery). |
| Metadata for a statute by year + number. |
| Full Akoma Ntoso text of a statute by year + number. |
| Declare what this connector covers, when each family was captured, and - explicitly - what it does NOT cover. Every gap carries a fallback. |
Every response carries the contract: eli_uri (a full ELI URL, e.g.
http://data.finlex.fi/eli/sd/2018/1050/alkup), human_readable_citation
(e.g. Tietosuojalaki (1050/2018)), and source_url.
Install
cd fi-eli-mcp
pip install -e .Configure (Claude Code / any MCP client)
{
"mcpServers": {
"fi-eli-mcp": { "command": "fi-eli-mcp" }
}
}Environment:
FI_ELI_BASE_URL- defaulthttps://opendata.finlex.fi/finlex/avoindata/v1FI_ELI_CACHE_DIR- default~/.matematic/cache/fi-eliFI_ELI_AUDIT_DIR- default~/.matematic/audit
No API key. Finlex open data is keyless.
Governance
Public data only - read-only against Finlex; no client data leaves the machine.
Audit log - every tool call appends one JSON line to
~/.matematic/audit/fi-eli-mcp.jsonl.Vendor-neutral - talks only to
opendata.finlex.fi; no LLM provider, no telemetry.Verifiable citations - every response is independently checkable via
source_url.
See CONSTITUTION.md and DISCOVERY.md.
Tests
pip install -e ".[dev]"
pytest tests/test_instructions_drift.py -v # offline
pytest tests/test_smoke.py -v # hits live FinlexLicence
Apache-2.0. © Matematic Solutions / Wieslaw Mazur.
Available Tools
4 toolsfi_coverageARead-onlyIdempotent
Declare what this connector covers, how it is sourced, and what it does NOT cover.
Call this before telling a user that the law "does not contain" something, and whenever a search comes back empty: the absence may be a gap in this connector rather than in the law. Every gap carries a fallback saying where to look instead.
Returns:
Coverage with families, an as-of note, and a non-empty list of known gaps.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| status | No | |
| families | No | |
| as_of_note | Yes | States what the dates mean, and what they do not promise. |
| known_gaps | No | Never empty. An empty list would mean 'not checked', not 'no gaps'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the annotations by explaining the open-world nature of the tool: an empty search result may indicate a connector gap, not legal absence. It also discloses the return shape, including families, an as-of note, and known gaps with fallbacks, which is genuinely useful for calibration.
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 compact and front-loaded: it opens with the core purpose, then gives concrete usage triggers, then summarizes the return object. Every sentence adds either purpose, usage guidance, or behavioral context with no filler.
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 zero parameters and an existing output schema, the description is complete: it covers what the tool does, when to invoke it, why it matters for empty search results, and what the response contains. No critical calling context is missing.
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?
The tool has zero parameters and an empty input schema, so there is no parameter semantics to document. The baseline for zero-parameter tools is 4, and the description appropriately does not invent parameter details.
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 a specific verb and resource: it declares what the connector covers, how it is sourced, and what it does not cover. It clearly differentiates from sibling tools like fi_list_acts and fi_get_act by focusing on coverage metadata rather than act listing or retrieval.
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?
Usage is explicit: call before telling a user the law does not contain something, and whenever a search comes back empty. It also explains that every gap carries a fallback, which tells the agent what to do next rather than leaving the decision implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fi_get_actARead-onlyIdempotent
Fetch statute metadata by year and number.
| Name | Required | Description | Default |
|---|---|---|---|
| year | Yes | e.g. ``2018``. | |
| number | Yes | e.g. ``1050``. |
Output Schema
| Name | Required | Description |
|---|---|---|
| year | No | |
| title | No | |
| number | No | |
| eli_uri | No | |
| subtype | No | |
| frbr_uri | No | |
| source_url | No | |
| date_issued | No | |
| date_published | No | |
| human_readable_citation | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations fully cover safety (readOnly, idempotent) so description adds minimal extra context. Does not elaborate on what metadata includes or any side effects.
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?
Single sentence with no unnecessary words, clearly front-loads the purpose.
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 rich annotations and presence of output schema, the description covers all necessary information succinctly.
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 simple parameter descriptions. Description confirms usage of year and number but adds no new semantics beyond the 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?
Clear verb 'fetch', specific resource 'statute metadata', and unique selection criteria 'by year and number'. Distinct from siblings which suggest full text or listing.
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 explicit guidance on when to use this tool over fi_get_text or fi_list_acts. Context can be inferred but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fi_get_textBRead-onlyIdempotent
Fetch the full Akoma Ntoso text of a statute by year and number.
| Name | Required | Description | Default |
|---|---|---|---|
| year | Yes | e.g. ``2018``. | |
| number | Yes | e.g. ``1050``. |
Output Schema
| Name | Required | Description |
|---|---|---|
| year | Yes | |
| format | No | |
| number | Yes | |
| content | No | |
| eli_uri | No | |
| byte_size | No | |
| source_url | No | |
| dataset_note | No | |
| human_readable_citation | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds the context that the text is 'full Akoma Ntoso' format, but does not detail behavioral aspects like error handling or scope beyond the 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with the action. It is concise, but could be more valuable by briefly differentiating from siblings without adding length.
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, full schema coverage, and presence of an output schema, the description adequately explains what the tool does and how to identify the statute. It does not explain error handling or disambiguation from siblings, but overall it is sufficient for basic use.
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?
The input schema has 100% coverage with clear parameter descriptions (year and number with examples). The description merely restates 'by year and number', adding no additional meaning beyond the 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?
The description clearly states the tool fetches the full Akoma Ntoso text of a statute by year and number. The verb 'fetch' and resource 'full Akoma Ntoso text' are specific, but it does not differentiate from sibling tools like fi_get_act or fi_list_acts.
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 no guidance on when to use this tool versus alternatives. It does not mention conditions, prerequisites, or situations where fi_get_act or fi_list_acts would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fi_list_actsARead-onlyIdempotent
List Finnish statutes published in a given year.
| Name | Required | Description | Default |
|---|---|---|---|
| year | Yes | e.g. ``2018``. |
Output Schema
| Name | Required | Description |
|---|---|---|
| year | Yes | |
| items | No | |
| total | Yes | |
| dataset_note | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide read-only, idempotent, and non-destructive hints. The description adds no further behavioral detail beyond the parameter scope, consistent 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?
A single, well-structured sentence that directly states the tool's purpose with no waste.
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 simple one-parameter tool, presence of output schema, and comprehensive annotations, the description is adequate for understanding the tool's function, though it lacks guidance on result format or limits.
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 of 'year' (e.g., 2018) is 100% covered; the description's mention of 'given a year' adds no new meaning beyond the parameter 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?
The description uses a specific verb 'List' and resource 'Finnish statutes' with scope 'published in a given year', clearly distinguishing from sibling tools like 'fi_get_act' which likely fetches a single act.
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 use when wanting statutes by year but does not explicitly state when to use this over siblings or provide context on year range or coverage.
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 tool update
v0.3.3- Added
fi_coverage
3 tool updates
v0.1.0- First observed
fi_get_act - First observed
fi_get_text - First observed
fi_list_acts
TDQS
Each tool has a clearly distinct purpose: listing statutes by year, fetching metadata, fetching full text, and declaring coverage gaps. There is no overlap or ambiguity between them.
Three tools follow a consistent verb_noun pattern (fi_list_acts, fi_get_act, fi_get_text), but fi_coverage is a noun-only name that breaks the pattern. The inconsistency is minor and doesn't cause confusion.
With 4 tools, the server is small but well-scoped for a focused legal data connector. The count is slightly below the typical range but each tool serves a necessary function in retrieval and transparent coverage reporting.
The tool surface covers core read operations (list, get metadata, get text) plus explicit coverage handling, which is a thoughtful safeguard. A keyword search or version history would be a natural addition but its absence is not a critical gap for the apparent purpose.
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
Resolve, search and verify legal citations against the official sources, with provenance.
Search Swiss federal legislation: laws, articles, amendments via the Fedlex SPARQL endpoint.
Temporal search and comparison for official Luxembourg and reviewed EU law, with provenance.
Agent-native API for Finnish public company data via YTJ. Pay-per-call $0.01 USDC over x402.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI agents to search and retrieve consolidated Swedish statutes (SFS) from the Riksdagen open data API, with verifiable citations and persistent identifiers.4Apache 2.0
- AlicenseAqualityAmaintenanceEnables querying Luxembourg legislation metadata and full Akoma Ntoso text via ELI identifiers from Legilux open data.31Apache 2.0
- AlicenseAqualityAmaintenanceProvides access to Danish legislation from Retsinformation.dk, enabling retrieval of act metadata, full text, and recent changes with verifiable citations.4Apache 2.0
- AlicenseAqualityBmaintenanceEnables access to Slovak legislation from the Collection of Laws via static.slov-lex.sk. Supports listing consolidated versions, retrieving act metadata, and fetching full text with verifiable citations.4Apache 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/fi-eli-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server