i14y-mcp
i14y-mcp is a read-only MCP server for discovering and inspecting Switzerland's national metadata catalogue (I14Y/BFS): who publishes what, through which interface, and under which licence.
Search the catalogue with free-text queries, filtered by language, type, theme, and publisher (
search_catalog).List and inspect datasets — complete paginated register plus full metadata records, including contact point, coverage, documentation, and distributions (
list_datasets,get_dataset).Get download details — per-distribution formats, access/download URLs, media types, and licences (
get_dataset_distributions).Discover official APIs — register of Swiss public data services with endpoint URLs and OpenAPI descriptions (
list_data_services,get_data_service).Explore administrative services and concepts — public service offerings, harmonised concepts/code lists, and individual code-list entries (
list_public_services,list_concepts,get_concept,search_codelist_entries).Find publishers and catalogues — publishing bodies with Swiss UID join keys, and contributing catalogues (
list_publishers,list_catalogs).Check upstream availability —
api_statusdistinguishes “no data matched” from “source is down” with an evaluable status.Every result includes provenance, retrieval timestamp, and source attribution; all tools are read-only and idempotent.
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., "@i14y-mcpsearch for datasets about special needs education"
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.
Part of the Swiss Public Data MCP Portfolio — a collection of open-source MCP servers connecting AI agents to Swiss public and open data. This is a private project. It is not affiliated with, endorsed by, or operated on behalf of any employer or public authority.
i14y-mcp
MCP server for the I14Y interoperability platform — Switzerland's national metadata catalogue.
Why this server exists
The other servers in this portfolio answer «what does the data say?». This one answers the question that comes first: «who publishes data on this topic, through which interface, under which licence?»
I14Y is the national data catalogue maintained by the Federal Statistical Office. It describes datasets, registered APIs, public services and harmonised concepts from the Confederation, cantons and communes, using the DCAT-AP-CH profile (eCH-0200).
Mnemonic: «Catalogue before shelf.» Without a catalogue, an agent has to already know a data source exists. With one, it can find it.
Related MCP server: swiss-food-safety-mcp
🎯 Anchor Demo Query
«Which authority publishes data on special needs education, through which interface is it available, and under which licence?»
search_catalog(query="Sonderpädagogik")
→ «Statistik der Sonderpädagogik» — Federal Statistical Office (BFS), theme: Bildung
get_dataset(dataset_id=...)
→ 2 distributions, licence: «Opendata BY ASK — attribution required,
commercial use only with permission from the data supplier»
→ contact: auskunftsdienst@bfs.admin.chTwo tool calls turn a vague topic into a named authority, a download URL and a
licence you can act on — get_dataset aggregates the distributions, licences
and contact point into one record.
Demo
Architecture
┌──────────────────────────────┐
│ MCP Host (Claude) │
└───────────────┬──────────────┘
│ stdio | streamable-http
┌───────────────▼──────────────┐
│ i14y-mcp │
│ ┌────────────────────────┐ │
│ │ server.py (13 tools) │ │
│ ├────────────────────────┤ │
│ │ mappers.py │ │ DCAT → flat, one language
│ ├────────────────────────┤ │
│ │ models.py (Pydantic) │ │ source + provenance envelope
│ ├────────────────────────┤ │
│ │ client.py │ │ retry 2s/4s/8s, no-retry 4xx
│ └────────────────────────┘ │
└───────────────┬──────────────┘
│ HTTPS, no auth
┌───────────────▼──────────────┐
│ api.i14y.admin.ch/api │
│ datasets · dataservices · │
│ concepts · publicservices · │
│ catalogs · agents · search │
└──────────────────────────────┘Architecture decision
This server uses Architecture A (live API only).
Rationale (verified live on 2026-07-21):
All read endpoints respond without authentication and paginate correctly.
No bulk download of catalogue metadata is offered, and none is needed.
Error responses follow RFC 7807, so failure modes are distinguishable.
Consequences:
Every HTTP call retries transient failures with 2 s / 4 s / 8 s backoff.
search_catalogcaps results client-side because the upstream ignores paging.api_statusalways returns an evaluable state instead of empty records.
Full probe report: docs/probe-i14y.md.
Project phase
This server is in Phase 1 (read-only) of the portfolio's «Read-only First»
phase architecture: all tools are read-only, there is no authentication and no
personal data. See docs/roadmap.md for the phase model and
the prerequisites for any future write capability.
Tools
Tool | Purpose |
| Free-text search across the catalogue. Entry point. |
| Paginated dataset register (complete, unlike search). |
| Full metadata record for one dataset. |
| Download URLs, formats and licences. |
| Register of official Swiss APIs with endpoint URLs. |
| Full record for one registered interface. |
| Administrative services for citizens. |
| Harmonised concepts and code lists. |
| One concept definition. |
| Individual codes of a code list. |
| Publishing bodies, with Swiss UID. |
| Contributing catalogues. |
| Reachability check with graceful degradation. |
All tools are annotated readOnlyHint: true. Write operations exist in the
upstream API but are deliberately not exposed.
MCP primitives
This server exposes Tools only — no Resources, no Prompts. That is a deliberate choice, not an omission: I14Y is queried by free-text search and by opaque UUIDs, so there is no small, stable set of addressable URIs that would map cleanly onto MCP Resources, and the server ships no opinionated prompt templates. Every tool is read-only and idempotent; if a future stable entry point emerges (e.g. a fixed theme list) it is a candidate for a Resource.
MCP Protocol Version
This server speaks two protocol eras over the same endpoint. The client's first request on a connection decides which one applies; a later claim from the other era is refused.
Era | Revision | Who reaches it |
|
| What today's clients speak. The server answers with the revision asked for, or with the |
Per-request envelope |
| A request carrying the |
Both revisions are pinned in
tests/test_protocol_version.py and asserted
against the installed SDK, so a Dependabot bump of mcp cannot move either one
silently. The handshake ceiling is measured against a live initialize through
the assembled ASGI stack, not read off a constant name.
Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern
era, not for the handshake era — pinning against it alone would leave the era
that current clients actually negotiate free to drift.
What the server carries on the modern revision
2026-07-28 moves discovery off the initialize handshake onto
server/discover plus a per-request _meta envelope, and gives every cacheable
result a freshness hint. What this server puts on those surfaces is measured in
tests/test_spec_2026_07_28.py through the
assembled stack — and, for stdio, through a real subprocess — rather than read
back off the configuration:
Surface | What this server answers |
| name, display title, description, website, and the installed distribution version — the same version the outbound |
| how to sequence the tools, plus the two properties of I14Y that no single tool description shows |
| 300 s, |
| a display name per tool, so a client shows «Search a concept's code list» rather than |
The freshness hint is not cosmetic. With none set, the SDK answers ttlMs: 0, cacheScope: private — «already stale, never share» — for directories that are
fixed at import and cannot change while the process runs.
Both transports serve the modern revision: HTTP through the streamable-HTTP
session manager, and stdio — the default, and what uvx i14y-mcp starts —
through the same dual-era loop. Neither is evidence for the other, so both are
measured.
One thing this server advertises but does not use. On 2026-07-28 the
listChanged flags and resources.subscribe derive solely from whether
subscriptions/listen is served, and the SDK wires that handler
unconditionally. server/discover therefore reports listChanged: true for a
tool list that is fixed at import, and a subscribe capability over an empty
resource list; no change notification is ever sent. It is not switchable
through the public API — only a wholesale replacement of the server/discover
handler could do it, which would be a second truth about our own capabilities —
so it is pinned by a test instead of papered over.
Update policy. When the gate fails, do not edit the constant blindly: read
the spec changelog between the two revisions, verify the server still behaves,
then move the constant, this section, README.de.md and
CHANGELOG.md together.
Installation
uvx i14y-mcpOr from source:
git clone https://github.com/malkreide/i14y-mcp
cd i14y-mcp
pip install -e ".[dev]"Claude Desktop
{
"mcpServers": {
"i14y": {
"command": "uvx",
"args": ["i14y-mcp"]
}
}
}Remote deployment (Render, Railway)
I14Y_MCP_TRANSPORT=streamable-http HOST=0.0.0.0 PORT=8000 i14y-mcpI14Y_MCP_TRANSPORT accepts stdio (the default of the entry point itself),
streamable-http (http is a synonym) or sse. The HTTP transports bind to
HOST, which defaults to 127.0.0.1 (loopback); set HOST=0.0.0.0 to expose
the port on a PaaS (the container image already does both).
Connector URL: https://<host>/mcp
A Claude.ai custom connector speaks Streamable HTTP, and that transport serves
exactly one path: /mcp. sse is the older transport and serves /sse and
/messages instead — measured through the assembled app, POST /mcp answers
404 there and 200 under Streamable HTTP. The container image therefore
defaults to streamable-http; a connector pointed at an SSE deployment gets a
404 and never completes a handshake.
I14Y_MCP_ALLOWED_HOSTS — required for a public deployment
A comma-separated list of the hostnames the server is reached under — hostnames only, no scheme and no port:
I14Y_MCP_ALLOWED_HOSTS=i14y-mcp.up.railway.app,mcp.example.chThe value is compared literally against the incoming Host header, so
https://i14y-mcp.up.railway.app or a trailing :443 matches nothing and every
request fails with HTTP 421 Invalid Host header. Behind TLS the browser
sends the bare hostname; a non-standard port needs the SDK's only wildcard form,
host:*. Loopback stays reachable either way, so container health checks are
unaffected.
Leaving it unset on a non-loopback bind does not fall back to something safe. The server cannot guess the name it will be addressed by, and a guessed list would reject every real request, so it switches the Host check off entirely and says so in the log:
dns_rebinding_protection_offrailway.json
railway.json pins the one build setting the deployment cannot
get wrong on its own:
{ "build": { "builder": "DOCKERFILE", "dockerfilePath": "Dockerfile" } }With any other builder Railway never looks at the Dockerfile. It derives a start
command itself, I14Y_MCP_TRANSPORT is then set nowhere, and main() falls into
the stdio branch — the container runs, never opens a port, and the only trace is
a failing health check. tests/test_entrypoint.py fails the day that setting
changes.
Two things the file deliberately does not carry:
No environment variables. Railway's schema has no key for them at any level, so
I14Y_MCP_ALLOWED_HOSTSandI14Y_MCP_TRANSPORTbelong in the service variables. The trap is that the schema validates values but waves invented keys through: a"variables": { … }block passes validation, your editor stays quiet, and Railway ignores it. A test rejects such a key.No
healthcheckPath. Measured through the assembled app, no path answers a GET with 2xx:/and/healthare 404,/mcpis 400 without a session and 421 under a foreignHost. A health check pointed at any of them would mark the deployment unhealthy and roll it back. The Dockerfile's TCP check does the right thing instead. Should the server ever grow a real health route, the key may be set — a test then requires that the path actually answers.
CORS exposes the Mcp-Session-Id header so browser MCP clients keep their session.
Which browser origins may call the server comes from I14Y_MCP_CORS_ORIGINS, a
comma-separated list — unset means no browser client is permitted at all,
which is the default. * is still accepted and logs a warning. stdio and other
non-browser clients are unaffected either way.
Docker
docker compose up --build # Streamable HTTP on http://localhost:8000/mcpThe image is a hardened multi-stage build: it runs as a non-root user, ships no
build tools, and needs no secrets (the API is unauthenticated). See
Dockerfile and compose.yaml.
Join keys
I14Y is a connector layer. Two identifiers make it composable with the rest of the portfolio:
Key | Field | Joins to |
Swiss UID |
|
|
Endpoint URL |
| any portfolio server wrapping that API |
Known limitations
Verified live on 2026-07-21.
The search index covers roughly half the register.
search_catalogreturns at most 1013 records;list_datasetsreaches about 2003. Uselist_datasetswhen completeness matters.Search returns Datasets only. Filtering by
types=["Concept"]ortypes=["DataService"]yields zero results even though those entities exist. Uselist_conceptsandlist_data_servicesinstead.The upstream ignores paging on search. The full result set is always returned; this server caps it at 200 records and sets
truncated: true.Licences vary per distribution, not per dataset. Most carry «Opendata BY ASK», which requires attribution and restricts commercial use. Always read the
licencefield before reuse.Some metadata fields are simply empty. Frequency, temporal coverage and distribution format are optional and frequently unset by publishers. This is a data-quality property of the catalogue, not a bug in this server.
Not every entry with an endpoint has a URL. Entries labelled only «OpenAPI Spezifikation» without a URI are surfaced as
(no URI) <label>rather than dropped.
Testing
PYTHONPATH=src pytest tests/ -m "not live" # offline, used in CI
PYTHONPATH=src pytest tests/ -m "live" # hits the real API
PYTHONPATH=src pytest tests/ # everything
python -m ruff check src testsThe live tests are not decoration: fundstück 4 in the probe report — keywords
nesting their language object under label — was caught by a live test after
the unit tests were already green.
Contributing
See CONTRIBUTING.md for the ground rules (read-only, one
egress host, no secrets) and the local dev loop. Maintainers: PUBLISHING.md
covers the PyPI / MCP Registry release process.
Security
See SECURITY.md for the security posture and how to report a
vulnerability.
License
MIT License — see LICENSE. The catalogue data remains subject to the terms declared by each publisher.
Author
Hayal Oezkan · github.com/malkreide
Credits & related projects
Data: I14Y Interoperability Platform, Federal Statistical Office (BFS)
Standard: eCH-0200 / DCAT-AP-CH
Source discovery inspired by rnckp/awesome-ogd-switzerland
Portfolio: swiss-public-data-mcp
Protocol: Model Context Protocol
Licence: MIT. The catalogue data remains subject to the terms declared by each publisher.
MCP Registry
Ownership marker used by the MCP Registry to link this PyPI package to the GitHub namespace:
mcp-name: io.github.malkreide/i14y-mcpAvailable Tools
13 toolsapi_statusCheck the I14Y API statusARead-onlyIdempotent
Check whether the I14Y API is reachable and which endpoints respond.
Always returns an evaluable status rather than an empty result, so an agent can distinguish «no data matched» from «the source is down».
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | |
| source | No | Attribution string. |
| base_url | Yes | |
| reachable | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
| checked_endpoints | Yes | |
| last_successful_call | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, covering safety. The description adds a valuable behavioral guarantee beyond the annotations: it 'always returns an evaluable status rather than an empty result,' which shapes agent interpretation of results. 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 with no wasted words. The main purpose is front-loaded, and the second sentence adds a key behavioral distinction that helps the agent reason about results. 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 zero-parameter status tool with rich annotations and an output schema, the description is complete. It states what is checked, guarantees a non-empty evaluable result, and explains why that matters. Nothing necessary for correct invocation 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?
There are zero parameters, and schema coverage is 100%, so there is nothing missing. The baseline of 4 applies because no parameter semantics are needed; the description appropriately says nothing about parameters.
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 clear verb and resource: 'Check whether the I14Y API is reachable and which endpoints respond.' This distinguishes it as a status/health tool from the data-retrieval siblings, though it does not explicitly name a sibling or exclusion. It is clear but lacks explicit 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 provides clear use context: it is meant to check API reachability and to distinguish 'no data matched' from 'the source is down.' It implies when to use it (after empty results or when API health is in question), but it does not explicitly state when not to use it or name alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_conceptGet one conceptARead-onlyIdempotent
Retrieve one concept definition, including its value type and version.
Args:
concept_id: UUID from list_concepts.
language: Language for titles and descriptions.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | de | |
| concept_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | Attribution string. |
| concept | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
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 safety profile is covered. The description adds 'including its value type and version', giving some content context, but no additional behavioral details such as error conditions, localization defaults, or response structure beyond what the output schema would provide. This is acceptable but not rich.
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 with the core action, followed by concise parameter explanations. Every sentence contributes useful information, with no redundancy or filler. The Args block is clean 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 simple read-only lookup with two parametershol, strong annotations, and an output schema, the description is complete. It tells the agent what the tool returns, how to source concept_id, and what language affects. Nothing essential is missing for correct invocation.
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 carry the parameter meaning burden. It does this well: concept_id is described as a UUID from list_concepts, and language is described as affecting titles and descriptions. These add practical meaning beyond the bare schema names, though the description could have noted the default language.
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 opens with a specific verb and resource: 'Retrieve one concept definition', which clearly distinguishes it from sibling tools like list_concepts and get_dataset. The title 'Get one concept' reinforces the singular focus. An agent can immediately tell this tool fetches a single concept by ID rather than listing or searching.
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 clear context that concept_id is a 'UUID from list_concepts', which tells the agent where to obtain the ID before calling this tool. It also explains that language is used for titles and descriptions. It does not explicitly discuss when not to use this tool versus search_catalog or list_concepts, so it misses a full explicit exclusion statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_data_serviceGet one data serviceARead-onlyIdempotent
Retrieve the full record for one registered API, including endpoints.
Args:
data_service_id: UUID from list_data_services.
language: Language for titles and descriptions.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | de | |
| data_service_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | Attribution string. |
| provenance | No | Where this payload came from. |
| data_service | Yes | |
| retrieved_at | Yes | UTC timestamp of retrieval. |
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 safety profile is covered. The description adds useful behavioral context by stating that the returned record is 'full' and 'including endpoints,' plus the language-dependent behavior of titles and descriptions.
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 with the main purpose in the first sentence. The Args section is minimal and every line contributes either parameter meaning or workflow context. There is no filler or repetition.
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 single-record retrieval tool, the description provides the necessary workflow source for the ID, the language behavior, and the scope of the returned record. An output schema exists, so detailed return structure is not needed in the description. The annotations cover safety and idempotency.
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 carries the burden of explaining parameters. It does so well: data_service_id is identified as a UUID from `list_data_services`, and language is defined as affecting titles and descriptions. The schema only supplies types/enums, so this adds meaningful semantics.
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 ('Retrieve'), a resource ('the full record for one registered API'), and a distinctive detail ('including endpoints'). It clearly differentiates from list_data_services and other sibling get_* tools by targeting a single record rather than a collection.
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 explicitly tells the agent to source data_service_id from `list_data_services`, which establishes a clear workflow and prerequisite. It does not explicitly enumerate when not to use the tool, but the singular-record framing and sibling list make the selection context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_datasetGet one datasetARead-onlyIdempotent
Retrieve the full, aggregated metadata record for one dataset.
This is the aggregated detail tool: a single call returns the contact
point, temporal and spatial coverage, documentation links and every
distribution with its licence — so search_catalog → get_dataset
answers «who publishes it, through which interface, under which licence»
in two calls, without a separate distributions or contact lookup.
Args:
dataset_id: UUID from search_catalog or list_datasets.
language: Language for titles and descriptions.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | de | |
| dataset_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | Attribution string. |
| dataset | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is fully covered. The description adds value beyond annotations by disclosing the aggregation behavior — that one call returns contact point, coverage, documentation links, and every distribution with its licence — a trait an agent cannot infer from the schema or annotations alone.
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 first sentence front-loads the purpose, the second sentence earns its place by explaining why aggregation matters, and the Args block is cleanly formatted. The phrasing 'answers «who publishes it, through which interface, under which licence»' is slightly florid but not filler, so the size is justified.
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?
With an output schema documenting return structure, annotations covering safety and idempotency, and both parameters explained including value provenance, nothing an agent needs to call this tool correctly is missing. The workflow context (used after search_catalog or list_datasets) completes the picture.
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 carries the full burden for both parameters. It delivers: dataset_id gains provenance (a UUID from search_catalog or list_datasets) which the schema's pattern constraint lacks, and language gains a semantic effect (titles and descriptions). Both parameters are meaningfully enriched.
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?
Opens with a specific verb+resource ('Retrieve the full, aggregated metadata record for one dataset') and immediately positions itself as the aggregated detail tool. The distinction from sibling get_dataset_distributions is clear: this tool returns everything in one call, so an agent can tell them apart without opening either schema.
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?
Describes the intended workflow (search_catalog → get_dataset) and states where dataset_id comes from (search_catalog or list_datasets). It explicitly contrasts with 'a separate distributions or contact lookup,' steering agents away from redundant sibling calls. It never names get_dataset_distributions explicitly or states hard when-not-to-use conditions, so it stops just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dataset_distributionsGet a dataset's distributionsARead-onlyIdempotent
Get the downloadable files and access URLs for a dataset.
This is the «where do I actually get the data» tool. Each distribution
carries its own format, licence and download URL — licences differ between
distributions of the same dataset, so always read the licence field
before reusing the data. (get_dataset returns these same distributions
alongside the rest of the record.)
Args:
dataset_id: UUID from search_catalog or list_datasets.
language: Language for titles and descriptions.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | de | |
| dataset_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | Attribution string. |
| returned | Yes | |
| dataset_id | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
| dataset_title | No | |
| distributions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive behavior. The description adds useful extras beyond those: distributions each have their own format, licence, and download URL, licences can differ within a dataset, and the agent should read the licence field before reuse. It also reveals consistency with get_dataset. It does not go further into rate limits or error behavior, but the annotations lower that burden.
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 front-loaded with the main action, then uses a short positioning sentence, a licence caveat, a sibling note, and a compact Args list. Every sentence contributes either selection guidance, parameter semantics, or a behavioral warning; there is no low-value 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?
For a two-parameter read-only retrieval tool with an output schema, the description supplies the missing context: what a distribution contains, the licence warning, the source of dataset_id, the meaning of language, and the relationship to get_dataset. An agent has enough to decide when to call it and how to invoke it correctly.
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?
With 0% schema description coverage, the Args section carries the semantic load and succeeds: dataset_id is explained as coming from search_catalog or list_datasets, and language is defined as controlling titles and descriptions. This meaningfully compensates for the schema's absent descriptions and complements the enum/pattern constraints already present.
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 opens with a specific verb and resource: 'Get the downloadable files and access URLs for a dataset.' It also differentiates itself from the close sibling get_dataset by noting that get_dataset returns the same distributions 'alongside the rest of the record,' so an agent can distinguish the two without inspecting schemas.
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 frames the tool as 'the «where do I actually get the data» tool' and names get_dataset as the alternative that returns these distributions with the full record, giving clear selection context. It does not, however, state an explicit when-to-use/when-not-to-use rule such as 'use this when you only need distributions; use get_dataset when you need the full record.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_catalogsList cataloguesARead-onlyIdempotent
List the catalogues that feed into I14Y.
Each catalogue represents one contributing organisation's data collection.
Args: language: Language for titles. page: 1-based page number. page_size: Records per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| language | No | de | |
| page_size | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| catalogs | Yes | |
| returned | Yes | |
| page_size | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description doesn't need to restate those. It adds some domain context about catalogues, but no additional behavioral details such as pagination behavior, sorting, or open-world caveats beyond the annotation.
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 short, front-loaded with the main action, and clearly separates purpose, context, and arguments. Every sentence earns its place and there is no redundant 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 presence of an output schema and strong annotations, the description covers the essential domain concept and all optional parameters. It is slightly incomplete because it offers no guidance on choosing among sibling list/search tools, but it is otherwise sufficient for a simple read-only listing endpoint.
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?
With 0% schema description coverage, the description compensates by documenting all three parameters: language controls titles, page is 1-based, and page_size is records per page. This adds meaning beyond the bare schema titles and constraints, though the explanations are minimal.
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 names a specific verb ('List') and resource ('catalogues that feed into I14Y'), then adds a defining sentence about what a catalogue represents. This makes it clearly distinguishable from siblings like list_datasets and search_catalog.
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 no guidance about when to use this tool versus alternatives such as search_catalog or list_datasets. It states what the tool does, but an agent is left to infer the appropriate selection context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_conceptsList harmonised conceptsARead-onlyIdempotent
List harmonised concepts and code lists of the Swiss administration.
Concepts are the semantic backbone of interoperability: shared definitions
and code lists that different bodies agree to use. Note that these are not
reachable through search_catalog.
Args:
publisher_identifier: Publisher identifier from list_publishers.
language: Language for titles and descriptions.
page: 1-based page number.
page_size: Records per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| language | No | de | |
| page_size | No | ||
| publisher_identifier | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| concepts | Yes | |
| returned | Yes | |
| page_size | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld, and non-destructive behavior, so the bar is lower. The description adds useful behavioral context: the resources are harmonised concepts and code lists with a specific semantic role, and they are not reachable via search_catalog. This goes beyond the annotations and schema without contradicting them.
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 well-structured: purpose first, then domain context, then a key caveat, then compact parameter documentation. Every sentence adds value, and the Args section is scannable without redundant 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?
With an output schema presentcherta, no required parameters, comprehensive annotations, and all parameters described, nothing essential is missing. The domain context and search_catalog exclusion complete the picture for an agent deciding whether to invoke this 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?
Schema description coverage is 0%, so the description must compensate, and it does: every parameter is described. publisher_identifier is enriched with its source (list_publishers), language is clarified as affecting titles and descriptions, and page/page_size semantics are stated. This is sufficient, though terse.
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 opens with a specific verb and resource: 'List harmonised concepts and code lists of the Swiss administration.' It clearly distinguishes this tool from siblings by naming search_catalog as not the way to reach these resources, and the plural 'list' contrasts with singular get_concept.
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 explicitly says these concepts are not reachable through search_catalog, giving a when-not to use an alternative. It also instructs that publisher_identifier comes from list_publishers, chaining to the prerequisite tool. It does not explicitly contrast with get_concept or search_codelist_entries, but enough context is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_data_servicesList data services (APIs)ARead-onlyIdempotent
List machine interfaces (APIs) registered by Swiss public bodies.
The strategic payload of this server: the national register of official APIs, with endpoint URLs and OpenAPI specification links where the publisher supplied them. Use this to discover whether an interface already exists before building a scraper.
Args:
publisher_identifier: Publisher identifier from list_publishers.
language: Language for titles and descriptions.
page: 1-based page number.
page_size: Records per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| language | No | de | |
| page_size | No | ||
| publisher_identifier | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| returned | Yes | |
| page_size | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
| data_services | Yes |
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 only needs to add context beyond that. It does: results include OpenAPI links only where the publisher supplied them, the data is the national official register, and language affects titles and descriptions. 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 front-loaded with the core definition, followed by the strategic value and a concrete usage sentence. The Args block is terse, parallel, and informative. Every sentence earns its place 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 the output schema, annotations, and sibling context, the description is nearly complete: it explains the purpose, the data caveat, the parameter source, and the intended use. The only small gap is not explicitly describing pagination behavior, but the schema already defines page and page_size bounds clearly.
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 Args block carries the burden. It meaningfully covers all four parameters: publisher_identifier is tied to list_publishers, language is for titles/descriptions, page is 1-based, and page_size is records per page. This compensates for the empty schema descriptions, though it does not deeply explain filtering behavior.
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?
States a specific verb ('List') and resource ('machine interfaces (APIs) registered by Swiss public bodies'), then adds what the tool returns: endpoint URLs and OpenAPI specification links. The 'discover whether an interface already exists' use case further clarifies its role and distinguishes it from sibling list/get tools at a glance.
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?
Gives an explicit use case ('Use this to discover whether an interface already exists before building a scraper') and useful context such as listing official Swiss APIs. It also cross-references list_publishers for the publisher_identifier. However, it does not explicitly contrast with get_data_service or other sibling tools, so there is minor room for ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_datasetsList datasetsARead-onlyIdempotent
List registered datasets, optionally filtered by publisher.
Unlike search_catalog, this endpoint paginates correctly and covers the
complete register (roughly 2000 datasets as of July 2026), including
records the search index misses.
Args:
publisher_identifier: Publisher identifier from list_publishers.
access_rights: e.g. "PUBLIC", "NON_PUBLIC", "RESTRICTED".
language: Language for titles and descriptions.
page: 1-based page number.
page_size: Records per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| language | No | de | |
| page_size | No | ||
| access_rights | No | ||
| publisher_identifier | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| datasets | Yes | |
| returned | Yes | |
| page_size | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the `readOnlyHint`/`idempotentHint` annotations, it discloses pagination behavior, dataset volume, and completeness relative to the search index. These are meaningful runtime traits not visible in structured metadata and add real value for an agent.
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?
Front-loaded purpose, a single targeted comparison sentence, then a terse, complete Args list. No filler or redundant restatement of the title.
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?
With an output schema present and annotations covering safety/idempotency, the description covers purpose, alternative routing, filter semantics, and pagination. Nothing needed to invoke it correctly 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 input schema has no property descriptions (0% coverage), and the description compensates with an Args block for all five parameters, including the source of `publisher_identifier` (`list_publishers`), examples for `access_rights`, and semantics for `page`/`page_size`. This is exactly what an agent needs to construct valid input.
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?
States a specific action ('List registered datasets') plus an optional filter, and explicitly contrasts itself with `search_catalog`, so an agent can distinguish it from its siblings without opening schemas. The scope is clear and the comparison reinforces what this endpoint is for.
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 explicitly names the alternative (`search_catalog`) and gives the deciding factors: correct pagination, complete ~2000-dataset register, and coverage of records the search index misses. This tells an agent when to choose this endpoint over the search-based sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_public_servicesList public servicesARead-onlyIdempotent
List registered public services (administrative offerings for citizens).
Args:
publisher_identifier: Publisher identifier from list_publishers.
language: Language for titles and descriptions.
page: 1-based page number.
page_size: Records per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| language | No | de | |
| page_size | No | ||
| publisher_identifier | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| returned | Yes | |
| page_size | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
| public_services | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, openWorldHint, and non-destructiveness, so safety is covered. The description contributes no behavioral detail beyond that—nothing about pagination iteration, ordering, response shape, or side effects—so it adds little transparency beyond the 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 short, front-loads the purpose in one sentence, and then presents a compact args list where each line earns its place. No redundant prose or repetition of schema defaults.
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 paginated list with a full output schema and strong annotations, the description covers the essential context: what the tool returns at a conceptual level and what each argument controls. An agent has enough to invoke it correctly without needing extra return-value or safety detail.
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?
With 0% schema description coverage, the description compensates by explaining every parameter: publisher_identifier's source from list_publishers, language's effect on titles and descriptions, page as 1-based, and page_size's range. This is meaningfully more than the bare schema types and defaults, though the definitions are terse.
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 a clear resource ('registered public services'), with a helpful parenthetical explaining what public services are. It does not explicitly contrast itself with sibling tools like list_data_services, 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 phrase 'registered public services (administrative offerings for citizens)' implies this is the tool for administrative offerings, and the mention of list_publishers suggests a workflow, but there is no explicit when-to-use, when-not-to-use, or alternative tool guidance. Usage is inferred from the name and description rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_publishersList publishersARead-onlyIdempotent
List the public bodies that publish into I14Y.
Returns publisher identifiers needed by the other tools, plus the Swiss UID
where available — the UID is the join key to register-mcp (Zefix).
Args: identifier: Filter by exact publisher identifier. uid: Filter by Swiss UID, e.g. "CHE-123.456.789". language: Language for names. page: 1-based page number. page_size: Records per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| uid | No | ||
| page | No | ||
| language | No | de | |
| page_size | No | ||
| identifier | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| returned | Yes | |
| page_size | Yes | |
| provenance | No | Where this payload came from. |
| publishers | Yes | |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered by structured data. The description adds useful context beyond this by disclosing the return payload (publisher identifiers plus Swiss UID) and the UID's role as the join key to register-mcp (Zefix). No contradiction exists.
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 purpose is front-loaded in the first sentence, followed by a brief return-value note and a clean Args block. Every line adds information with no padding, repetition, or vague 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?
With an output schema present and all five optional parameters documented in both schema (defaults, enums, bounds) and description, an agent has what it needs to call the tool correctly. Defaults like language 'de' and page_size 50 are already encoded in the schema, and the description covers the rest — the tool is simple enough that nothing critical 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?
Schema description coverage is 0%, so the description carries the full burden for parameter meaning — and it delivers. All five parameters are explained in an Args block, with concrete format guidance: the 'CHE-123.456.789' UID example, 1-based pagination, the 1-100 page_size bound, and language applicability. This completely compensates for the empty schema descriptions.
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 first sentence names a specific verb (List), a resource (public bodies/publishers), and scope (publishing into I14Y), which inherently distinguishes it from sibling tools like list_datasets and list_public_services. However, it doesn't explicitly differentiate itself from siblings, so it falls short of a 5.
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 statement 'Returns publisher identifiers needed by the other tools' gives clear context for when to use it — when a downstream tool requires a publisher identifier. It stops short of naming alternatives or exclusions, such as when to prefer search_catalog over this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_catalogSearch the I14Y catalogueARead-onlyIdempotent
Search Switzerland's national metadata catalogue for data resources.
The primary entry point: use this to find out who publishes data on a topic before looking for a specific dataset. Returns titles, publishers, themes and portal permalinks.
Known limitation (verified live 2026-07-21): the upstream search index
covers Datasets only. Filtering by types=["Concept"] or
types=["DataService"] returns zero results even though those entities
exist — use list_concepts and list_data_services for those.
Args: query: Free-text search term, e.g. "Sonderpaedagogik" or "Bildung". An empty string returns the full index (over 1000 records) and is not recommended. language: Language for titles and descriptions. types: Restrict to resource types. Effectively only "Dataset" works. themes: Filter by theme identifiers. publishers: Filter by publisher identifiers. limit: Maximum records to return (1-200). Upstream ignores paging, so capping happens in this server.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| types | No | ||
| themes | No | ||
| language | No | de | |
| publishers | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Actionable next step when match_type is 'none' (e.g. which tool to try). |
| hits | Yes | |
| query | No | |
| source | No | Attribution string. |
| language | Yes | |
| returned | Yes | Records in this payload after capping. |
| truncated | Yes | True when the upstream result set exceeded the cap. |
| match_type | No | 'none' when nothing matched, so the agent never sees a bare empty result. |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
| total_matched | Yes | Matches reported by the upstream index. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool readOnly/idempotent; the description goes beyond them by disclosing that the upstream index only covers Datasets, that Concept/DataService filters return zero results, and that the server caps the limit because upstream ignores paging. This is exactly the context annotations cannot express.
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?
Although relatively long, each sentence adds operational value: purpose, return fields, limitation, and parameter caveats. It is organized with a clear intro, limitation callout, and compact Args list. No filler or duplication of the schema.
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?
With six parameters, an output schema, and sibling discovery tools, the description covers selection, invocation, parameter semantics, and expected returns (titles, publishers, themes, permalinks). The only aspects left implicit, such as sorting/pagination, are either addressed via the limitation or likely covered by the output schema.
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 0%, but the Args block describes every parameter with practical detail: query includes examples and an empty-string warning, types carries the 'only Dataset works' caveat, and limit explains the 1-200 cap and server-side capping. This fully compensates for the schema's lack of descriptions.
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 opens with a specific verb and object: 'Search Switzerland's national metadata catalogue for data resources,' and narrows the tool's role as 'the primary entry point' for discovery. It explicitly distinguishes itself from dataset-specific lookups ('before looking for a specific dataset') and from type-specific siblings by stating which entity types are unsupported. This leaves no ambiguity about what the tool is for.
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 states when to use ('find out who publishes data on a topic before looking for a specific dataset') and what NOT to use it for via the known limitation. It explicitly routes Concept and DataService searches to list_concepts and list_data_services. The empty-query warning also sets expectations around acceptable use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_codelist_entriesSearch a concept's code listARead-onlyIdempotent
List the individual codes of a code-list concept.
Use this to resolve official code values — for example the canonical list
of a classification used across several federal datasets. Only concepts
with concept_type == "CodeList" return entries.
Args:
concept_id: UUID of a code-list concept from list_concepts.
language: Language for entry names. Required by the upstream API.
page: 1-based page number.
page_size: Records per page (1-200).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| language | No | de | |
| page_size | No | ||
| concept_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| source | No | Attribution string. |
| entries | Yes | |
| language | Yes | |
| returned | Yes | |
| page_size | Yes | |
| concept_id | Yes | |
| provenance | No | Where this payload came from. |
| retrieved_at | Yes | UTC timestamp of retrieval. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only, idempotent, and non-destructive. The description adds non-redundant behavioral context: only CodeList concepts return entries and `language` is required by the upstream API, which helps an agent anticipate failures. 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 two short paragraphs plus a compact Args list. The core purpose and key constraint are front-loaded, and each sentence adds information without repetition or 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?
For a paged read-only listing tool with an output schema available, the description covers purpose, applicable concept type, pagination parameters, and the upstream language requirement. It doesn't fully specify behavior for invalid or non-codelist concept IDs (empty vs error), but the CodeList-only statement largely covers the main edge case.
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?
With 0% schema-level parameter descriptions, the Args section carries the full burden and succeeds: each parameter gets a purpose, and `concept_id` is tied back to `list_concepts`, `language` noted as required upstream, and paging semantics are stated. This is complete and meaningful compensation for the schema gap.
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 opens with 'List the individual codes of a code-list concept,' a specific verb-plus-resource statement that clearly distinguishes this from sibling tools like list_concepts and get_concept. The title reinforces the scope without ambiguity.
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 says 'Use this to resolve official code values' and adds the precondition that only concepts with `concept_type == "CodeList"` return entries, giving clear when-to-use context. It does not explicitly name sibling alternatives or state 'do not use for X,' so it earns a 4 rather than 5.
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.
3 tool updates
v0.3.2- Added
api_status - Added
get_data_service - Added
get_dataset
10 tool updates
v0.2.1- First observed
get_concept - First observed
get_dataset_distributions - First observed
list_catalogs - First observed
list_concepts - First observed
list_data_services - First observed
list_datasets - First observed
list_public_services - First observed
list_publishers - First observed
search_catalog - First observed
search_codelist_entries
TDQS
Scored across 13 tools
Each tool targets a distinct resource or action: listing vs. fetching individual entities, plus search, status, and code-list lookup. Even the overlapping get_dataset and get_dataset_distributions are clearly differentiated by the description noting get_dataset returns distributions alongside the full record, making get_dataset_distributions a focused convenience tool. No two tools appear to do the same thing.
Tool names follow a consistent verb_noun pattern: list_* for collections, get_* for single entities, search_* for search operations, and api_status for health. The pattern is uniform across all 13 tools with no mixed conventions or vague verbs.
13 tools is well within the ideal 3-15 range for a domain-specific server. Each tool covers a distinct aspect of the I14Y metadata catalog (datasets, data services, public services, concepts, publishers, catalogs, status), and none feel redundant or superfluous.
The tool surface covers the core read-only workflows for a catalog: listing and retrieving datasets, data services, concepts, and code-list entries, plus search, publishers, catalogs, and status. Minor gaps exist—there is no get_public_service or get_catalog, so those entities can only be listed, not fetched individually. This is a minor gap that agents can work around, but it does not break the primary use cases.
Maintenance
Related MCP Connectors
opendata.swiss MCP — Switzerland's federal open-data portal (CKAN catalogue).
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Hosted MCP server for finding authoritative primary data sources and official portals.
This MCP server provides seamless access to Malaysia's government open data, including datasets, w…
Related MCP Servers
- AlicenseAqualityDmaintenanceSwiss open data MCP server — transport, weather, geodata, companies, etc,. Zero API keys.76179 npm22MIT
- AlicenseAqualityAmaintenanceMCP server connecting AI models to Swiss Federal Food Safety and Veterinary Office open data, enabling queries about food recalls, animal disease surveillance, food control results, and more.1126 PyPIMIT
- AlicenseBqualityAmaintenanceAn MCP server providing AI-powered access to Open Data from the City of Zurich, enabling queries to 900+ datasets, real-time environmental and mobility data, geodata, parliamentary proceedings, and more.26166 PyPI8MIT
- AlicenseAqualityAmaintenanceMCP server for TERMDAT, the terminology database of the Swiss Federal Administration, giving AI agents officially validated designations of Swiss authorities, departments, and legal acts across DE/FR/IT/EN with source references and validation status.7125 PyPI1MIT