MCP server: One MCP server.

treasury-fiscaldata-mcp-server

@cyanheadsMCP server · External

Query US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP.

Government open datav0.3.0Apache-2.0TypeScript
Freeno charge per call

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

What it does

7 read

Grouped by tool name. At most: moves money, runs code or commands, deletes data, or sends messages for you.

What it costs

Free

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

Tools

7 · grouped by tool name · checked 26 Oct 2026

Read · 7Look things up

  • treasury_list_datasets
  • treasury_query_dataset
  • treasury_get_debt
  • treasury_get_interest_rates
  • treasury_get_exchange_rates
  • treasury_dataframe_describe
  • treasury_dataframe_query
Try it in the Inspector
README11 min read

@cyanheads/treasury-fiscaldata-mcp-server

Query US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP.

8 Tools · dataframe drop is opt-in

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


Overview

US Treasury Fiscal Data: the national debt, interest rates, exchange rates, and other federal fiscal datasets. Pull the headline numbers in one call, query any Fiscal Data endpoint directly, and run SQL over large pulls.

Tools

ToolDescription
treasury_list_datasetsBrowse the curated catalog of 17 Treasury Fiscal Data endpoints with field names, descriptions, and update cadence
treasury_query_datasetQuery any Treasury Fiscal Data endpoint by path, field list, filters, sort, and page — with optional DataCanvas spill
treasury_get_debtFetch national debt (Debt to the Penny) — latest record, specific date, or date-range series with optional DataCanvas spill
treasury_get_interest_ratesAverage interest rates Treasury pays on outstanding securities by type — marketable issues, non-marketable series, and aggregate totals
treasury_get_exchange_ratesOfficial Treasury statutory exchange rates for ~165 countries, published quarterly
treasury_dataframe_describeList DataCanvas dataframes materialized by the treasury_* tools with schema, row count, and TTL
treasury_dataframe_queryRun a single-statement SELECT against DataCanvas dataframes using standard DuckDB SQL
treasury_dataframe_dropDelete a staged dataframe and its provenance (disabled unless TREASURY_DATAFRAME_DROP_ENABLED=true)

Capability reference

treasury_list_datasets tool

  • Filter by category (debt, interest_rates, exchange_rates, revenue_spending, savings_bonds, securities, other) or keyword search.
  • Returns endpoint paths, fields, types, and update cadence from a bundled catalog, with no network call.

treasury_query_dataset tool

  • Query an endpoint with { field, operator, value } filters (eq, gt, gte, lt, lte, in), sort, and pagination: page_size 1–10000 (default 100), page_number starts at 1.
  • Returns rows, field labels, total_count, and total_pages; error reasons are invalid_endpoint, invalid_field, invalid_filter, and page_out_of_range.
  • Pass canvas_id to stage the page for SQL analysis; the returned canvas_id is the assigned table name.

treasury_get_debt tool

  • mode=latest returns the newest business-day record; mode=date accepts a YYYY-MM-DD date; mode=series accepts a date range. Coverage begins 1993-04-01.
  • Returns debt totals and a 20-row series preview; compare retrieved_records with total_records. A missing date returns no_data_for_date.
  • Series staging starts above 500 rows or on request via canvas_id; paging stops at 50,000 rows.

treasury_get_interest_rates tool

  • mode=latest returns the newest month's rates, optionally filtered by security_type; mode=series accepts a date range.
  • Rates are percentages, with available security types disclosed when a filter matches nothing; the series preview holds at most 20 rows.
  • Series staging starts above 200 rows or on request via canvas_id.

treasury_get_exchange_rates tool

  • Quarterly official reporting rates in foreign currency units per 1 USD. Filter countries by exact name; mode=latest returns one current row per currency and mode=series accepts a date range.
  • Each row carries record_date and effective_date; mixed_record_dates flags a result spanning quarters. Series previews hold 20 rows; retrieved_records discloses progress against total_records.
  • Series staging starts above 500 rows or on request via canvas_id; paging stops at 50,000 rows.
  • country_not_found error when a requested country has no records

treasury_dataframe_describe tool

  • Omit name to list the tenant's active dataframes, or supply one exact table name.
  • Returns provenance, created/expiry timestamps, row count, and column schema; truncated / max_rows disclose a capped source pull.
  • Table expiry defaults to 24h after staging, configurable with CANVAS_TTL_MS.

