OpenDataMCP
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., "@OpenDataMCPcheck for train disruptions on SBB network today"
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.
Open Data Model Context Protocol
See it in action
https://github.com/user-attachments/assets/760e1a16-add6-49a1-bf71-dfbb335e893e
We enable 2 things:
Open Data Access: Access to many public datasets right from your LLM application (starting with Claude, more to come).
Publishing: Get community help and a distribution network to distribute your Open Data. Get everyone to use it!
How do we do that?
Access: Setup our MCP servers in your LLM application in 2 clicks via our CLI tool (starting with Claude, see Roadmap for next steps).
Publish: Use provided templates and guidelines to quickly contribute and publish on Open Data MCP. Make your data easily discoverable!
Related MCP server: MobusMCP
Usage
Access: Access Open Data using Open Data MCP CLI Tool
Prerequisites
If you want to use Open Data MCP with Claude Desktop app client you need to install the Claude Desktop app.
You will also need uv to easily run our CLI and MCP servers.
macOS
# you need to install uv through homebrew as using the install shell script
# will install it locally to your user which make it unavailable in the Claude Desktop app context.
brew install uvWindows
# (UNTESTED)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Open Data MCP - CLI Tool
Overview
# show available commands
uvx odmcp
# show available providers
uvx odmcp list
# show info about a provider
uvx odmcp info $PROVIDER_NAME
# setup a provider's MCP server on your Claude Desktop app
uvx odmcp setup $PROVIDER_NAME
# remove a provider's MCP server from your Claude Desktop app
uvx odmcp remove $PROVIDER_NAMEExample
Quickstart for the Switzerland SBB (train company) provider:
# make sure claude is installed
uvx odmcp setup ch_sbbRestart Claude and you should see a new hammer icon at the bottom right of the chat.
You can now ask questions to Claude about SBB train network disruption and it will answer based on data collected on data.sbb.ch.
Publish: Contribute by building and publishing public datasets
Prerequisites
Install UV Package Manager
# macOS brew install uv # Windows (PowerShell) powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" # Linux/WSL curl -LsSf https://astral.sh/uv/install.sh | shClone & Setup Repository
# Clone the repository git clone https://github.com/OpenDataMCP/OpenDataMCP.git cd OpenDataMCP # Create and activate virtual environment uv venv source .venv/bin/activate # Unix/macOS # or .venv\Scripts\activate # Windows # Install dependencies uv syncInstall Pre-commit Hooks
# Install pre-commit hooks for code quality pre-commit install
Publishing Instructions
Create a New Provider Module
Each data source needs its own python module.
Create a new Python module in
src/odmcp/providers/.Use a descriptive name following the pattern:
{country_code}_{organization}.py(e.g.,ch_sbb.py).Start with our template file as your base.
Implement Required Components
Define your Tools & Resources following the template structure
Each Tool or Resource should have:
Clear description of its purpose
Well-defined input/output schemas using Pydantic models
Proper error handling
Documentation strings
Tool vs Resource
Choose Tool implementation if your data needs:
Active querying or computation
Parameter-based filtering
Complex transformations
Choose Resource implementation if your data is:
Static or rarely changing
Small enough to be loaded into memory
Simple file-based content
Reference documentation or lookup tables
Reference the MCP documentation for guidance
Testing
Add tests in the
tests/directoryFollow existing test patterns (see other provider tests)
Required test coverage:
Basic functionality
Edge cases
Error handling
Validation
Test your MCP server using our experimental client:
uv run src/odmcp/providers/client.pyVerify all endpoints respond correctly
Ensure error messages are helpful
Check performance with typical query loads
For other examples, check our existing providers in the src/odmcp/providers/ directory.
Contributing
We have an ambitious roadmap and we want this project to scale with the community. The ultimate goal is to make the millions of datasets publicly available to all LLM applications.
For that we need your help!
Discord
We want to build a helping community around the challenge of bringing open data to LLM's. Join us on discord to start chatting: https://discord.gg/QPFFZWKW
Our Core Guidelines
Because of our target scale we want to keep things simple and pragmatic at first. Tackle issues with the community as they come along.
Simplicity and Maintainability
Minimize abstractions to keep codebase simple and scalable
Focus on clear, straightforward implementations
Avoid unnecessary complexity
Standardization / Templates
Follow provided templates and guidelines consistently
Maintain uniform structure across providers
Use common patterns for similar functionality
Dependencies
Keep external dependencies to a minimum
Prioritize single repository/package setup
Carefully evaluate necessity of new dependencies
Code Quality
Format code using ruff
Maintain comprehensive test coverage with pytest
Follow consistent code style
Type Safety
Use Python type hints throughout
Leverage Pydantic models for API request/response validation
Ensure type safety in data handling
Tactical Topics (our current priorities)
Initialize repository with guidelines, testing framework, and contribution workflow
Implement CI/CD pipeline with automated PyPI releases
Develop provider template and first reference implementation
Integrate additional open datasets (actively seeking contributors)
Establish clear guidelines for choosing between Resources and Tools
Develop scalable repository architecture for long-term growth
Expand MCP SDK parameter support (authentication, rate limiting, etc.)
Implement additional MCP protocol features (prompts, resource templates)
Add support for alternative transport protocols beyond stdio (SSE)
Deploy hosted MCP servers for improved accessibility
Roadmap
Let’s build the open source infrastructure that will allow all LLMs to access all Open Data together!
Access:
Make Open Data available to all LLM applications (beyond Claude)
Make Open Data data sources searchable in a scalable way
Make Open Data available through MCP remotely (SSE) with publicly sponsored infrastructure
Publish:
Build the many Open Data MCP servers to make all the Open Data truly accessible (we need you!).
On our side we are starting to build MCP servers for Switzerland ~12k open dataset!
Make it even easier to build Open Data MCP servers
We are very early, and lack of dataset available is currently the bottleneck. Help yourself! Create your Open Data MCP server and get users to use it as well from their LLMs applications. Let’s connect LLMs to the millions of open datasets from governments, public entities, companies and NGOs!
As Anthropic's MCP evolves we will adapt and upgrade Open Data MCP.
Limitations
All data served by Open Data MCP servers should be Open.
Please oblige to the data licenses of the data providers.
Our License must be quoted in commercial applications.
References
Kudos to Anthropic's open source MCP release enabling initiative like this one.
License
This project is licensed under the MIT License - see the LICENSE file for details
Available Tools
3 toolsrail-traffic-infoC
Fetch rail traffic information
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Language code for responses (de, fr, it, en). Affects message content language | |
| limit | No | Maximum number of traffic info entries to return (1-100) | |
| where | No | Filter conditions for traffic info. Examples: 'validitybegin >= NOW()', 'description LIKE "*Zürich*"' | |
| offset | No | Number of traffic info entries to skip for pagination | |
| refine | No | Refine by specific facets. Example: 'author:SBB' to show only SBB notifications | |
| select | No | Fields to select in the response. Examples: 'title,description' for basic info, 'title,validitybegin,validityend' for timing info | |
| exclude | No | Exclude specific fields from response. Example: 'description_html' to exclude HTML formatting | |
| group_by | No | Group traffic info by specific fields. Example: 'author' to group by the author of the traffic info | |
| order_by | No | Sort traffic info. Example: 'validitybegin ASC' for chronological order, 'published DESC' for newest first | |
| timezone | No | Timezone for validity and publication times. Example: 'Europe/Zurich' for local Swiss time | UTC |
| include_links | No | Include related links in response | |
| include_app_metas | No | Include application metadata |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It only says 'fetch', implying a read operation, but does not describe response format, pagination behavior, or potential side effects. This is insufficient for a tool with 12 parameters.
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 with no waste, but it is under-specified for a tool of this complexity. It does not provide an overview of capabilities or structure the information in a way that helps an agent quickly understand the tool's scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is completely inadequate for a tool with 12 optional parameters and no output schema or annotations. It does not synthesize the parameter capabilities (filtering, pagination, language, timezone) or provide any contextual hints, leaving the agent to rely entirely on the 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 100%, meaning each of the 12 parameters has a description in the schema. The tool description adds no additional parameter information, so the baseline of 3 is appropriate because the schema already documents all parameters clearly.
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 'Fetch rail traffic information' provides a clear verb and resource, distinguishing the tool from siblings like railway-lines and rolling-stock. However, it does not specify what constitutes 'traffic information' (e.g., delays, disruptions), leaving some 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?
No guidance is given on when to use this tool versus alternatives. The description does not mention any context or conditions that would lead an agent to select this over railway-lines or rolling-stock, nor does it provide exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
railway-linesC
Fetch railway line information
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of railway line entries to return (1-100) | |
| where | No | Filter conditions. Examples: 'linie = 100', 'bpk_anfang LIKE "*Zürich*"' | |
| offset | No | Number of railway line entries to skip for pagination | |
| select | No | Fields to select in the response. Examples: 'linie,linienname' for basic info, 'bpk_anfang,bpk_ende' for station info | |
| group_by | No | Group railway lines by specific fields. Example: 'bpk_anfang' to group by starting station | |
| order_by | No | Sort railway lines. Example: 'linie ASC' for line number order, 'km_ende DESC' for longest routes first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden, but it only restates the fetch purpose. It does not mention response format, pagination behavior, filtering semantics, rate limits, or what data is actually returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is free of filler and front-loaded with the core action. However, it is under-specified rather than efficiently informative, leaving the agent with only a minimal statement of 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?
For a six-parameter query tool with no output schema and no annotations, this is not a complete definition. It omits default return fields, how filtering and pagination behave, and how this tool fits with the sibling rail-related tools.
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 100%, so all six parameters (limit, where, offset, select, group_by, order_by) are already documented in the input schema. The description adds no parameter-level meaning, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
'Fetch railway line information' names a clear verb and resource, so an agent knows this is a read operation on railway line data. It does not go beyond that to distinguish itself from siblings like rail-traffic-info or rolling-stock, 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 description gives no guidance about when to use this tool instead of rail-traffic-info or rolling-stock, and it states no exclusions or alternative conditions. An agent must infer usage entirely from the schema and tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rolling-stockC
Fetch rolling stock (vehicle) information
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of rolling stock entries to return (1-100) | |
| where | No | Filter conditions. Examples: 'fahrzeug_typ = "X"', 'vmax_betrieblich_zugelassen > 100' | |
| offset | No | Number of rolling stock entries to skip for pagination | |
| select | No | Fields to select in the response. Examples: 'fahrzeug_typ,objekt' for basic info, 'vmax_betrieblich_zugelassen,lange_uber_puffer_lup' for technical details | |
| group_by | No | Group rolling stock by specific fields. Example: 'fahrzeug_typ' to group by vehicle type | |
| order_by | No | Sort rolling stock. Example: 'baudatum_fahrzeug ASC' for oldest first, 'vmax_betrieblich_zugelassen DESC' for fastest first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only says 'Fetch rolling stock information' without revealing that it supports pagination, filtering, grouping, or ordering, nor whether it is a read-only operation. The description adds no behavioral context beyond what the name implies.
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, concise sentence that is front-loaded with the core action. It avoids unnecessary verbosity, though it sacrifices informativeness for brevity. It is not bloated, but could be more helpful with additional context.
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 tool with 6 optional parameters covering filtering, sorting, grouping, and pagination, the description is extremely minimal. It does not explain what kind of data is returned, the meaning of 'rolling stock', or the query syntax beyond what the schema provides. With no output schema, the agent has limited understanding of the response format.
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 provides 100% coverage with descriptive examples for each parameter (limit, where, select, group_by, order_by, offset). The description itself adds no parameter-specific meaning, but since the schema fully documents the parameters, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch') and resource ('rolling stock (vehicle) information'), which is clear and distinct from the sibling tools (rail-traffic-info, railway-lines). However, it does not elaborate on what 'information' encompasses, so it is clear but not fully differentiated beyond the name.
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 guidance is provided on when to use this tool versus the sibling tools. There is no mention of scenarios, exclusions, or alternative selection criteria. An agent would have to infer from the name alone when to choose rolling-stock over rail-traffic-info or railway-lines.
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.1.0- First observed
rail-traffic-info - First observed
railway-lines - First observed
rolling-stock
TDQS
Scored across 3 tools
Each tool targets a reasonably distinct resource: traffic information, railway lines, and rolling stock. However, rail-traffic-info and railway-lines could be confused in situations involving line status or operations, since both could plausibly return similar operational information.
All tool names use lowercase hyphenated noun phrases, which gives the set a consistent overall style. The minor inconsistency between 'rail', 'railway', and 'rolling-stock' is noticeable but does not cause significant confusion.
Three tools is on the lean side, but each one covers a meaningful area of rail open data: traffic, infrastructure, and vehicles. The count is reasonable for a specialized read-only data server, though it could be expanded.
The set covers several core rail datasets, but there are obvious gaps such as stations, schedules, departures, and disruptions unless they are implicitly included in traffic info. Agents working with broader rail queries would likely need additional tools.
Maintenance
Related MCP Connectors
Connect LLMs to business data. Serve data from CRMs, databases, ERPs or SaaS apps via Dataddo MCP.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Connect your ads, shop, analytics, social, CRM and finance platforms once, then let Claude, ChatGPT, Cursor or any MCP client read, join and explain your numbers. Public statistics from the World Bank, IMF, Eurostat, OECD, WHO and SEC filings come as context, searchable and chartable from the same tools. Read-only by design, every number carries its source.
Hosted MCP server for AI-driven data ops. Create apps, manage schemas, and CRUD structured data.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAccess to many public datasets right from your LLM application.155MIT
- AlicenseNot gradedqualityBmaintenanceSearch, preview, and analyze datasets from 20+ platforms and millions of datasets via a single MCP connector. Works with Claude instantly7 npm29MIT
- AlicenseNot gradedqualityDmaintenanceUnified MCP server for discovering open datasets across Hugging Face, Zenodo, and Kaggle, with ranked search results and one-click Colab starter code generation.1MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that connects to open data portals like CKAN and Socrata, enabling natural language querying of datasets via Claude.MIT