About imf-mcp-server
An MCP server for querying IMF SDMX 3.0 macroeconomic data across dataflows and countries. It serves analysts and agents who need time series such as WEO projections, balance of payments, CPI, or exchange rates, with optional SQL analysis of staged results.
Key features
- 01Browse IMF dataflows
- 02Resolve dimensions and codes
- 03Query time-series data
- 04Stage large results in DataCanvas
- 05Run read-only SQL on staged tables
- 06Read dataflow metadata as a resource
Use cases
- 01Find an IMF dataset for a macroeconomic indicator
- 02Retrieve country data over a time range
- 03Compare or analyze staged multi-country results
- 04Inspect dimension codes before querying
MCP support
Provides six tools and an `imf://database/{dataflow_id}` resource to MCP clients over STDIO or Streamable HTTP. A public hosted endpoint is available.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://imf.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-imf https://imf.caseyjhand.com/mcp{"mcpServers":{"cyanheads-imf":{"type":"http","url":"https://imf.caseyjhand.com/mcp"}}}Open in Cursor{"servers":{"cyanheads-imf":{"type":"http","url":"https://imf.caseyjhand.com/mcp"}}}Open in VS Code{"mcpServers":{"cyanheads-imf":{"type":"http","url":"https://imf.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-imf":{"serverUrl":"https://imf.caseyjhand.com/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
5| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Maximum dataflows to return in this call. Default 50; one call returns at most 200, so a larger limit (up to 1,000) returns 200 and echoes requested_limit and applied_limit. total_count reports how many matched, so a partial page is always recognizable as one. |
| filter | string | No | Optional words to filter results by, split on spaces and commas. A dataflow matches when every word appears, case-insensitively, somewhere in its ID, name, or full description. Example: "exchange rate" returns ER and related dataflows; "WEO outlook" returns WEO and the regional outlooks built on it. |
| offset | integer | No | Number of matching dataflows to skip before this page. Combine with limit to page through a broad or unfiltered catalog. |
| include_vintages | boolean | No | Include vintage (historical snapshot) dataflows such as WEO_2025_OCT_VINTAGE. Default false — vintages are excluded to keep the discovery surface clean. |
Details
From the project README@cyanheads/imf-mcp-server
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
Overview
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.
Tools
| 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 |
Resources
| Resource | Description |
|---|---|
imf://database/{dataflow_id} | Discovery metadata for one dataflow: dimensions, codelist previews, and key_format |
Capability reference
imf_list_databases tool
filterkeeps dataflows whose ID, name, or description contains every word (split on spaces and commas, case-insensitive); vintage snapshots such asWEO_2025_OCT_VINTAGEare excluded unlessinclude_vintages=true- Paged with
limit(default 50) andoffset; a page holds at most 200, and a largerlimit(up to 1,000) echoesrequested_limit/applied_limit.total_countandreturned_countreport the match and page sizes - Descriptions are cut to 200 characters;
imf_get_databasereturns the full text
imf_get_database tool
- Resolves terms to SDMX dimension codes (countries are ISO 3-letter:
USA, notUS) and returnskey_format, the dot-separated dimension orderimf_query_datasetrequires - Codelist previews hold 50 entries; set
dimension_idto page one dimension withlimit/offset(at most 200 per page,next_offsetnames the rest), andcodelist_filterto keep codes whose ID or name contains every word available_only=truepages only the codes the dataflow publishes, with series count and time coverage;agency_id/versionare auto-detected when omitted
imf_query_dataset tool
- Dot-separated key in DSD order, where
+combines codes at a position and*matches all of them; codes anddataflow_idare case-insensitive.start_period/end_periodacceptYYYY,YYYY-SN,YYYY-QN,YYYY-MM, orYYYY-MM-DD, andlast_n_observations(1–1,000,000) keeps each series' last N observations - Returns
time_period,value,status, and series attributes (unit,scale,decimals,reference_periodwhere published), with oneseries_metadataentry per series. Responses are held to 100,000 characters: with DataCanvas, larger results spill to it (output_mode: "canvas"forces staging, andstagedreports storage); without it, the earliest observations return withtruncated: trueandretrieval_guidance - Key and range errors are
invalid_key_code(with the nearest valid codes),wildcard_in_code_list,key_too_long,response_too_large,no_data, andno_data_in_range; a+key that partly returns lists the rest inmissing_series. Upstream failures aredata_unavailableandrate_limited, both retryable within a 45-second call budget
imf_dataframe_describe tool
- Lists every staged table with row count and column names and DuckDB types
- Requires
canvas_idfrom animf_query_datasetcall that returnedstaged: true; call it beforeimf_dataframe_query - Listed only with
CANVAS_PROVIDER_TYPE=duckdb, like the other dataframe tools
imf_dataframe_query tool
- One read-only SQL
SELECTper call; a leadingWITH … SELECTis accepted, DML and DDL are rejected - Results are capped by the canvas row limit (default 10,000), then a 100,000-character response budget;
truncated: truemeans either cap trimmed the result. Page with a stableORDER BYplusLIMIT/OFFSET - Oversized cells are clipped in the text table while
structuredContentkeeps every value;response_too_largemeans a single row exceeds the budget even so - Listed only with
CANVAS_PROVIDER_TYPE=duckdb
imf_dataframe_drop tool
- Removes one named table or view from a canvas; requires the exact name from
imf_dataframe_describe - A repeated or absent drop returns
dropped: falserather than an error - Disabled by default; set
IMF_ENABLE_DATAFRAME_DROP=truealongsideCANVAS_PROVIDER_TYPE=duckdbto register it
imf://database/{dataflow_id} resource
- Every dimension with up to 50 codelist entries, plus counts,
key_format, name, and description dataflow_idcomes fromimf_list_databases;continuationmetadata points toimf_get_databasefor codelists beyond the preview
Features
Built 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:
- Keyless access to the public IMF SDMX 3.0 portal
- Typed SDMX 3.0 client that validates the key's dimension count against the DSD before each query
- Dataflow catalog and availability constraints cached in-session
- DuckDB-backed DataCanvas spill for large multi-country or long time-range results
Agent-friendly output:
- Codelist entries carry both the machine code and the human-readable label
key_formatin every dataflow response states the dimension order- Observations carry each dataflow's
statusflags (e.g.T,C,NA) for data-quality caveats stagedandtruncatedare reported separately, and staged results carrycanvas_id,table_name, and retrieval guidance
Getting started
Public Hosted Instance
A 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"
}
}
}
Self-Hosted / Local
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
Prerequisites
- Bun v1.4.0 or higher (or Node.js v24+).
- No API key required.
Installation
- Clone the repository:
git clone https://github.com/cyanheads/imf-mcp-server.git
- Navigate into the directory:
cd imf-mcp-server
- Install dependencies:
bun install
- Configure environment:
cp .env.example .env
# edit .env as needed — no required vars for basic use
Configuration
| 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.
Running the server
Local development
-
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
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.
Project structure
| 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. |
Development guide
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storage - Register new tools and resources via the barrels in
src/mcp-server/*/definitions/index.ts - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Data source
Data 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/.
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
License
Apache-2.0 — see LICENSE for details.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.