Query IMF SDMX 3.0 macroeconomic dataflows — WEO, BOP, CPI, exchange rates, 190 countries.
One address for any MCP client. No sign-in needed on this server.
5 read
Grouped by tool name. At most: creates or changes data: records, files, settings.
Odel charges nothing per call. The publisher may charge for its own service.
Query IMF SDMX 3.0 macroeconomic data — hundreds of dataflows across 190 countries, WEO projections, BOP, CPI, exchange rates, and national accounts via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://imf.caseyjhand.com/mcp
IMF macroeconomic data across 190 countries: World Economic Outlook projections, balance of payments, CPI, exchange rates, national accounts, and hundreds more datasets. Browse the catalog, resolve dimension codes, query time series, and run SQL over large multi-country results. No API key required.
| Tool | Description |
|---|---|
imf_list_databases | List IMF SDMX dataflows, with an optional word filter |
imf_get_database | Fetch a dataflow's dimensions and codelists to resolve terms to SDMX codes |
imf_query_dataset | Query a dataflow by dimension key over a time range |
imf_dataframe_describe | List DataCanvas tables and columns staged by imf_query_dataset |
imf_dataframe_query | Run a read-only SQL SELECT across staged DataCanvas tables |
imf_dataframe_drop | Remove one staged table or view; disabled by default |
| Resource | Description |
|---|---|
imf://database/{dataflow_id} | Discovery metadata for one dataflow: dimensions, codelist previews, and key_format |
imf_list_databases toolfilter keeps dataflows whose ID, name, or description contains every word (split on spaces and commas, case-insensitive); vintage snapshots such as WEO_2025_OCT_VINTAGE are excluded unless include_vintages=truelimit (default 50) and offset; a page holds at most 200, and a larger limit (up to 1,000) echoes requested_limit/applied_limit. total_count and returned_count report the match and page sizesimf_get_database returns the full textimf_get_database toolUSA, not US) and returns key_format, the dot-separated dimension order imf_query_dataset requiresdimension_id to page one dimension with limit/offset (at most 200 per page, next_offset names the rest), and codelist_filter to keep codes whose ID or name contains every wordavailable_only=true pages only the codes the dataflow publishes, with series count and time coverage; agency_id/version are auto-detected when omittedimf_query_dataset tool+ combines codes at a position and * matches all of them; codes and dataflow_id are case-insensitive. start_period/end_period accept YYYY, YYYY-SN, YYYY-QN, YYYY-MM, or YYYY-MM-DD, and last_n_observations (1–1,000,000) keeps each series' last N observationstime_period, value, status, and series attributes (unit, scale, decimals, reference_period where published), with one series_metadata entry per series. Responses are held to 100,000 characters: with DataCanvas, larger results spill to it (output_mode: "canvas" forces staging, and staged reports storage); without it, the earliest observations return with truncated: true and retrieval_guidanceinvalid_key_code (with the nearest valid codes), wildcard_in_code_list, key_too_long, response_too_large, no_data, and no_data_in_range; a + key that partly returns lists the rest in missing_series. Upstream failures are data_unavailable and rate_limited, both retryable within a 45-second call budgetimf_dataframe_describe toolcanvas_id from an imf_query_dataset call that returned staged: true; call it before imf_dataframe_queryCANVAS_PROVIDER_TYPE=duckdb, like the other dataframe toolsimf_dataframe_query toolSELECT per call; a leading WITH … SELECT is accepted, DML and DDL are rejectedtruncated: true means either cap trimmed the result. Page with a stable ORDER BY plus LIMIT/OFFSETstructuredContent keeps every value; response_too_large means a single row exceeds the budget even soCANVAS_PROVIDER_TYPE=duckdbimf_dataframe_drop toolimf_dataframe_describedropped: false rather than an errorIMF_ENABLE_DATAFRAME_DROP=true alongside CANVAS_PROVIDER_TYPE=duckdb to register itimf://database/{dataflow_id} resourcekey_format, name, and descriptiondataflow_id comes from imf_list_databases; continuation metadata points to imf_get_database for codelists beyond the previewBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
IMF-specific:
Agent-friendly output:
key_format in every dataflow response states the dimension orderstatus flags (e.g. T, C, NA) for data-quality caveatsstaged and truncated are reported separately, and staged results carry canvas_id, table_name, and retrieval guidanceA public instance is available at https://imf.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"imf-mcp-server": {
"type": "streamable-http",
"url": "https://imf.caseyjhand.com/mcp"
}
}
}
No API key required. Add the following to your MCP client configuration file.
{
"mcpServers": {
"imf-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/imf-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"imf-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/imf-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"imf-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/imf-mcp-server:latest"
]
}
}
}
To enable SQL analytics over large result sets, add CANVAS_PROVIDER_TYPE=duckdb to the env block. Add IMF_ENABLE_DATAFRAME_DROP=true only when agents should be able to remove staged tables.
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/imf-mcp-server.git
cd imf-mcp-server
bun install
cp .env.example .env
# edit .env as needed — no required vars for basic use
| Variable | Description | Default |
|---|---|---|
CANVAS_PROVIDER_TYPE | Set to duckdb to enable DataCanvas spill and the dataframe tools. | — |
IMF_ENABLE_DATAFRAME_DROP | Register imf_dataframe_drop. | false |
IMF_BASE_URL | IMF SDMX 3.0 base URL. | https://api.imf.org/external/sdmx/3.0 |
IMF_REQUEST_TIMEOUT_MS | Per-request timeout in milliseconds. | 30000 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_SESSION_MODE | HTTP session handling: stateful, stateless, or auto. | stateless |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
Build and run:
bun run rebuild
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t imf-mcp-server .
docker run --rm -p 3010:3010 imf-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/imf-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools/resources and inits services. |
src/config/server-config.ts | Server-specific env var parsing and validation with Zod. |
src/mcp-server/tools/definitions/ | Tool definitions (*.tool.ts). |
src/mcp-server/resources/definitions/ | Resource definitions (*.resource.ts). |
src/services/canvas/ | DataCanvas accessor — wraps the framework canvas instance. |
src/services/imf-sdmx/ | IMF SDMX 3.0 API client — dataflow catalog, DSD fetching, data queries. |
tests/ | Unit and integration tests mirroring src/. |
docs/ | Design notes and directory tree. |
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/*/definitions/index.tsData is sourced from the International Monetary Fund SDMX 3.0 portal under the IMF Copyright and Terms of Use. The IMF's terms permit redistribution of statistical data with attribution. Each data-returning tool response includes a source field with the required attribution: Source: International Monetary Fund, <dataflow name>, https://data.imf.org/.
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.