Skip to content

Releases: cyanheads/oecd-mcp-server

v0.3.0: unified upstream and flow-ref error contracts

Choose a tag to compare

@cyanheads cyanheads released this 10 Aug 02:57
v0.3.0
ecdd37c

unified upstream and flow-ref error contracts

  • Every tool and the oecd://dataflow/{agency_id}/{flow_id} resource declare data.reason and data.recovery.hint for OECD upstream failures via a shared upstreamRefusal() reader (#29)
  • oecd_get_dimension_values and the dataflow resource report an unparseable flow_ref as invalid_flow_ref (ValidationError) instead of dataflow_not_found / a bare NotFound (#27, #28)
  • upstream_error no longer declares retryabledata.retryable is omitted rather than sent as true
  • oecd_list_agencies and oecd_search_datasets no longer restate every remaining failure as upstream_error; undeclared codes now bubble as themselves

CHANGELOG v0.3.0

v0.2.2: redirects refused at the OECD fetch boundary

Choose a tag to compare

@cyanheads cyanheads released this 10 Aug 01:14
v0.2.2
d60d121

redirects refused at the OECD fetch boundary

  • fetchOecd issues every request with redirect: manual and refuses any 3xx as a terminal, non-retried Forbidden — the origin externalServiceRoot() pins a delegated root to previously bound only the first hop (#26)
  • oecd_list_agencies, oecd_search_datasets, oecd_get_dataset_info, oecd_get_dimension_values, oecd_query_dataset declare upstream_redirect (Forbidden, not retryable) and report the boundary's own sentence instead of an undeclared Forbidden or a retryable upstream_error
  • docs: redirect-refusal decision record in docs/design.md, README OECD_BASE_URL note, three drifted rows in the tools table corrected

CHANGELOG v0.2.2

v0.2.1: Delegated dataflows and version-pinned codelists

Choose a tag to compare

@cyanheads cyanheads released this 10 Aug 00:20
v0.2.1
1468797

Delegated dataflows and version-pinned codelists

  • Follow the 27 dataflows OECD catalogues on the public root but defines on sti-public, dcd-public, or archive, for structure, codes, and observations (#23)
  • Read codelists and concept schemes at the root and version the datastructure actually references, instead of the configured root's latest (#24)
  • Check for a delegated root before spending the observation retry budget on a 500/404, instead of after three attempts and backoff (#25)
  • NoRecordsFound bodies read as an empty result, alongside the existing NoResultsFound handling
  • field-test skill doc fix: debug-level upstream traces land in the file log sinks, not mcp_log (2.8 → 2.9)

CHANGELOG v0.2.1

v0.2.0: Dataflow reference resolution, dot-segment identifier fix

Choose a tag to compare

@cyanheads cyanheads released this 09 Aug 21:39
v0.2.0
9354d99

Dataflow reference resolution, dot-segment identifier fix

Fixes the 8 dataflows OECD publishes without a datastructure prefix and
the 49 whose id prefix names a datastructure OECD does not keep in sync
— both were unreachable or 404ing. Dimension names and agency
directorates now resolve from OECD's concept and agency schemes instead
of repeating the id.

  • BREAKING: oecd_get_dimension_values pages results (50 by default,
    limit up to 500) instead of returning the whole codelist; a
    1,164-code dimension no longer ships 66 KB to structuredContent (#6)
  • Security: a flow_ref of "." or ".." — plain or percent-encoded —
    normalized past identifier validation to an unrelated collection
    endpoint, returning the wrong dataflow's structure as if it were the
    one requested; identifiers now require a leading letter or digit
  • Dataflow references resolve through the id OECD actually catalogues,
    with a datastructure fallback for id/DSD mismatches (#20, #22)
  • oecd_list_agencies reports each agency's directorate; oecd_get_dataset_info,
    the oecd://dataflow resource, and dimension descriptions carry concept
    names instead of the raw id (#13, #16)
  • oecd_dataframe_query maps a missing table to a table_not_found reason
    instead of a generic invalid_sql (#17)

CHANGELOG v0.2.0

v0.1.5: UNIT_MULT scaling fix, full inline rendering, typed upstream-failure classification

Choose a tag to compare

@cyanheads cyanheads released this 09 Aug 15:28
v0.1.5
fd95d7b

UNIT_MULT scaling fix, full inline rendering, typed upstream-failure classification

  • Value scaling corrected: a GDP figure previously returned as 26054.614
    now returns 26054614000000, applying UNIT_MULT as OECD intends. Every
    row carries value_scale, the divisor back to the published figure (#9)
  • Every declared observation attribute (OBS_STATUS, PRICE_BASE, DECIMALS,
    UNIT_MULT, ...) is now a column instead of being dropped (#9)
  • format() renders the full result up to a shared preview budget instead
    of a 10-row cap, on both the DataCanvas and no-canvas paths; a no-canvas
    cap now discloses itself via content_table_capped (#11, #19)
  • oecd_query_dataset gained typed reasons for a 422/400 rejection, a
    request-rate or download-size throttle, a timeout, and an exhausted
    5xx, each with its own recovery (#7, #10, #18, #21)
  • Internal: shared fetchOecd HTTP boundary extracted for both SDMX
    services; explicit canvas schema so sparse attribute columns register

CHANGELOG v0.1.5

v0.1.4: oecd_search_datasets description matching + offset paging, retry fixes

Choose a tag to compare

@cyanheads cyanheads released this 09 Aug 12:57
v0.1.4
9bf703c

oecd_search_datasets description matching + offset paging, retry fixes

  • oecd_search_datasets matches descriptions as well as names (matched_in), returns a 240-char truncated description, and adds offset paging past limit (#14, #15)
  • oecd_search_datasets: agency_not_found contract entry for an unknown agency_id, no longer misreported as a retryable outage (#12)
  • Structure-service retries reclassify 404 as terminal NotFound, restate any 5xx as retryable, and stop a 429 Retry-After: 0 from collapsing the backoff
  • enrichment.totalCount on oecd_search_datasets is optional, fixing an output-validation failure on fully-returned searches (#5)
  • README and design docs: stale PISA references and dead example agency IDs corrected against the live catalog (#8)
  • Dockerfile production stage installs prod deps instead of copying dev node_modules (888 MB -> 664 MB)
  • deps: @cyanheads/mcp-ts-core ^0.10.6 -> ^0.11.1 (+ dev-dep bumps, bun 1.3.14)

CHANGELOG v0.1.4

v0.1.3: mcp-ts-core ^0.10.6 adoption

Choose a tag to compare

@cyanheads cyanheads released this 13 Jun 04:00
v0.1.3
395844b

mcp-ts-core ^0.10.6 adoption

Framework upgrade to 0.10.x with the tool-surface and packaging changes it brings.

Added:

  • oecd_search_datasets discloses the full match count (enrichment.totalCount) when the limit caps the returned list
  • oecd_dataframe_query denies system-catalog introspection from caller SQL (denySystemCatalogs: true)
  • Container HEALTHCHECK on /healthz, APP_VERSION OCI label, writable .cache/.mirror data dirs

Changed:

  • createApp() sets explicit name/title = oecd-mcp-server
  • Error contracts invalid_sql/invalid_flow_ref/invalid_key migrate InvalidParamsValidationError
  • bundle cleans the .mcpb (clean-mcpb.ts): prunes dev deps, strips dependency-shipped agent docs

Dependency bumps:

  • @cyanheads/mcp-ts-core ^0.9.21 → ^0.10.6
  • @biomejs/biome ^2.4.16 → ^2.5.0
  • @types/node ^25.9.2 → ^25.9.3

61 tests pass; bun run devcheck clean.

v0.1.2: DX fixes across 4 tools

Choose a tag to compare

@cyanheads cyanheads released this 07 Jun 06:41
v0.1.2
0c0b17c

DX fixes across 4 tools

Corrects four agent-facing gaps identified during initial field testing.

Fixed:

  • oecd_search_datasets description no longer leaks the caching implementation detail (#1)
  • oecd_query_dataset response echoes effective query parameters (flow_ref, key, period range) in both structuredContent and content[] (#2)
  • oecd_get_dimension_values returns a notice field when a dimension has no codelist, directing the caller to oecd_query_dataset for discovery (#3)
  • oecd_dataframe_describe / oecd_dataframe_query canvas-not-configured path uses a declared canvas_disabled contract (ServiceUnavailable, typed data.reason) instead of an undeclared factory call (#4)

Dependency bumps:

  • @types/node ^25.9.1 → ^25.9.2

61 tests pass; bun run devcheck clean.

v0.1.1: First public release — OECD SDMX MCP server

Choose a tag to compare

@cyanheads cyanheads released this 05 Jun 12:27
v0.1.1
1c27f9b

First public release — OECD SDMX MCP server

7 MCP tools + 1 resource over 1,500+ OECD statistical datasets via SDMX. Keyless; no API key required. Optional DataCanvas SQL support for large result sets via DuckDB.

Added:

  • oecd_list_agencies, oecd_search_datasets, oecd_get_dataset_info, oecd_get_dimension_values — SDMX structure tools
  • oecd_query_dataset — fetch observations; large result sets spill to DataCanvas (CANVAS_PROVIDER_TYPE=duckdb)
  • oecd_dataframe_describe, oecd_dataframe_query — DataCanvas SQL tools
  • oecd://dataflow/{agency_id}/{flow_id} resource — dimension metadata as JSON
  • Dockerfile with node_modules copy for @duckdb/node-api native binary preservation

Security:

  • SDMX_ID_SAFE regex — validates agencyId, dsdId, dfId against /^[A-Za-z0-9._-]+$/ before URL construction
  • SDMX_KEY_SAFE regex — validates dimension key against /^[A-Za-z0-9._+%-]*$/ before URL path insertion
  • Error sanitization — removed url from serviceUnavailable context, stripped body content from 400/parse-error messages

60 tests pass; bun run devcheck clean.