MCP server for US Treasury Fiscal Data — national debt, interest rates, exchange rates, and federal revenue/spending.
@cyanheads/treasury-fiscaldata-mcp-server
Query US Treasury national debt, interest rates, exchange rates, and 80+ fiscal datasets via MCP. STDIO or Streamable HTTP.
Tools
Five tools for querying the US Treasury Fiscal Data API, plus two for SQL analytics over DuckDB-backed DataCanvas dataframes:
| Tool | Description |
|:-----|:------------|
| treasury_list_datasets | Browse the catalog of 80+ Treasury Fiscal Data endpoints with field names, descriptions, and update cadence |
| treasury_query_dataset | Query any Treasury Fiscal Data endpoint by path, field list, filters, sort, and page — with optional DataCanvas spill |
| treasury_get_debt | Fetch national debt (Debt to the Penny) — latest record, specific date, or date-range series with optional DataCanvas spill |
| treasury_get_interest_rates | Average interest rates Treasury pays on outstanding securities by type (Bills, Notes, Bonds, TIPS, FRN) |
| treasury_get_exchange_rates | Official Treasury statutory exchange rates for ~130 countries, published quarterly |
| treasury_dataframe_describe | List DataCanvas dataframes materialized by the treasury_* tools with schema, row count, and TTL |
| treasury_dataframe_query | Run a single-statement SELECT against DataCanvas dataframes using standard DuckDB SQL |
treasury_list_datasets
Browse the embedded catalog of available Treasury Fiscal Data endpoints. No network calls — serves from a static catalog bundled with the server.
- Filter by category:
debt,interest_rates,exchange_rates,revenue_spending,savings_bonds,securities,other - Keyword search against dataset name and description (case-insensitive substring)
- Returns endpoint paths, field names, types, and update cadence
- Use this first to get the exact endpoint path and field names before calling
treasury_query_dataset
treasury_query_dataset
Generic parameterized query against any Treasury Fiscal Data endpoint.
- Filter syntax:
{ field, operator, value }where operator iseq,gt,gte,lt,lte,in - Multiple filters ANDed together
- Pagination via
page_size(1–10000) andpage_number - Sort by any field, descending with
-prefix (e.g.-record_date) - All response values are strings per the API contract — including numeric and date fields;
"null"means no value - Pass
canvas_idto register results into a named DataCanvas dataframe for SQL viatreasury_dataframe_query(requiresCANVAS_PROVIDER_TYPE=duckdb)
treasury_get_debt
Convenience tool for national debt (Debt to the Penny) — total public debt outstanding broken into publicly-held debt and intragovernmental holdings.
mode=latest— most recent business-day recordmode=date— specific business day (YYYY-MM-DD; API only records debt on market-open days)mode=series— date range, sorted newest-first; auto-spills to DataCanvas when the series exceeds 500 rows- Records go back to 1993-01-04
treasury_get_interest_rates
Average interest rates the Treasury pays on outstanding securities. Updated monthly (end-of-month records).
- Covers Bills, Notes, Bonds, TIPS, Floating Rate Notes (FRN), and aggregate marketable/non-marketable totals
mode=latest— most recent month's rates for all or one security typemode=series— time-range history; auto-spills to DataCanvas when results exceed 200 rows
treasury_get_exchange_rates
Official Treasury statutory reporting exchange rates for ~130 countries, published quarterly (March 31, June 30, Sep 30, Dec 31).
- Rate expressed as foreign currency units per 1 USD (e.g. Japan-Yen 159.41 means 1 USD = 159.41 JPY)
- These are not market exchange rates — required by US federal agencies for foreign-currency-to-USD conversions in official reporting
- Filter to one or more countries by exact name; omit for all ~130 countries in a quarter
mode=seriesauto-spills to DataCanvas when results exceed 500 rows (~18,800 rows full history)
treasury_dataframe_describe / treasury_dataframe_query
In-conversation SQL analytics over the dataframes that treasury_query_dataset, treasury_get_debt, treasury_get_interest_rates, and treasury_get_exchange_rates materialize on a shared DuckDB-backed DataCanvas. Each data-returning call with canvas_id adds a df_XXXXX_XXXXX handle; pass that handle to treasury_dataframe_query for joins, aggregates, window functions, and CTEs — standard DuckDB SQL.
- Read-only. Writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected by the SQL gate. System catalogs (
information_schema,pg_catalog,sqlite_master,duckdb_*) are denied at the bridge layer. - All Treasury columns are VARCHAR. CAST to
DECIMALorDATEfor arithmetic and date comparisons. register_aschaining.treasury_dataframe_querycan persist its result as a new dataframe with a fresh TTL for multi-step analysis.- Per-table TTL. Dataframes age on their own clock (default 24h, override with
CANVAS_TTL_MS). - Requires
CANVAS_PROVIDER_TYPE=duckdb.
Features
Built on @cyanheads/mcp-ts-core:
- Declarative tool definitions — single file per tool, framework handles registration and validation
- Structured output schemas with automatic formatting for human-readable display
- Unified error handling — handlers throw, framework catches, classifies, and formats
- Pluggable auth:
none,jwt,oauth - Structured logging with request-scoped context
- STDIO and Streamable HTTP transports
Treasury-specific:
- Embedded catalog of 80+ Treasury Fiscal Data endpoints with field metadata — no discovery round-trip required
- Convenience tools for the three most-queried datasets (national debt, interest rates, exchange rates)
- Full generic access to any Fiscal Data endpoint via
treasury_query_dataset - DataCanvas integration: large time-series pulls register as
df_<id>dataframes queryable via DuckDB SQL - No API keys required — the US Treasury Fiscal Data API is free and public
Agent-friendly output:
- Filter expression echo (
applied_filters) so agents can verify what was sent to the API - Field-label maps on query results (
field_labels) map raw field names to human-readable labels - Enrichment notices on empty results and partial-country mismatches guide the next tool call
- Canvas provenance: source tool, original query parameters, row count, and column schema surfaced by
treasury_dataframe_describe
Getting started
Add the following to your MCP client configuration file.
{
"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):
{
"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:
{
"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:
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:
- Set
CANVAS_PROVIDER_TYPE=duckdbin your server environment. - Call a data tool with a
canvas_id— e.g.,treasury_get_debtwithmode=seriesand acanvas_idvalue, ortreasury_query_datasetwithcanvas_id. The tool registers the results as adf_XXXXX_XXXXXdataframe and returns the table name. - Inspect the schema with
treasury_dataframe_describe— lists column names, types (all VARCHAR for Treasury data), row count, and TTL. - 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.
-- 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.3.0 or higher (or Node.js v24+).
- No API key required — the US Treasury Fiscal Data API is free and public.
- For DataCanvas SQL:
CANVAS_PROVIDER_TYPE=duckdb(DuckDB is bundled as@duckdb/node-api).
Installation
- Clone the repository:
git clone https://github.com/cyanheads/treasury-fiscaldata-mcp-server.git
- Navigate into the directory:
cd treasury-fiscaldata-mcp-server
- Install dependencies:
bun install
- Configure environment:
cp .env.example .env
# edit .env as needed — no required vars; CANVAS_PROVIDER_TYPE=duckdb to enable SQL
Configuration
| Variable | Description | Default |
|:---------|:------------|:--------|
| CANVAS_PROVIDER_TYPE | Canvas engine. Set to duckdb to enable DataCanvas SQL via treasury_dataframe_* tools. Set to none to disable (e.g. on Cloudflare Workers). | duckdb |
| CANVAS_TTL_MS | Per-table TTL for DataCanvas dataframes in milliseconds. | 86400000 (24h) |
| MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
| MCP_HTTP_PORT | Port for HTTP server. | 3010 |
| MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
| MCP_LOG_LEVEL | Log level (debug, info, notice, warning, error). | info |
| LOGS_DIR | Directory for log files (Node.js/Bun only). | <project-root>/logs |
| OTEL_ENABLED | Enable OpenTelemetry spans and metrics. | false |
See .env.example for the full list of optional overrides.
Running the server
Local development
-
Build and run:
bun run rebuild bun run start:stdio # or bun run start:http -
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
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. DuckDB native modules are pre-built in the build stage and copied to the production stage — no extra build tools required at runtime. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
| Directory | Purpose |
|:----------|:--------|
| src/index.ts | createApp() 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 + 2 DataCanvas tools. |
| 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/catchin tool logic - Use
ctx.logfor request-scoped logging,ctx.statefor 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 and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
License
Apache-2.0 — see LICENSE for details.