← The evidence ledger
Evidence row 579916
Observed , by probe.mcp/1.
- Kind
- mcp.tools
- About
- endpoint ac612620-886c-46f8-83ac-926298f79d17
- Recorded
- Previous row
- None: the first of its kind about this subject
- Body SHA-256
- fb9220c919a2c290d91c5ca30d4bbb6b109e9dbd08af05a75ed0a444d55a21a9
- Leaf
- 0x727191a8ca3d50156d3d53eb36d491d4b85e6aa367f8bf6dfc76bb85d12cde6e
What was observed
{
"count": 5,
"tools": [
{
"description": "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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"canvas_id": {
"description": "Canvas ID returned by imf_query_dataset whenever staged=true, from automatic spillover or output_mode=\"canvas\".",
"pattern": "^[A-Za-z0-9_-]{10}$",
"type": "string"
}
},
"required": [
"canvas_id"
],
"type": "object"
},
"name": "imf_dataframe_describe"
},
{
"description": "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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"canvas_id": {
"description": "Canvas ID returned by imf_query_dataset whenever staged=true. Call imf_dataframe_describe with it before writing SQL.",
"pattern": "^[A-Za-z0-9_-]{10}$",
"type": "string"
},
"sql": {
"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.",
"type": "string"
}
},
"required": [
"canvas_id",
"sql"
],
"type": "object"
},
"name": "imf_dataframe_query"
},
{
"description": "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 codelist_filter, which keeps codes whose ID or name contains every word given. 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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"agency_id": {
"description": "Agency ID that publishes this dataflow, e.g. IMF.RES or IMF.STA, matched case-insensitively. Auto-detected from the dataflow list when omitted.",
"type": "string"
},
"available_only": {
"default": false,
"description": "Return only codes reported by the dataflow-wide availability constraint. Default false keeps ordinary codelist discovery unchanged.",
"type": "boolean"
},
"codelist_filter": {
"description": "Optional words to search for in each dimension's codelist, split on spaces and commas. A code matches when every word appears, case-insensitively, in its code ID or name; different words may match different fields. Filtering runs before the 50-entry preview or selected-dimension page. Example: \"CPI\", \"GDP constant prices\", or \"NGDP_RPCH percent\" surfaces matching WEO indicator codes.",
"minLength": 1,
"type": "string"
},
"dataflow_id": {
"description": "Dataflow identifier from imf_list_databases, e.g. WEO, BOP, CPI.",
"type": "string"
},
"dimension_id": {
"description": "Exact dimension ID from this tool, e.g. INDICATOR. Select one dimension to page beyond its preview.",
"minLength": 1,
"type": "string"
},
"limit": {
"description": "Entries to return from the selected dimension. Valid only with dimension_id; default 50. One call returns at most 200, so a larger limit (up to 50,000) returns 200, echoes requested_limit and applied_limit, and next_offset names the rest.",
"maximum": 50000,
"minimum": 1,
"type": "integer"
},
"offset": {
"description": "Matching entries to skip in the selected dimension before this page. Valid only with dimension_id; default 0.",
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"version": {
"description": "Dataflow version, e.g. 9.0.0. Auto-detected from the dataflow list when omitted.",
"type": "string"
}
},
"required": [
"dataflow_id"
],
"type": "object"
},
"name": "imf_get_database"
},
{
"description": "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 and at most 200, 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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"filter": {
"description": "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.",
"minLength": 1,
"type": "string"
},
"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; 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.",
"maximum": 1000,
"minimum": 1,
"type": "integer"
},
"offset": {
"default": 0,
"description": "Number of matching dataflows to skip before this page. Combine with limit to page through a broad or unfiltered catalog.",
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "imf_list_databases"
},
{
"description": "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. An index series also carries the reference_period it is based on (e.g. 2010A, 2010=100) exactly as published, on the series and, where the dataflow publishes one per observation, on each observation. 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); * stands alone and cannot join a + list. Codes are matched case-insensitively and checked against each dimension's codelist before the query — an unknown code is rejected with the nearest valid codes. 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. When a + key returns data for some requested series and none for others, missing_series names each empty one with the reason a query for it alone gives (no_data or no_data_in_range). When the extra request that recovers the unit, scale, or decimals a + key suppresses fails, unresolved_attributes names them and how to get them. 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. last_n_observations keeps each series' last N observations — 1 is each series' latest value, the cheap way to ask many countries for their latest figure. Values are in base units everywhere, staged canvas rows included: scale is the power of ten the IMF publishes a series in (value / 10^scale is the published figure), never a factor still to apply. A response is held to 100,000 serialized characters. With DataCanvas enabled (CANVAS_PROVIDER_TYPE=duckdb), a larger result (multi-country, long time range) spills to it: call imf_dataframe_describe first to inspect staged tables and columns, then imf_dataframe_query for SQL analysis. Without DataCanvas, a larger result returns its earliest observations with truncated=true, and retrieval_guidance names the last period returned and how to narrow the query.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"agency_id": {
"description": "Agency ID, e.g. IMF.RES or IMF.STA, matched case-insensitively. Auto-detected from dataflow list when omitted.",
"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.",
"pattern": "^[A-Za-z0-9_-]{10}$",
"type": "string"
},
"dataflow_id": {
"description": "Dataflow identifier from imf_list_databases, e.g. WEO, BOP, CPI. Matched case-insensitively; the response echoes the catalog spelling.",
"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"
},
"key": {
"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. A * stands alone at its position — combined with other codes (USA+*) it is rejected. Codes are trimmed and matched case-insensitively (usa resolves to USA), empty and repeated + members are dropped (USA++GBR+USA is queried as USA+GBR, and notice says so), and the response echoes the canonical key. A code missing from its dimension's codelist is rejected before the query, naming the nearest valid codes. The portal limits the request URL, so a + list of a few hundred codes is rejected as too long — use * there, or split the codes across calls. Country codes are ISO 3-letter: USA not US, GBR not GB, DEU not DE.",
"type": "string"
},
"last_n_observations": {
"description": "Keep only each series' last N observations, an integer from 1 to 1,000,000; 1 returns each series' latest value. Latest is per series: series end at different periods, and a WEO series ends in its projection years (e.g. 2031), so set end_period to stop at a past year. With start_period or end_period, the last N inside that range. A series with fewer than N observations is returned whole. Omit to return every observation.",
"maximum": 1000000,
"minimum": 1,
"type": "integer"
},
"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.",
"enum": [
"auto",
"canvas"
],
"type": "string"
},
"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"
},
"version": {
"description": "Dataflow version, e.g. 9.0.0. Auto-detected from dataflow list when omitted.",
"type": "string"
}
},
"required": [
"dataflow_id",
"key"
],
"type": "object"
},
"name": "imf_query_dataset"
}
]
}What the leaf hashes
{"body":"fb9220c919a2c290d91c5ca30d4bbb6b109e9dbd08af05a75ed0a444d55a21a9","id":579916,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793143571386910,"prev":null,"subject":"ac612620-886c-46f8-83ac-926298f79d17","subject_kind":"endpoint"}Proof
Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (273461 rows).
- 0x72723c11e65d235640b1bd604c20cde6983289c82bb5e9593b2830d696384f2c
- 0x012a1eb9a14b1138dadfb9f673e46fcbdf82f3f23d2d42328e5cbff7e9ba19ec
- 0x52b52c2a180eebae5a940a7e2b1cf8ee8ad5f3de0921c141f3f55dd243808671
- 0x72886491d1fb7483e0a44690ecac9efbf3e66aba29ee81d478a2ae1cc0edbc20
- 0xe89b8e4cfe55b313190029123e2da6aadd0632c6737f6efb48be692ed514bc3f
- 0xe5cfe14e5f757b62f471c552fdbe8fe264431a0fc4c5de973025cfb9b595acaa
- 0xd28b9820c103fe305883c62851d41538b00c3c872b2e7365034c95dbf0eb77ed
- 0x7f56d06ce265c94e68c09c7731531b3dee2a4c04f87a3890d2eebbf07dac9997
- 0x1834926a41726b82ca399b1246e6ca611c1b2916772420cc0f0a584bd58d1d1c
- 0x41177ecd574fbfd5db971f26345d463c2727ea480039aa14f77f20bd18ac0eca
- 0x23a51a936f60011ce90a404c26ca8b5c81a512eb324bd00dcb5ce643c0b38c8e
- 0x8a2168d13e43e2c8b0f508ca779f90beef60501499eeab439eb7d23816a97bc4
- 0x2926e99aefa0ff2e14a67a3ae10a7f6e753ce4b799c6fe531f8cbf8d33b31a66
- 0xb2ae53d841a55a805fb4078b1a7d44e08a81aba4be3690bac3a5b4c366bf39da
- 0x275720ecabb68df33eee92ae4fd70572a8d952d6c61c061c2869cfc3217aa5c5
- 0x23cf9bb4337ee8be7fcae368fd69d24c62c11fb45882127b4cd919bb96a19996
- 0x0e01aa9525097570a6edaf32bfc959de57bf5c24317cf10c0716affea85ca60d
- 0xa20d48798a34aba12eb9c7297722982d910f06c148f5e27ac59307422964a585
- 0x9fc354c0ea3efc3f1b6548bb77ea902a50f2c9647647ea61592efce2bd795699
- Day root
- 0xdd77e5e99da32c3f154180d63e3c3e6fe11e896a2c6896412ef6b5c4bcf7e795
- Chained
- 0x23bb4dfd09f55c15ac3962f53578e02c6114d5bfd9bb451cf8794fb6e2817ef4
- Published
- On Arc Testnet, block 69414147: 0xb2ebd83aafeb765a0ce66e76aefb133ed06606c98038fd56191e2bcd1dcb77b4