imf-mcp-server

v0.4.1 pre-1.0

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.

imf.caseyjhand.com/mcp
claude mcp add --transport http imf-mcp-server https://imf.caseyjhand.com/mcp
codex mcp add imf-mcp-server --url https://imf.caseyjhand.com/mcp
{
  "mcpServers": {
    "imf-mcp-server": {
      "url": "https://imf.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http imf-mcp-server https://imf.caseyjhand.com/mcp
{
  "mcpServers": {
    "imf-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://imf.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "imf-mcp-server": {
      "type": "http",
      "url": "https://imf.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://imf.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

6

read 5

imf_list_databases

open-world

List IMF SDMX dataflows available on the portal. Entry point for every query: imf_get_database and imf_query_dataset both require a dataflow id obtained here. Vintage (historical snapshot) dataflows such as WEO_2025_OCT_VINTAGE are excluded by default; set include_vintages=true to include them. Results are paged — 50 per call by default, adjustable with limit and offset — and total_count reports how many dataflows matched. Descriptions are shortened here; imf_get_database returns the full text for a single dataflow.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "imf_list_databases",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "filter": {
      "description": "Optional name, ID, or description substring to filter results. Case-insensitive. Example: \"exchange rate\" returns ER and related dataflows.",
      "type": "string",
      "minLength": 1
    },
    "include_vintages": {
      "default": false,
      "description": "Include vintage (historical snapshot) dataflows such as WEO_2025_OCT_VINTAGE. Default false — vintages are excluded to keep the discovery surface clean.",
      "type": "boolean"
    },
    "limit": {
      "default": 50,
      "description": "Maximum dataflows to return in this call. Default 50, ceiling 200; total_count reports how many matched, so a partial page is always recognizable as one.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "offset": {
      "default": 0,
      "description": "Number of matching dataflows to skip before this page. Combine with limit to page through a broad or unfiltered catalog.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "include_vintages",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

imf_get_database

open-world

Fetch a dataflow's dimension list with a codelist preview for each dimension. Resolves human-readable terms to SDMX codes (e.g. "United States" → USA, "Constant prices" → NGDP_RPCH). Required before imf_query_dataset — SDMX keys are opaque without codelist lookups. Each codelist is capped at the first 50 entries by default, including previews filtered by codelist_filter. Set dimension_id to retrieve one codelist with bounded limit/offset paging after the optional substring filter. Set available_only=true to page codes the dataflow actually publishes, with series and time coverage metadata; availability filtering happens before codelist_filter and paging. The imf://database/{dataflow_id} resource provides the same bounded discovery summary. Country codes are ISO 3-letter (USA, GBR, DEU), not ISO 2-letter (US, GB, DE). The key_format field shows the exact dimension order required by imf_query_dataset. Note: codelists enumerate the code universe, not actual coverage — valid codes can still return no_data if the combination has no series in this dataflow.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "imf_get_database",
    "arguments": {
      "dataflow_id": "<dataflow_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "dataflow_id": {
      "type": "string",
      "description": "Dataflow identifier from imf_list_databases, e.g. WEO, BOP, CPI. Case-sensitive."
    },
    "agency_id": {
      "description": "Agency ID that publishes this dataflow, e.g. IMF.RES or IMF.STA. Auto-detected from the dataflow list when omitted.",
      "type": "string"
    },
    "version": {
      "description": "Dataflow version, e.g. 9.0.0. Auto-detected from the dataflow list when omitted.",
      "type": "string"
    },
    "codelist_filter": {
      "description": "Optional case-insensitive substring to search within each dimension's codelist (code ID and name). Filtering runs before the 50-entry preview or selected-dimension page. Example: \"CPI\" or \"Constant prices\" surfaces matching WEO indicator codes.",
      "type": "string",
      "minLength": 1
    },
    "available_only": {
      "default": false,
      "description": "Return only codes reported by the dataflow-wide availability constraint. Default false keeps ordinary codelist discovery unchanged.",
      "type": "boolean"
    },
    "dimension_id": {
      "description": "Exact dimension ID from this tool, e.g. INDICATOR. Select one dimension to page beyond its preview.",
      "type": "string",
      "minLength": 1
    },
    "limit": {
      "description": "Entries to return from the selected dimension. Valid only with dimension_id; default 50, maximum 200.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "offset": {
      "description": "Matching entries to skip in the selected dimension before this page. Valid only with dimension_id; default 0.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "dataflow_id",
    "available_only"
  ],
  "additionalProperties": false
}
view source ↗

imf_query_dataset

open-world

Query an IMF SDMX dataflow by dimension key over a time range. Returns observations with time_period, value, and status, plus the unit, scale, and decimals of each series — a key resolving to several series carries one entry per series in series_metadata, since unit and scale differ between them. Requires imf_get_database first to obtain the correct key_format and valid dimension codes. Country codes are ISO 3-letter (USA, GBR, DEU — not US, GB, DE). Key format: dot-separated codes in DSD keyPosition order (e.g. USA.NGDP_RPCH.A for WEO). Every position must carry a code: use + to combine codes (e.g. USA+GBR.NGDP_RPCH.A) and * to match every code at a position (e.g. *.NGDP_RPCH.A for all countries). Codelists from imf_get_database enumerate the code universe, not actual coverage — valid codes can still return no_data if the combination has no series. start_period and end_period must be valid period strings (YYYY, YYYY-SN, YYYY-QN, YYYY-MM, or a calendar-valid YYYY-MM-DD) with start_period no later than end_period; malformed or reversed ranges are rejected. A bound covers the whole period it names, so end_period 2023 includes 2023-M12 and 2023-Q4. Large analytical result sets (multi-country, long time range) spill to DataCanvas; call imf_dataframe_describe first to inspect staged tables and columns, then imf_dataframe_query for SQL analysis.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "imf_query_dataset",
    "arguments": {
      "dataflow_id": "<dataflow_id>",
      "key": "<key>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "dataflow_id": {
      "type": "string",
      "description": "Dataflow identifier from imf_list_databases, e.g. WEO, BOP, CPI."
    },
    "agency_id": {
      "description": "Agency ID, e.g. IMF.RES or IMF.STA. Auto-detected from dataflow list when omitted.",
      "type": "string"
    },
    "version": {
      "description": "Dataflow version. Auto-detected from dataflow list when omitted.",
      "type": "string"
    },
    "key": {
      "type": "string",
      "description": "Dot-separated dimension codes in DSD keyPosition order. Call imf_get_database to get key_format and valid codes first. Use + to combine codes at one position (e.g. USA+GBR.NGDP_RPCH.A). Use * to match every code at a position — *.NGDP_RPCH.A returns the indicator for all countries, and CAN.*.A every indicator for Canada. Every position needs a code or a *; an empty segment (USA..A) is rejected. Country codes are ISO 3-letter: USA not US, GBR not GB, DEU not DE."
    },
    "start_period": {
      "description": "Start of time range (inclusive). Accepts any of YYYY (annual), YYYY-SN (semi-annual, e.g. 2023-S1), YYYY-QN (quarterly, e.g. 2023-Q1), YYYY-MM (monthly), or a calendar-valid YYYY-MM-DD (daily), whatever the dataflow's frequency. The bound covers the whole period it names, so start_period 2023 admits 2023-M01 and 2023-Q1. Observations before this period are excluded from the result.",
      "type": "string"
    },
    "end_period": {
      "description": "End of time range (inclusive). Same formats as start_period, and must not be earlier than it. The bound covers the whole period it names, so end_period 2023 admits 2023-M12 and 2023-Q4. Observations after this period are excluded from the result.",
      "type": "string"
    },
    "canvas_id": {
      "description": "Existing canvas ID to accumulate results into across multiple queries. This selects the destination only; it does not force staging. Use output_mode=\"canvas\" to stage an under-budget result.",
      "type": "string"
    },
    "output_mode": {
      "default": "auto",
      "description": "Result placement. auto returns an under-budget result inline and spills only when needed. canvas explicitly stages the full result, using canvas_id when supplied or allocating a fresh canvas.",
      "type": "string",
      "enum": [
        "auto",
        "canvas"
      ]
    }
  },
  "required": [
    "dataflow_id",
    "key",
    "output_mode"
  ],
  "additionalProperties": false
}
view source ↗

imf_dataframe_describe

List DataCanvas tables and columns staged by a prior imf_query_dataset call. Returns each table's name, row count, and column schema (name + DuckDB type). Required before imf_dataframe_query to discover the table and column names for SQL.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "imf_dataframe_describe",
    "arguments": {
      "canvas_id": "<canvas_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "canvas_id": {
      "type": "string",
      "description": "Canvas ID returned by imf_query_dataset whenever staged=true, from automatic spillover or output_mode=\"canvas\"."
    }
  },
  "required": [
    "canvas_id"
  ],
  "additionalProperties": false
}
view source ↗

imf_dataframe_query

Run a read-only SQL SELECT against a DataCanvas table staged by imf_query_dataset. Supports multi-country comparisons, time-series aggregation, and cross-indicator joins. Requires imf_dataframe_describe first to discover table and column names. One SELECT statement per call; a leading WITH … SELECT (CTE) is accepted. DML and DDL are rejected.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "imf_dataframe_query",
    "arguments": {
      "canvas_id": "<canvas_id>",
      "sql": "<sql>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "canvas_id": {
      "type": "string",
      "description": "Canvas ID returned by imf_query_dataset whenever staged=true. Call imf_dataframe_describe with it before writing SQL."
    },
    "sql": {
      "type": "string",
      "description": "Read-only SQL SELECT statement — exactly one statement, starting with SELECT or with a WITH … SELECT common table expression. Reference tables by the names returned by imf_dataframe_describe. Example: SELECT time_period, value FROM spilled_abc123 WHERE time_period >= '2010' ORDER BY time_period."
    }
  },
  "required": [
    "canvas_id",
    "sql"
  ],
  "additionalProperties": false
}
view source ↗

disabled 1

imf_dataframe_drop

Remove one DataCanvas table or view staged by imf_query_dataset without affecting other tables on the same canvas. Use imf_dataframe_describe to copy the exact table name. A repeated or absent drop returns dropped=false.

disabledwould be destructive

Disabled. Dataframe table cleanup is disabled in this deployment.

IMF_ENABLE_DATAFRAME_DROP=true
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "canvas_id": {
      "type": "string",
      "description": "Canvas ID returned by imf_query_dataset whenever staged=true."
    },
    "table_name": {
      "type": "string",
      "description": "Exact table or view name returned by imf_dataframe_describe."
    }
  },
  "required": [
    "canvas_id",
    "table_name"
  ],
  "additionalProperties": false
}
view source ↗

Resources

1

Metadata for a single IMF SDMX dataflow — dimensions with their concept-scheme labels and bounded codelist previews, counts, key_format, name, and description. Stable URI-addressable reference for known dataflow IDs (WEO, BOP, CPI, etc.).

uri imf://database/{dataflow_id} mime application/json