treasury_dataframe_query tool

  • Accepts one read-only SELECT; row_limit defaults to 1000 (max 10000) and preview may not exceed it. System catalogs, external-file functions, and SQL mutations are denied.
  • Returns rows and row_count_capped; errors distinguish canvas_unavailable, system_catalog_access, invalid_sql, missing_table, and invalid_query_bounds.
  • register_as materializes the full result as a new dataframe with a fresh TTL.

treasury_dataframe_drop tool

  • Accepts the exact name from treasury_dataframe_describe, a data tool's canvas_id, or query's registered_as; deletes that table and its provenance for the tenant.
  • Returns name and dropped: true; an absent or expired table returns missing_table with guidance to list active tables.
  • Disabled by default. Set TREASURY_DATAFRAME_DROP_ENABLED=true and CANVAS_PROVIDER_TYPE=duckdb to make it callable; the HTTP landing page shows the disabled tool and enable hint otherwise.

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.

Fiscal Data-specific:

  • All API values are strings; "null" means no value. Treasury dataframe columns are VARCHAR — CAST to DECIMAL or DATE for arithmetic and date comparisons. DataCanvas requires CANVAS_PROVIDER_TYPE=duckdb; configured canvas tools report canvas_unavailable otherwise.
  • Curated catalog of 17 endpoints with field metadata — no discovery round-trip required; pass any endpoint path directly to treasury_query_dataset for datasets outside the catalog
  • Convenience tools for the three most-queried datasets — national debt, interest rates, exchange rates
  • DataCanvas integration: large pulls register as df_<id> dataframes queryable via DuckDB SQL, with automatic staging thresholds per tool
  • No API key required — the US Treasury Fiscal Data API is free and public

Agent-friendly output:

  • Provenance: filter-expression echo (applied_filters) and field-label maps (field_labels) let agents verify what was sent and read raw field names
  • Enrichment notices: empty-result guidance, partial-country mismatches, canvas staging confirmations, and truncated-series warnings all name the next tool call
  • Graceful truncation: series and query results carry truncated / retrieved_records / row_count_capped fields instead of silently dropping rows
  • Canvas provenance: source tool, original query parameters, row count, and column schema surfaced by treasury_dataframe_describe

Getting started

Public Hosted Instance

A public instance is available at https://treasury-fiscaldata.caseyjhand.com/mcp — no installation required. It serves Streamable HTTP; each client takes its own config shape.

For Claude Code:

sh
claude mcp add --transport http treasury-fiscaldata-mcp-server https://treasury-fiscaldata.caseyjhand.com/mcp

For Cline (cline_mcp_settings.json):

json
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "type": "streamableHttp",
      "url": "https://treasury-fiscaldata.caseyjhand.com/mcp"
    }
  }
}

For Cursor (mcp.json):

json
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "url": "https://treasury-fiscaldata.caseyjhand.com/mcp"
    }
  }
}

Claude Desktop adds remote servers under Settings → Connectors.

The Claude Desktop .mcpb download supports Treasury API queries with DataCanvas disabled. Its portable bundle omits DuckDB's platform-specific native bindings. Use the hosted endpoint, npm, or Docker for dataframe staging and SQL.

Self-Hosted / Local

Add the following to your MCP client configuration file.

json
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/treasury-fiscaldata-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with npx (no Bun required):

json
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/treasury-fiscaldata-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with Docker:

json
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "ghcr.io/cyanheads/treasury-fiscaldata-mcp-server:latest"
      ]
    }
  }
}

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

DataCanvas SQL workflow

For large time-series pulls or multi-dataset analysis, use the DataCanvas SQL workflow:

  1. Use the hosted endpoint, npm, or Docker. DataCanvas is enabled by default; CANVAS_PROVIDER_TYPE=none disables it. The desktop .mcpb bundle does not include DataCanvas.
  2. Call a data tool with a canvas_id — e.g., treasury_get_debt with mode=series and a canvas_id value, or treasury_query_dataset with canvas_id. The tool registers the results as a df_XXXXX_XXXXX dataframe and returns the table name.
  3. Inspect the schema with treasury_dataframe_describe — lists column names, types (all VARCHAR for Treasury data), row count, and TTL.
  4. Query with SQL via treasury_dataframe_query — standard DuckDB SELECT with joins, aggregates, window functions, and CTEs. CAST VARCHAR columns to DECIMAL or DATE for arithmetic.
