@cyanheads/treasury-fiscaldata-mcp-server
Provides SQL analytics over DuckDB-backed DataCanvas dataframes materialized from Treasury Fiscal Data queries.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/treasury-fiscaldata-mcp-serverWhat is the current national debt?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://treasury-fiscaldata.caseyjhand.com/mcp
Overview
US Treasury Fiscal Data — national debt, interest rates, exchange rates, and other fiscal datasets. Browse a curated catalog of 17 endpoints, query any endpoint directly, or stage large pulls as DuckDB dataframes for SQL analysis, from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Browse the curated catalog of 17 Treasury Fiscal Data endpoints with field names, descriptions, and update cadence |
| Query any Treasury Fiscal Data endpoint by path, field list, filters, sort, and page — with optional DataCanvas spill |
| Fetch national debt (Debt to the Penny) — latest record, specific date, or date-range series with optional DataCanvas spill |
| Average interest rates Treasury pays on outstanding securities by type — marketable issues, non-marketable series, and aggregate totals |
| Official Treasury statutory exchange rates for ~165 countries, published quarterly |
| List DataCanvas dataframes materialized by the treasury_* tools with schema, row count, and TTL |
| Run a single-statement SELECT against DataCanvas dataframes using standard DuckDB SQL |
Related MCP server: @cyanheads/eia-energy-mcp-server
Capability reference
treasury_list_datasets tool
Filter by category:
debt,interest_rates,exchange_rates,revenue_spending,savings_bonds,securities,otherKeyword search against dataset name and description (case-insensitive substring)
No network calls — serves from a static catalog bundled with the server
Returns endpoint paths, field names, types, and update cadence
Every path and field name is checked against the live API by
bun run verify:catalog, so a dataset Treasury moves or renames fails a gate rather than reaching a caller
treasury_query_dataset tool
Filter syntax:
{ field, operator, value }with operatoreq,gt,gte,lt,lte,in; multiple filters ANDed togetherPagination via
page_size(1–10000, default 100) andpage_number; sort any field, descending with a-prefixAll response values are strings per the API contract — including numeric and date fields;
"null"means no valueTyped error reasons:
invalid_endpoint,invalid_field,invalid_filter,page_out_of_rangecanvas_idstages the page as a DataCanvas table (df_XXXXX_XXXXX) — read its schema withtreasury_dataframe_describe, then SQL it withtreasury_dataframe_query(requiresCANVAS_PROVIDER_TYPE=duckdb)
treasury_get_debt tool
mode=latest— most recent business-day record;mode=date— a specific business day (YYYY-MM-DD; the API only records debt on market-open days);mode=series— a date range, newest-firstRecords go back to 1993-04-01
mode=seriesauto-stages to a DataCanvas table when the range exceeds 500 rows, or on request viacanvas_id; paging stops at 50,000 rows, with the response naming how many of the match were retrievedSeries rows returned inline are capped at 20, newest first — the full retrieved set is reachable via
canvas_idno_data_for_dateerror when no record exists for a requested date
treasury_get_interest_rates tool
mode=latest— most recent month's rates for all or one security type;mode=series— a time-range historyCovers every security type Treasury reports — marketable issues, non-marketable series, and aggregate totals; which types are published changes over time, so a
security_typefilter that matches nothing gets back the types the most recent month actually holdsRates are percentages (e.g.
"3.696"), not basis pointsmode=seriesauto-stages to DataCanvas when results exceed 200 rows, or on request viacanvas_id; inline series preview is capped at 20 rows, newest first
treasury_get_exchange_rates tool
Rate is foreign currency units per 1 USD (a Japan-Yen rate of 159.41 means 1 USD = 159.41 JPY) — official statutory reporting rates, not market rates
Published quarterly (Mar 31, Jun 30, Sep 30, Dec 31); filter to one or more countries by exact name, or omit for all ~165
mode=latestcollapses to one row per currency — newestrecord_date, then newesteffective_date— so an amendment supersedes the rate it replaced and a country with two legal tenders keeps both;mixed_record_datesflags a result whose rows span more than one quartermode=seriesauto-stages to DataCanvas when results exceed 500 rows; full published history is ~19,000 rows back to 2001-03-31, well within the 50,000-row paging capcountry_not_founderror when a requested country has no records
treasury_dataframe_describe tool
Lists every active DataCanvas dataframe for the tenant, or one by name — source tool, query params, created/expiry timestamps, row count, and column schema
Requires
CANVAS_PROVIDER_TYPE=duckdb;canvas_unavailableerror otherwiseColumns show name, DuckDB type, and nullability — all Treasury columns are VARCHAR
truncated/max_rowsflag when the source pull was capped before full materializationPer-table TTL is sliding, touched on every dataframe op — default 24h, override with
CANVAS_TTL_MS
treasury_dataframe_query tool
Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected; system catalogs (
information_schema,pg_catalog,sqlite_master,duckdb_*) are deniedAll Treasury dataframe columns are VARCHAR — CAST to
DECIMALorDATEfor arithmetic and date comparisonsrow_limitcaps rows produced (default 1000, max 10000);previewbounds the inline response and may not exceedrow_limitregister_aspersists the result as a new dataframe with a fresh TTL, for chained multi-step analysisTyped error reasons:
canvas_unavailable,system_catalog_access,invalid_sql,missing_table,invalid_query_bounds
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:
Curated catalog of 17 endpoints with field metadata — no discovery round-trip required; pass any endpoint path directly to
treasury_query_datasetfor datasets outside the catalogConvenience 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 toolNo 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 namesEnrichment 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_cappedfields instead of silently dropping rowsCanvas 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. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"treasury-fiscaldata-mcp-server": {
"type": "streamable-http",
"url": "https://treasury-fiscaldata.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
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/mcpDataCanvas 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 DESCPrerequisites
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.gitNavigate into the directory:
cd treasury-fiscaldata-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env as needed — no required vars; CANVAS_PROVIDER_TYPE=duckdb to enable SQLConfiguration
Variable | Description | Default |
| Canvas engine. Unset resolves to |
|
| Per-table TTL for DataCanvas dataframes in milliseconds. |
|
| Transport: |
|
| Port for HTTP server. |
|
| HTTP session handling: |
|
| Auth mode: |
|
| Log level ( |
|
| Directory for log files (Node.js/Bun only). |
|
| Enable OpenTelemetry spans and metrics. |
|
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:httpRun 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 bun run verify:catalog # Probe every catalog endpoint and field against the live APIverify:catalogis the one check that needs the network, which is why it is separate fromdevcheckand the test suite. Run it after editingsrc/services/fiscal-data/datasets.tsand before a release.
Docker
docker build -t treasury-fiscaldata-mcp-server .
docker run --rm -e CANVAS_PROVIDER_TYPE=duckdb -p 3010:3010 treasury-fiscaldata-mcp-serverThe 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 |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Treasury Fiscal Data API client, embedded endpoint catalog, and types. |
| Adapter over the framework DataCanvas: |
| Unit and integration tests mirroring |
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 logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageAll 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:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.
Treasury MCP — US Treasury Fiscal Data public API (free, no auth)
Treasury Fiscal MCP — US Treasury Fiscal Data API
Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceAccess FEC campaign finance data through MCP. Query data about candidates, money trails, and election filings. STDIO & Streamable HTTP.552 npm2Apache 2.0
- AlicenseNot gradedqualityAmaintenanceBrowse and query the U.S. Energy Information Administration API v2 — electricity, petroleum, natural gas, coal, forecasts, and more via MCP. STDIO or Streamable HTTP.258 npm2Apache 2.0
- AlicenseNot gradedqualityAmaintenanceSearch and fetch ~800K Federal Reserve economic time-series from the FRED API via MCP, with STDIO or Streamable HTTP transport.297 npm1Apache 2.0
- AlicenseNot gradedqualityAmaintenanceQuery FEMA disaster declarations, public assistance grants, housing aid, and NFIP flood insurance claims via MCP. Supports STDIO and Streamable HTTP.535 npm1Apache 2.0