MCP server: One MCP server.

imf-mcp-server

@cyanheadsMCP server · External

Query IMF SDMX 3.0 macroeconomic dataflows — WEO, BOP, CPI, exchange rates, 190 countries.

Economic datav0.4.4Apache-2.0TypeScript
Freeno charge per call

One address for any MCP client. No sign-in needed on this server.

What it does

5 read

Grouped by tool name. At most: creates or changes data: records, files, settings.

What it costs

Free

Odel charges nothing per call. The publisher may charge for its own service.

Tools

5 · grouped by tool name · checked 18 Oct 2026

Read · 5Look things up

  • imf_list_databases
  • imf_get_database
  • imf_query_dataset
  • imf_dataframe_describe
  • imf_dataframe_query
Try it in the Inspector
README8 min read

@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.

6 Tools • 1 Resource

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

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

ToolDescription
imf_list_databasesList IMF SDMX dataflows, with an optional word filter
imf_get_databaseFetch a dataflow's dimensions and codelists to resolve terms to SDMX codes
imf_query_datasetQuery a dataflow by dimension key over a time range
imf_dataframe_describeList DataCanvas tables and columns staged by imf_query_dataset
imf_dataframe_queryRun a read-only SQL SELECT across staged DataCanvas tables
imf_dataframe_dropRemove one staged table or view; disabled by default

Resources

ResourceDescription
imf://database/{dataflow_id}Discovery metadata for one dataflow: dimensions, codelist previews, and key_format

Capability reference

imf_list_databases tool

  • filter 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=true
  • Paged with limit (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 sizes
  • Descriptions are cut to 200 characters; imf_get_database returns the full text

imf_get_database tool

  • Resolves terms to SDMX dimension codes (countries are ISO 3-letter: USA, not US) and returns key_format, the dot-separated dimension order imf_query_dataset requires
  • Codelist previews hold 50 entries; set dimension_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 word
  • available_only=true pages only the codes the dataflow publishes, with series count and time coverage; agency_id/version are 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 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 observations
  • Returns time_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_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, 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 budget

imf_dataframe_describe tool

  • Lists every staged table with row count and column names and DuckDB types
  • Requires canvas_id from an imf_query_dataset call that returned staged: true; call it before imf_dataframe_query
  • Listed only with CANVAS_PROVIDER_TYPE=duckdb, like the other dataframe tools

imf_dataframe_query tool

  • One read-only SQL SELECT per call; a leading WITH … SELECT is 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: true means either cap trimmed the result. Page with a stable ORDER BY plus LIMIT/OFFSET
  • Oversized cells are clipped in the text table while structuredContent keeps every value; response_too_large means 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: false rather than an error
  • Disabled by default; set IMF_ENABLE_DATAFRAME_DROP=true alongside CANVAS_PROVIDER_TYPE=duckdb to register it

imf://database/{dataflow_id} resource

  • Every dimension with up to 50 codelist entries, plus counts, key_format, name, and description
  • dataflow_id comes from imf_list_databases; continuation metadata points to imf_get_database for 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_format in every dataflow response states the dimension order
  • Observations carry each dataflow's status flags (e.g. T, C, NA) for data-quality caveats
  • staged and truncated are reported separately, and staged results carry canvas_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:

json
{
  "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.

json
{
  "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):

json
{
  "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:

json
{
  "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:

sh
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

  1. Clone the repository:
sh
git clone https://github.com/cyanheads/imf-mcp-server.git
  1. Navigate into the directory:
sh
cd imf-mcp-server
  1. Install dependencies:
sh
bun install
  1. Configure environment:
sh
cp .env.example .env
# edit .env as needed — no required vars for basic use

Configuration

VariableDescriptionDefault
CANVAS_PROVIDER_TYPESet to duckdb to enable DataCanvas spill and the dataframe tools.—
IMF_ENABLE_DATAFRAME_DROPRegister imf_dataframe_drop.false
IMF_BASE_URLIMF SDMX 3.0 base URL.https://api.imf.org/external/sdmx/3.0
IMF_REQUEST_TIMEOUT_MSPer-request timeout in milliseconds.30000
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_SESSION_MODEHTTP session handling: stateful, stateless, or auto.stateless
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
OTEL_ENABLEDEnable OpenTelemetry instrumentation.false

See .env.example for the full list of optional overrides.

Running the server

Local development

  • Build and run:

    sh
    bun run rebuild
    
    bun run start:stdio
    # or
    bun run start:http
    
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    

Docker

sh
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

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools/resources and inits services.
src/config/server-config.tsServer-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/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for 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:

sh
bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

Similar modules

Browse Economic data