sql
-- Example: debt trend over the last year, month-end records only
SELECT
  record_date,
  CAST(tot_pub_debt_out_amt AS DECIMAL) / 1e12 AS total_debt_trillions
FROM df_xxxxx
WHERE CAST(record_date AS DATE) >= CURRENT_DATE - INTERVAL 1 YEAR
ORDER BY record_date DESC

Prerequisites

  • Bun v1.4.0 or higher (or Node.js v24+).
  • No API key required — the US Treasury Fiscal Data API is free and public.
  • DataCanvas SQL is enabled by default in npm and Docker installs, which include @duckdb/node-api and its native bindings. The portable desktop .mcpb bundle disables it.

Installation

  1. Clone the repository:
sh
git clone https://github.com/cyanheads/treasury-fiscaldata-mcp-server.git
  1. Navigate into the directory:
sh
cd treasury-fiscaldata-mcp-server
  1. Install dependencies:
sh
bun install
  1. Configure environment:
sh
cp .env.example .env
# edit .env as needed — no required vars; CANVAS_PROVIDER_TYPE=none disables SQL

Configuration

VariableDescriptionDefault
CANVAS_PROVIDER_TYPEduckdb backs dataframe describe/query, and drop when enabled. With none, callable canvas tools return canvas_unavailable; drop stays off the tool list unless separately enabled.duckdb (none in the desktop bundle)
CANVAS_TTL_MSPer-table TTL for DataCanvas dataframes in milliseconds.86400000 (24h)
TREASURY_DATAFRAME_DROP_ENABLEDRegister treasury_dataframe_drop as callable. Also requires CANVAS_PROVIDER_TYPE=duckdb.false
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_SESSION_MODEHTTP session handling: auto, stateful, or stateless. Setting it overrides the server's own declaration; leaving it unset falls through to that declaration, not to the schema default.stateless (declared in src/index.ts)
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, notice, warning, error).info
LOGS_DIRDirectory for log files (Node.js/Bun only).<project-root>/logs
LOG_TOOL_FAILURE_PAYLOADSLog failed-call arguments and results, redacted by key name. Secrets inside free-form values are not redacted.false
LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTESByte cap for each logged failed-call payload.16384
OTEL_ENABLEDEnable OpenTelemetry spans and metrics.false
OTEL_EXPORTER_OTLP_ENDPOINTBase OTLP endpoint for traces and metrics.Unset
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTExplicit OTLP log endpoint; the base endpoint does not enable log export.Unset

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
    bun run lint:deps        # Detect unused and missing dependencies with Knip
    bun run verify:catalog   # Probe every catalog endpoint and field against the live API
    

    verify:catalog makes live Fiscal Data requests and runs separately from devcheck and the test suite. Run it after editing src/services/fiscal-data/datasets.ts and before a release.

    Builds type-check and emit declarations with TypeScript, then use Bun to bundle server code as Node-compatible ESM in dist/index.js. Package dependencies remain external, including the framework and DuckDB native bindings. The installed server runs on Node or Bun; building from source requires Bun. Dependency checks use knip.jsonc to cover source, scripts, and tests.

Docker

sh
docker build -t treasury-fiscaldata-mcp-server .
docker run --rm -e CANVAS_PROVIDER_TYPE=duckdb -p 3010:3010 treasury-fiscaldata-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/treasury-fiscaldata-mcp-server. A native build-host dependency stage cross-installs DuckDB bindings for the target architecture, preserves the release-age and security checks, and removes unused musl bindings. OpenTelemetry peers are installed at the framework's declared ranges — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and inits services.
src/config/Server-specific environment variable parsing and validation with Zod.
src/mcp-server/tools/definitions/Tool definitions (*.tool.ts) — 5 data tools + 3 DataCanvas tools, including opt-in drop.
src/services/fiscal-data/Treasury Fiscal Data API client, embedded endpoint catalog, and types.
src/services/canvas-bridge/Adapter over the framework DataCanvas: df_<id> minting, per-table TTL, system-catalog SQL deny.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md and 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
  • All Treasury API values are strings — validate and CAST in downstream SQL; never fabricate missing fields
  • Register new tools via the arrays in src/index.ts

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 Government open data