mcp-i14y
Connects AI assistants to the Swiss I14Y Interoperability Platform, enabling natural language exploration of government datasets, APIs, codelists, and public services.
README
mcp-i14y
An MCP server that connects AI assistants to the Swiss I14Y Interoperability Platform.
Ask Claude, Gemini, or GitHub Copilot to explore Swiss government datasets, APIs, codelists, and public services in natural language — powered by the Model Context Protocol.
Inspired by the French datagouv-mcp project, adapted for the Swiss I14Y platform.
What is I14Y?
The I14Y Interoperability Platform (operated by the Swiss Federal Statistical Office) is Switzerland's national catalog for government data. It standardises and publishes metadata for:
- Datasets — data published by federal and cantonal bodies
- Data Services — APIs exposing government data
- Concepts — reusable data definitions, codelists, and data dictionaries
- Public Services — administrative services offered to citizens and businesses
Features
| Tool | Description |
|---|---|
list_datasets |
List datasets with filters (publisher, status, level) |
get_dataset |
Get full metadata for a dataset |
get_dataset_structure |
Export dataset schema (JSON-LD, Turtle, RDF) |
list_dataservices |
List data services (APIs) with filters |
get_dataservice |
Get full metadata for a data service |
list_concepts |
List concepts (codelists, dictionaries) with filters |
get_concept |
Get concept details, optionally with codelist entries |
get_concept_codelist |
Export all codelist entries (JSON or CSV) |
list_publicservices |
List public services with filters |
get_publicservice |
Get full metadata for a public service |
get_catalog |
Export a catalog in DCAT-AP format (Turtle or RDF/XML) |
list_mappingtables |
List mapping tables (source → target codelist correspondences) |
get_mappingtable |
Get full metadata for a mapping table |
get_mappingtable_relations |
Export all mapping relations (value correspondences) as JSON or CSV |
catalog_search |
Full-text search across all resource types (server-side, via CORE API) |
get_dataset_by_identifier |
Get a dataset by its short identifier (not UUID) |
check_dataset_has_structure |
Check whether a dataset has a structural model defined |
get_dataset_model_graph |
Get the dataset schema as a schema graph (nodes/edges) |
get_dataservice_by_identifier |
Get a data service by its short identifier |
get_publicservice_by_identifier |
Get a public service by its short identifier |
get_publicservice_relations |
Get related public services |
get_concept_by_identifier |
Get concept(s) by short identifier (e.g. "HGDE_KT") |
get_codelist_entries |
Paginated codelist entries with full annotations |
get_codelist_entry_by_code |
Look up a single codelist entry by code value |
get_codelist_entries_children |
Navigate hierarchical codelists (children of a code) |
search_codelist_entries |
Search entries within a specific codelist |
list_catalogs |
List all DCAT catalogs |
get_catalog_records |
Get records (resources) from a catalog |
get_catalog_themes |
Get themes used in a catalog (DCAT-AP alignment) |
list_agents |
List all publishing organisations (with identifiers for filtering) |
get_agent |
Get full metadata for a publishing organisation |
list_vocabularies |
List all controlled vocabularies (themes, licenses, formats…) |
get_vocabulary |
Get all entries of a controlled vocabulary for RDF/DCAT-AP use |
get_distribution_content |
Fetch the actual content of a distribution file (CSV, JSON, XML…) |
Quick Start
Option 1: Docker Compose (recommended)
git clone https://github.com/fgouzi/mcp-i14y.git
cd mcp-i14y
cp .env.example .env
docker compose up -d
The server will be available at http://localhost:8400/mcp.
Option 2: Local setup with uv
git clone https://github.com/fgouzi/mcp-i14y.git
cd mcp-i14y
uv sync
uv run python main.py
Verify
curl http://localhost:8400/health
# → {"status":"ok","platform":"i14y","version":"0.1.0"}
Connect to your AI assistant
The MCP endpoint is http://localhost:8400/mcp (Streamable HTTP / JSON-RPC).
Claude Desktop
Add to claude_desktop_config.json:
macOS/Linux:
~/.claude/claude_desktop_config.json· Windows:%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"i14y": {
"type": "http",
"url": "http://localhost:8400/mcp"
}
}
}
Claude Code (CLI)
/mcp add i14y http://localhost:8400/mcp
GitHub Copilot (VS Code)
Requires VS Code 1.112+ with the GitHub Copilot Chat extension.
A .vscode/mcp.json file is already included in this repository. After starting the server:
- Open the repo in VS Code — a "Start" button appears at the top of
.vscode/mcp.json - Click Start (or run
MCP: List Serversfrom the Command Palette) - Open Copilot Chat (
Ctrl+Shift+I/Cmd+Shift+I) and switch to Agent mode - Click the Tools icon to confirm the i14y tools are available
To configure manually in another project, create .vscode/mcp.json:
{
"servers": {
"i14y": {
"type": "http",
"url": "http://localhost:8400/mcp"
}
}
}
Mistral Le Chat
- Open Le Chat → side panel → Intelligence → Connectors
- Click + Add Connector → Custom MCP Connector
- Fill in:
- Connector name:
i14y - Connection server URL:
http://localhost:8400/mcp - Authentication: None
- Connector name:
- Click Connect
- Enable it in any conversation via the Tools icon (four squares) below the chat input
Mistral Vibe (CLI agent)
Add to your config.toml:
[[mcp_servers]]
name = "i14y"
transport = "streamable-http"
url = "http://localhost:8400/mcp"
Tools are then available as i14y_list_datasets, i14y_get_concept, etc.
MCP Inspector (testing)
npx @modelcontextprotocol/inspector http://localhost:8400/mcp
Available Tools
Datasets
list_datasets
List datasets from the I14Y platform with optional filters.
| Parameter | Type | Default | Description |
|---|---|---|---|
publisher_identifier |
string | — | Filter by publisher organisation ID |
registration_status |
string | — | Initial, Candidate, Recorded, Qualified, Standard, PreferredStandard, Superseded, Retired |
publication_level |
string | — | Internal or Public |
access_rights |
string | — | Access restriction code |
dataset_identifier |
string | — | Filter by dataset identifier |
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
get_dataset
| Parameter | Type | Description |
|---|---|---|
dataset_id |
string | Dataset unique identifier |
get_dataset_structure
| Parameter | Type | Default | Description |
|---|---|---|---|
dataset_id |
string | — | Dataset unique identifier |
format |
string | JsonLd |
JsonLd, Ttl, or Rdf |
Data Services
list_dataservices
Same filter parameters as list_datasets (with dataservice_identifier instead of dataset_identifier).
get_dataservice
| Parameter | Type | Description |
|---|---|---|
dataservice_id |
string | Data service unique identifier |
Concepts
list_concepts
| Parameter | Type | Default | Description |
|---|---|---|---|
publisher_identifier |
string | — | Filter by publisher |
concept_identifier |
string | — | Filter by concept identifier |
version |
string | — | Filter by version |
registration_status |
string | — | Registration status filter |
publication_level |
string | — | Internal or Public |
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
get_concept
| Parameter | Type | Default | Description |
|---|---|---|---|
concept_id |
string | — | Concept unique identifier |
include_codelist_entries |
boolean | false |
Embed codelist entries in response |
get_concept_codelist
| Parameter | Type | Default | Description |
|---|---|---|---|
concept_id |
string | — | Concept unique identifier |
format |
string | json |
json or csv |
Public Services
list_publicservices
Same filter parameters as list_datasets (with publicservice_identifier).
get_publicservice
| Parameter | Type | Description |
|---|---|---|
publicservice_id |
string | Public service unique identifier |
Catalogs
get_catalog
| Parameter | Type | Default | Description |
|---|---|---|---|
catalog_id |
string | — | Catalog unique identifier |
format |
string | ttl |
ttl (Turtle) or rdf (RDF/XML) |
Mapping Tables
A mapping table defines a correspondence between two codelists (source → target), enabling semantic alignment across classification systems (e.g. old canton codes → new codes, Swiss codes → European standards).
list_mappingtables
| Parameter | Type | Default | Description |
|---|---|---|---|
publisher_identifier |
string | — | Filter by publisher organisation ID |
mappingtable_identifier |
string | — | Filter by mapping table identifier |
version |
string | — | Filter by version string |
registration_status |
string | — | Initial, Candidate, Recorded, Qualified, Standard, PreferredStandard, Superseded, Retired |
publication_level |
string | — | Internal or Public |
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
get_mappingtable
| Parameter | Type | Description |
|---|---|---|
mappingtable_id |
string | Mapping table unique identifier (UUID) |
get_mappingtable_relations
| Parameter | Type | Default | Description |
|---|---|---|---|
mappingtable_id |
string | — | Mapping table unique identifier (UUID) |
format |
string | Json |
Json or Csv |
Search
Since the I14Y API has no full-text search endpoint, these tools fetch pages progressively and rank results client-side.
catalog_search
Full-text search across all I14Y resource types (server-side, via CORE API).
| Parameter | Type | Default | Description |
|---|---|---|---|
query |
string | — | Free-text search query (any language) |
types |
list | — | Filter by type(s): Dataset, DataService, PublicService, Concept, MappingTable |
publishers |
list | — | Filter by publisher identifier(s), e.g. ["CH1"] |
statuses |
list | — | Filter by registration status(es) |
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
Concepts (CORE)
get_concept_by_identifier
| Parameter | Type | Description |
|---|---|---|
identifier |
string | Short identifier string (e.g. "HGDE_KT", "CL_NOGA") |
get_codelist_entries
| Parameter | Type | Default | Description |
|---|---|---|---|
concept_id |
string | — | Concept UUID |
page |
integer | 1 |
Page number |
page_size |
integer | 100 |
Results per page |
get_codelist_entry_by_code
| Parameter | Type | Description |
|---|---|---|
concept_id |
string | Concept UUID |
code |
string | Code value to look up (e.g. "1", "CH") |
get_codelist_entries_children
| Parameter | Type | Default | Description |
|---|---|---|---|
concept_id |
string | — | Concept UUID |
parent_code |
string | — | Parent code whose children to retrieve |
page |
integer | 1 |
Page number |
page_size |
integer | 100 |
Results per page |
search_codelist_entries
| Parameter | Type | Default | Description |
|---|---|---|---|
concept_id |
string | — | Concept UUID |
query |
string | — | Search term |
language |
string | fr |
Language for label matching: fr, de, it, en |
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
Datasets (CORE)
get_dataset_by_identifier
| Parameter | Type | Description |
|---|---|---|
identifier |
string | Dataset short identifier (e.g. "px-x-0602010000_109") |
check_dataset_has_structure
| Parameter | Type | Description |
|---|---|---|
dataset_id |
string | Dataset UUID |
Returns true if a structural model exists, false otherwise. Use this before calling get_dataset_structure() to filter datasets that have a documented schema.
get_dataset_model_graph
| Parameter | Type | Description |
|---|---|---|
dataset_id |
string | Dataset UUID |
Returns the dataset schema as a graph (nodes/edges) — suited for programmatic processing. Complements get_dataset_structure() which returns RDF/JSON-LD.
Data Services (CORE)
get_dataservice_by_identifier
| Parameter | Type | Description |
|---|---|---|
identifier |
string | Data service short identifier |
Public Services (CORE)
get_publicservice_by_identifier
| Parameter | Type | Description |
|---|---|---|
identifier |
string | Public service short identifier |
get_publicservice_relations
| Parameter | Type | Description |
|---|---|---|
publicservice_id |
string | Public service UUID |
Catalogs (CORE)
list_catalogs
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
get_catalog_records
| Parameter | Type | Default | Description |
|---|---|---|---|
catalog_id |
string | — | Catalog UUID |
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
get_catalog_themes
| Parameter | Type | Default | Description |
|---|---|---|---|
catalog_id |
string | — | Catalog UUID |
page |
integer | 1 |
Page number |
page_size |
integer | 100 |
Results per page |
Agents
list_agents
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number |
page_size |
integer | 25 |
Results per page |
get_agent
| Parameter | Type | Description |
|---|---|---|
agent_id |
string | Agent UUID |
Vocabularies
Controlled vocabularies define valid values for DCAT-AP metadata fields (themes, access rights, licenses, media types, etc.).
list_vocabularies
No parameters. Returns all available vocabulary configurations with their identifiers.
get_vocabulary
| Parameter | Type | Description |
|---|---|---|
identifier |
string | Vocabulary identifier (e.g. "Concept_DATASET_THEME", "VOCAB_EU_FREQUENCY") |
Distributions
get_distribution_content
Fetch the actual data content of a DCAT distribution file.
Typical workflow:
- Call
get_dataset(dataset_id)→ finddistributions[n].downloadUrl.uri - Call
get_distribution_content(url)→ returns the file content
Supported formats: JSON, CSV, XML, RDF/Turtle, GeoJSON, plain text. Binary formats (PDF, ZIP, Excel, images) are rejected with an error message.
| Parameter | Type | Default | Description |
|---|---|---|---|
download_url |
string | — | The downloadUrl.uri value from a distribution object |
max_kb |
integer | 200 |
Maximum content size in KB — larger files are truncated with a warning |
Example Prompts
Once connected, try asking your LLM assistant:
- "List all public datasets published by the Federal Statistical Office."
- "What data services are available with status Standard?"
- "Show me the codelist for Swiss canton codes."
- "Get the full details for dataset with ID
abc-123." - "Export the catalog of the OFS in Turtle format."
- "What public administrative services are registered on I14Y?"
- "Search for datasets about employment by canton."
- "Find the concept codelist for 'Secteur économique'."
- "List all mapping tables that link old canton codes to new ones."
- "Export the mapping relations for mapping table
xyz-456as CSV." - "Find the dataset with identifier
px-x-0602010000_109." - "Get the valid values for DCAT themes (data subjects)."
- "Which organisations publish data on I14Y?"
- "Get all child codes of canton 1 in the commune hierarchy."
Development
Setup
git clone https://github.com/fgouzi/mcp-i14y.git
cd mcp-i14y
uv sync
cp .env.example .env
Run tests
# Unit tests only (no network required)
uv run pytest
# Including integration tests (hits live I14Y test API)
uv run pytest -m integration
Lint & format
uv run ruff check --fix .
uv run ruff format .
Install pre-commit hooks
uv run pre-commit install
Configuration
Copy .env.example to .env and adjust:
| Variable | Default | Description |
|---|---|---|
MCP_HOST |
0.0.0.0 |
Bind address (127.0.0.1 for local-only) |
MCP_PORT |
8400 |
Server port |
I14Y_API_ENV |
prod |
prod or test |
LOG_LEVEL |
INFO |
Logging level |
SENTRY_DSN |
(empty) | Optional Sentry DSN |
License
MIT — see LICENSE.
Credits
- Inspired by datagouv-mcp by the data.gouv.fr team
- Built on FastMCP and the MCP Python SDK
- Data provided by the Swiss Federal Statistical Office (OFS/BFS) via I14Y
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.