sdmx-data-mcp
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., "@sdmx-data-mcphow much do Swiss banks have in foreign claims since 2020?"
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.
sdmx-data-mcp
An MCP server that lets an AI assistant discover and retrieve official statistics from SDMX services.
Built on the BIS's own pysdmx library.
Why this exists
Other SDMX MCP servers navigate metadata well and then hand back a query URL. The assistant ends up with a link, not numbers — and cannot answer the question it was asked.
sdmx-data-mcp finishes the job. get_data returns the observations.
Related MCP server: Countries MCP Server
Quick start
pip install sdmx-data-mcpThen register it with your client:
claude mcp add sdmx -- sdmx-data-mcpThat is the whole setup. Ask your assistant something like "what is the Swiss policy rate since 2020?" and it will find the dataflow, check what it can filter on, and come back with the actual series.
Claude Desktop — in claude_desktop_config.json:
{
"mcpServers": {
"sdmx": {
"command": "sdmx-data-mcp"
}
}
}Cursor — in .cursor/mcp.json:
{
"mcpServers": {
"sdmx": {
"command": "sdmx-data-mcp"
}
}
}If sdmx-data-mcp is not on your PATH, use the absolute path to the
executable, or "command": "python", "args": ["-m", "sdmx_data_mcp"].
Over HTTP, to share one instance:
sdmx-data-mcp --transport http --host 127.0.0.1 --port 8000The four tools
Meant to be called in order. Only the last one moves data.
Tool | Purpose |
| Known endpoints, plus any SDMX-REST v2 base URL you supply |
| One |
| Components, available codes, size signals |
| Retrieves the observations |
A real session
Transcripts below are actual tool output, not illustrations. More in docs/EXAMPLES.md.
1. Find the dataflow
search_dataflows(query="policy rate central bank")
{
"search_terms": ["policy", "rate", "central", "bank"],
"total_dataflows_on_service": 32,
"match_count": 12,
"dataflows": [
{ "ref": "BIS:WS_CBPOL(1.0)", "name": "Central bank policy rates",
"matched_on": "name" },
{ "ref": "BIS:WS_CBS_PUB(1.0)", "name": "Consolidated banking",
"matched_on": "name" }
// ...
]
}One request to the service; the terms are matched locally. Searching for synonyms costs nothing extra, so put them all in one query.
2. See what you can filter on
inspect_dataflow(ref="BIS:WS_CBPOL(1.0)", find_code="CH")
{
"series_count": 98,
"obs_count": null, // BIS does not report this
"size_warning": null, // small enough to retrieve
"dimensions": [
{ "id": "FREQ", "name": "Frequency", "code_count": 2,
"codes": [{"id": "D", "name": "Daily"}, {"id": "M", "name": "Monthly"}] },
{ "id": "REF_AREA", "name": "Reference area", "code_count": 49,
"codes": [ /* ... */ {"id": "CH", "name": "Switzerland"} /* ... */ ] }
]
}3. Get the numbers
get_data(
ref="BIS:WS_CBPOL(1.0)",
filters="FREQ = 'M' AND REF_AREA = 'CH' AND TIME_PERIOD >= '2020-01'",
columns=["OBS_VALUE"],
)
{
"filter_applied": "FREQ = 'M' AND REF_AREA = 'CH' AND TIME_PERIOD >= '2020-01'",
"filter_fallback": null,
"row_count": 79,
"total_rows_available": 79,
"truncated": false,
"records": [
{"SERIES_KEY": "M.CH", "OBS_VALUE": "-0.75", "TIME_PERIOD": "2020-01"},
{"SERIES_KEY": "M.CH", "OBS_VALUE": "-0.75", "TIME_PERIOD": "2020-02"}
// ...
],
"next_step": "Complete: all 79 matching rows were returned. Safe to aggregate."
}truncated: false and row_count == total_rows_available, so this really is
the whole series and it is safe to average or chart.
Several values of one component
The query parser accepts AND but not OR. Use IN (...):
get_data(
ref="BIS:WS_XRU(1.0)",
filters="FREQ = 'M' AND CURRENCY IN ('CHF', 'KES') AND TIME_PERIOD >= '2026-01'",
columns=["OBS_VALUE"],
)
{ "row_count": 14, "truncated": false, "records": [
{"SERIES_KEY": "M.CH.CHF.E", "OBS_VALUE": "0.768269", "TIME_PERIOD": "2026-01"},
{"SERIES_KEY": "M.KE.KES.A", "OBS_VALUE": "129.126615", "TIME_PERIOD": "2025-12"}
// ...
] }With both legs retrieved, an assistant can compute what neither service publishes — a CHF/KES cross rate — and correctly note that the newest period the two currencies share is December 2025, because KES lags CHF.
What the server enforces
These rules are handled by the server rather than left for the assistant to remember. Each one prevents a specific class of confidently wrong answer.
Conjunctions only. AND between clauses, never OR. Several values of one
component use IN ('A', 'B').
Availability is not validity. inspect_dataflow reports codes for which
data currently exist. A code missing from that list may still be valid in the
full codelist, so its absence is never reported as proof that something does
not exist.
Ambiguous codes are surfaced, not guessed. On BIS consolidated banking,
CH is available in three components at once — reporting country, counterparty
country, and a bank type that happens to share the country codelist:
inspect_dataflow(ref="BIS:WS_CBS_PUB(1.0)", find_code="CH")
{ "code_locations": [
{"component_id": "L_REP_CTY", "role_hint": "reporting country"},
{"component_id": "CBS_BANK_TYPE", "role_hint": "bank type (shares a country codelist)"},
{"component_id": "L_CP_COUNTRY", "role_hint": "counterparty country"}
],
"next_step": "That code is ambiguous - it appears in 3 components ..." }Claims by Swiss banks and claims on Switzerland are different questions. The server makes the assistant choose rather than silently pick one.
Size before retrieval. obs_count is frequently unreported — the BIS
returns null for it on both full and filtered scopes — so series_count is
the signal relied on. A size_warning appears when retrieval would truncate.
Truncation is not sampling. When truncated is true, the rows are the
first N in service order, and next_step says so explicitly:
Truncated: 112,648 rows matched but only 500 were returned. These are the first rows in service order, not a sample — do not compute totals or averages from them.
Time filters degrade gracefully. TIME_PERIOD is pushed down to the
service first. On a client-side rejection the clause is stripped, the narrower
query is retried, and the cutoff is applied with pandas — reported in
filter_fallback. It deliberately does not fall back on NotFound,
Unavailable or InternalError, where dropping a clause cannot help and would
only obscure the real error.
Errors keep their meaning. The pysdmx error hierarchy is preserved rather than flattened, so an assistant can tell a transient outage from a bad reference instead of retrying blindly or giving up too early:
[internal_error] Unexpected message format - The payload could not be
deserialized. | retriable=false | next_step: The service failed, or returned a
response that could not be parsed. Do not repeat the identical call - narrow
the filter or try a different dataflow, since the fault is server-side.Kind | Retriable | Means |
| yes | Service unreachable; retry after a delay |
| yes | Transient failure |
| no | Resource does not exist; do not repeat |
| no | Malformed filter; check syntax and code IDs |
| no | Credentials rejected |
| no | Service lacks the required API |
| no | Server-side fault; narrow or change the query |
| no | Bug in this server; please report it |
Services
pysdmx.api.dc.Endpoints currently ships exactly one endpoint, the BIS. Every
tool therefore takes a service argument accepting any SDMX-REST v2 base
URL as a first-class input, not a fallback:
search_dataflows(query="prices", service="https://your-service.org/api/v2")The service must return structural metadata as SDMX-JSON 2.0.0 and data as SDMX-CSV. Other providers (ECB, OECD, IMF, Eurostat, ILO) are deliberately not hardcoded: each needs verifying against those requirements first, and listing them unverified would invite confident failures.
Development
pip install -e ".[dev]"
ruff format && ruff check && mypy
pytest --cov=sdmx_data_mcp --cov-branch --cov-report=term-missing162 tests at 100% statement and branch coverage, mypy in strict mode, CI across Linux, Windows and macOS on Python 3.10–3.13.
Most server tests inject a fake connector so every branch is reachable
deterministically. A separate end-to-end module drives the real
PandasConnector against respx-mocked responses, so drift in URL
construction or SDMX-CSV parsing surfaces there.
Relationship to pysdmx
This package depends on pysdmx[data] from PyPI. It does not fork or vendor
it, and uses only the public API — PandasConnector, Endpoints and the
errors hierarchy.
The same server has also been proposed upstream as bis-med-it/pysdmx#669. This package exists so it is installable today regardless of what happens there.
Licence
Apache-2.0. See LICENSE.
Available Tools
4 toolsget_dataA
Retrieve observations as records. This returns the actual numbers.
Call inspect_dataflow first to confirm component and code IDs and to check the size of what you are about to pull.
If a TIME_PERIOD clause is rejected by the service, it is retried without that clause and the cutoff is applied locally; the response says so in filter_fallback.
Returns: The observations, the filter actually sent, and a truncated flag. When truncated, the rows are the first N in service order and are NOT a representative sample.
Raises: ToolError: If retrieval fails. The message carries a [kind] discriminator and a retry hint.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | Dataflow reference in agency:id(version) form, such as 'BIS:WS_CBS_PUB(1.0)'. | |
| limit | No | Maximum rows to return. Defaults to 1000, hard ceiling 10000. | |
| labels | No | 'id' returns code IDs (default, and far more compact). 'name' substitutes human-readable names. 'both' gives 'ID: Name'. Leave as 'id' unless names were requested. | id |
| columns | No | Components to return, such as ['OBS_VALUE']. Omit for all. TIME_PERIOD and SERIES_KEY are added automatically by pysdmx. | |
| filters | No | Filter selecting the data, such as "L_MEASURE = 'S' AND L_REP_CTY = 'CH' AND TIME_PERIOD >= '2020-Q1'". AND only, never OR; use IN ('A', 'B') for several values of one component. Omitting this pulls the whole dataflow and will almost certainly truncate. | |
| service | No | Service name or SDMX-REST v2 base URL. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ref | Yes | The resolved dataflow reference. |
| columns | Yes | |
| records | Yes | |
| service | Yes | |
| next_step | Yes | |
| row_count | Yes | Rows actually returned. |
| truncated | Yes | True when total_rows_available exceeded the cap. The returned rows are the first row_count in service order and are NOT a representative sample - narrow the filter for a complete answer. |
| filter_applied | Yes | The filter actually sent to the service, echoed so the caller can verify what was queried. |
| filter_fallback | No | Set when server-side time pushdown failed and the time constraint was applied locally instead. Names the filter that was sent and the cutoff applied with pandas. |
| total_rows_available | Yes | Rows matching the filter before the cap was applied. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the fallback behavior for rejected TIME_PERIOD clauses, the truncated flag and that rows are 'NOT a representative sample' when truncated, and the ToolError format with a [kind] discriminator and retry hint. It also notes that TIME_PERIOD and SERIES_KEY are added automatically. This is thorough behavioral disclosure.
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 moderately long but every sentence earns its place. It is front-loaded with the purpose, then proceeds logically to prerequisites, fallback behavior, return info, and error handling. It is structured and does not ramble, though it could be slightly trimmed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 params, output schema exists, no annotations), the description covers the critical gotchas: prerequisite inspection, fallback behavior, truncation semantics, and error format. It does not need to explain return values because an output schema is present. Nothing essential 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?
Schema coverage is 100%, so the baseline is 3. The description adds value by contextualizing the ref and filters parameters—telling the agent to obtain component/code IDs from inspect_dataflow and explaining the consequence of omitting filters. This goes beyond the schema's per-parameter descriptions, hence a 4.
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 'Retrieve observations as records. This returns the actual numbers.' which is a specific verb+resource that clearly distinguishes this from the sibling tools (list_services, search_dataflows, inspect_dataflow). It leaves no ambiguity about what the tool does and its output nature.
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 explicitly instructs the agent to 'Call inspect_dataflow first to confirm component and code IDs and to check the size of what you are about to pull.' This is a clear prerequisite and directly routes the agent to the right sibling. It also warns that omitting the filters 'pulls the whole dataflow and will almost certainly truncate,' giving concrete guidance on when to use filters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_dataflowA
Inspect a dataflow's components, available codes and size.
Call this before get_data. It answers three questions: what can I filter on, which codes actually have data, and is this small enough to retrieve?
If you only need to know whether data exist for some subset, pass filters and stop here rather than going on to get_data.
Returns: Components grouped by role, availability-backed codes, and size signals with a warning when retrieval would truncate.
Raises: ToolError: If the dataflow is not found or the request fails.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | Dataflow reference in agency:id(version) form, such as 'BIS:WS_CBS_PUB(1.0)'. Take this from the ref field of search_dataflows. A full SDMX URN also works. | |
| filters | No | Optional filter scoping availability to a subset, such as "L_REP_CTY = 'CH' AND FREQ = 'Q'". AND only, never OR; use IN ('A', 'B') for several values of one component. Supplying this narrows the reported codes and counts to what remains available. | |
| service | No | Service name or SDMX-REST v2 base URL. | |
| find_code | No | Optional code value such as 'CH'. Reports every component whose available codes contain it, and the role each plays. Use this before filtering on a country: the same code often appears in several dimensions with different meanings. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ref | Yes | The resolved dataflow reference. |
| name | No | |
| service | Yes | |
| measures | Yes | |
| next_step | Yes | |
| obs_count | No | Observation count. Frequently null - BIS does not report it. Use series_count as the size signal when null. |
| attributes | Yes | |
| dimensions | Yes | |
| description | No | |
| series_count | No | |
| size_warning | No | Present when the scope is large enough that get_data would truncate. Narrow the filter first. |
| code_locations | No | Populated when find_code was supplied: every component whose available codes contain that value, with the role each plays. More than one entry means the value is ambiguous - on BIS consolidated banking 'CH' appears as reporting country, counterparty country and bank type - so choose the intended role before filtering. |
| filter_applied | No | The filter used to scope availability, echoed verbatim. Null means availability covers the whole dataflow. |
| availability_note | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does a solid job: it discloses the return content, warns about truncation signals, and lists the ToolError condition. It could more explicitly state that the operation is read-only and has no side effects, but 'Inspect' plus the returns/raises structure conveys the essential behavioral profile.
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, front-loaded with the core purpose, and uses a clear structure with Returns and Raises sections. Each sentence earns its place; the 'three questions' framing is especially efficient because it instantly communicates the tool's decision-making value.
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 4-parameter inspection tool with an output schema and a richly documented input schema, the description is complete: it states what the tool does, when to call it relative to get_data, what it returns, and when it errors. The sibling relationships are sufficiently covered by the explicit get_data comparison.
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 the baseline is 3. The tool description does not add parameter-level meaning beyond the schema, but the schema itself already explains ref format, filter syntax, the IN() alternative, and find_code semantics. The description's reference to 'filters' aligns with the schema but adds no new parameter information.
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: 'Inspect a dataflow's components, available codes and size.' It further clarifies the tool's role by naming the three questions it answers, distinguishing it from get_data by positioning itself as the pre-retrieval inspection step.
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 'Call this before get_data' and gives a concrete stopping condition: 'If you only need to know whether data exist for some subset, pass filters and stop here rather than going on to get_data.' This gives clear when-to-use guidance and differentiates it from the main sibling alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_servicesA
List the SDMX services this server can query.
Any SDMX-REST v2 base URL also works: pass it as the service argument to any other tool. The service must return structural metadata as SDMX-JSON 2.0.0 and data as SDMX-CSV.
Returns: The known services, with capability notes for each.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| services | Yes | |
| next_step | Yes | |
| custom_endpoints_supported | No | Every tool accepts a 'service' argument holding either a known name or an arbitrary SDMX-REST v2 base URL. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the tool's behavior (lists services) and explicitly describes the return format ('known services, with capability notes'). It does not mention side effects or permissions, but listing is inherently non-destructive and the return description adds meaningful context, warranting a 4.
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 extremely concise—two sentences plus a 'Returns:' line—with the core purpose front-loaded. Every sentence adds value: it explains the tool's purpose, notes the service URL flexibility for other tools, and outlines the return. No waste or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (0 params, list operation) and the presence of an output schema, the description covers the essentials: what the tool does and what it returns. It could be more explicit about the possible content of 'capability notes' or how services are discovered, but it is adequate for the agent to use 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?
The tool has zero parameters and schema coverage is 100% (empty schema). The baseline for 0 params is 4. The description adds context about passing service arguments to other tools, which is helpful for the broader workflow even though it does not directly describe this tool's parameters (none exist).
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 SDMX services this server can query', clearly stating the verb, resource, and scope. It distinguishes itself from siblings like search_dataflows, inspect_dataflow, and get_data, which all focus on data retrieval rather than service enumeration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by noting that any SDMX-REST v2 base URL can be passed as a service argument to other tools, which directs the user to this listing tool to discover available services before querying data. However, it does not explicitly state 'use this when you need to see available services' or provide a when-not-to-use rule, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_dataflowsA
Find dataflows (datasets) matching a topic.
Issues exactly one request to the service and matches the terms locally, so searching for synonyms costs nothing extra: put them all in one query rather than calling this repeatedly.
Returns: Matching dataflows, each with a ref to pass to the next tool.
Raises: ToolError: If the service is unknown or the request fails. The message carries a [kind] discriminator and a retry hint.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum dataflows to return. | |
| query | No | Topic to search for, such as 'banking' or 'policy rates'. Space-separated words are treated as alternatives and matched case-insensitively against each dataflow's id, name and description. Pass an empty string to list every dataflow. | |
| service | No | Service name from list_services, or an SDMX-REST v2 base URL. Defaults to the pysdmx endpoint. |
Output Schema
| Name | Required | Description |
|---|---|---|
| service | Yes | |
| dataflows | Yes | |
| next_step | Yes | |
| match_count | Yes | |
| search_terms | Yes | |
| total_dataflows_on_service | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that exactly one request is issued, terms are matched locally, and errors raise ToolError with a [kind] discriminator and retry hint. This goes beyond typical descriptions, though it stops short of covering side effects or permissions—less critical for a read-only search.
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 well-structured, front-loading the purpose, then behavioral notes, then Returns and Raises sections. Every sentence adds value: the request-count note, the synonym advice, the ref routing hint, and the error format are all useful and not redundant with 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?
Given the tool's relative simplicity, full schema coverage, and the existence of an output schema, the description covers purpose, usage, behavior, return value routing, and error handling. No critical information an agent needs to call 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?
Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description adds no additional parameter-level detail, but the baseline of 3 applies since the schema does the heavy lifting.
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 'Find dataflows (datasets) matching a topic', which names a specific verb and resource. It is clearly distinct from siblings: search_dataflows searches for dataflows, list_services lists services, inspect_dataflow inspects a single dataflow, and get_data fetches data.
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 explains when to use the tool (topic search) and gives efficiency guidance: put synonyms in one query because matching is local. It does not explicitly name alternatives or say when not to use it, but the purpose is clear and the returned refs point to the next tool, providing contextual routing.
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.
4 tool updates
v0.1.0- First observed
get_data - First observed
inspect_dataflow - First observed
list_services - First observed
search_dataflows
TDQS
Scored across 4 tools
Each tool maps to a distinct stage of an SDMX query workflow: discovering services, finding dataflows, inspecting a dataflow, and fetching data. There is no overlap in purpose, and the descriptions explicitly position each tool relative to the next.
All tool names follow a consistent verb_noun snake_case pattern: list_services, search_dataflows, inspect_dataflow, get_data. The minor singular/plural variation between dataflows and dataflow is natural and does not create confusion.
Four tools is a well-scoped size for a focused SDMX data retrieval server. Each tool is necessary and corresponds to a meaningful step in the pipeline without redundancy or bloat.
The tool surface covers the full read-only workflow: discovering available services, locating relevant dataflows, understanding their structure and constraints, and retrieving actual observations. No critical operations are missing for the stated purpose.
Maintenance
Related MCP Connectors
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
MCP server connecting AI agents to non-custodial staking data across 130+ networks.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Related MCP Servers
- AlicenseBqualityDmaintenanceA model Context Protocol (MCP) server that provides comprehensive OECD statistics through the SDMX API, supporting AI assistants and chatbots to query OECD datasets in areas such as economy, health, education, and environment.92Apache 2.0
- AlicenseNot gradedqualityDmaintenanceMCP Server that gives AI assistants access to comprehensive country data from 250+ countries.1MIT
- AlicenseBqualityDmaintenanceMCP server for accessing Japanese government statistics portal 'e-Stat' API, enabling language models to search and retrieve statistical data.520MIT
- FlicenseNot gradedqualityDmaintenanceMCP server that lets AI agents discover and call R and Python statistical functions without writing code.-