The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Treasury Fiscaldata MCP Server listing page.
Query US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP.
Public Hosted Server: https://treasury-fiscaldata.caseyjhand.com/mcp
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 curated catalog of 17 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 — marketable issues, non-marketable series, and aggregate totals |
treasury_get_exchange_rates | Official Treasury statutory exchange rates for ~165 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_datasetsBrowse the embedded catalog of available Treasury Fiscal Data endpoints. No network calls — serves from a static catalog bundled with the server.
debt, interest_rates, exchange_rates, revenue_spending, savings_bonds, securities, othertreasury_query_datasetbun run verify:catalog, so a dataset Treasury moves or renames fails a gate rather than reaching a callertreasury_query_datasetGeneric parameterized query against any Treasury Fiscal Data endpoint.
{ field, operator, value } where operator is eq, gt, gte, lt, lte, inpage_size (1–10000) and page_number- prefix (e.g. -record_date)"null" means no valuecanvas_id to stage the page as a DataCanvas table — the server assigns the name and returns it in canvas_id; read its schema with treasury_dataframe_describe, then SQL it with treasury_dataframe_query (requires CANVAS_PROVIDER_TYPE=duckdb)treasury_get_debtConvenience 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 rowstreasury_get_interest_ratesAverage interest rates the Treasury pays on outstanding securities. Updated monthly (end-of-month records).
security_type takes any security_desc value the data carries, matched exactly; which types Treasury publishes changes over the years, so when a filter matches nothing the response names the types the data does holdmode=latest — most recent month's rates for all or one security typemode=series — time-range history; auto-spills to DataCanvas when results exceed 200 rowstreasury_get_exchange_ratesOfficial Treasury statutory reporting exchange rates for ~165 countries, published quarterly (March 31, June 30, Sep 30, Dec 31).
mode=latest returns one row per currency — the operative rate, newest record_date and then newest effective_date, so an amended rate supersedes the one it replaced and a country holding two legal tenders keeps bothrecord_date with a later effective_date, so both dates ride every row; mixed_record_dates flags a result whose rows are not all from one quartermode=series auto-spills to DataCanvas when results exceed 500 rows (~19,000 rows full history, back to 2001-03-31)treasury_dataframe_describe / treasury_dataframe_queryIn-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; read its columns with treasury_dataframe_describe, then pass the handle to treasury_dataframe_query for joins, aggregates, window functions, and CTEs — standard DuckDB SQL.
information_schema, pg_catalog, sqlite_master, duckdb_*) are denied at the bridge layer.DECIMAL or DATE for arithmetic and date comparisons.register_as chaining. treasury_dataframe_query can persist its result as a new dataframe with a fresh TTL for multi-step analysis.CANVAS_TTL_MS).CANVAS_PROVIDER_TYPE=duckdb.Built on @cyanheads/mcp-ts-core:
none, jwt, oauthTreasury-specific:
treasury_query_dataset to access datasets not in the catalog.treasury_query_datasetdf_<id> dataframes queryable via DuckDB SQLAgent-friendly output:
applied_filters) so agents can verify what was sent to the APIfield_labels) map raw field names to human-readable labelstreasury_dataframe_describeA public instance is available at https://treasury-fiscaldata.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
Add the following to your MCP client configuration file.
Or with npx (no Bun required):
Or with Docker:
For Streamable HTTP, set the transport and start the server:
For large time-series pulls or multi-dataset analysis, use the DataCanvas SQL workflow:
CANVAS_PROVIDER_TYPE=duckdb in your server environment.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.treasury_dataframe_describe — lists column names, types (all VARCHAR for Treasury data), row count, and TTL.treasury_dataframe_query — standard DuckDB SELECT with joins, aggregates, window functions, and CTEs. CAST VARCHAR columns to DECIMAL or DATE for arithmetic.CANVAS_PROVIDER_TYPE=duckdb (DuckDB is bundled as @duckdb/node-api).| Variable | Description | Default |
|---|---|---|
CANVAS_PROVIDER_TYPE | Canvas engine. Unset resolves to none, and the treasury_dataframe_* tools then reject every call — set it to duckdb to enable DataCanvas SQL. | none |
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_SESSION_MODE | HTTP session handling: auto, stateful, or stateless. .env.example ships stateless. | auto (resolves to stateful) |
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.
Build and run:
Run checks and tests:
verify:catalog is the one check that needs the network, which is why it is separate from devcheck and the test suite. Run it after editing src/services/fiscal-data/datasets.ts and before a release.
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.
| 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/. |
See CLAUDE.md and AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/index.tsIssues and pull requests are welcome. Run checks and tests before submitting:
Apache-2.0 — see LICENSE for details.