@cyanheads/treasury-fiscaldata-mcp-server

v0.1.1 pre-1.0

MCP server for US Treasury Fiscal Data — national debt, interest rates, exchange rates, and federal revenue/spending.

@cyanheads/treasury-fiscaldata-mcp-server
claude mcp add --transport http treasury-fiscaldata-mcp-server https://treasury-fiscaldata.caseyjhand.com/mcp
codex mcp add treasury-fiscaldata-mcp-server --url https://treasury-fiscaldata.caseyjhand.com/mcp
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "url": "https://treasury-fiscaldata.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http treasury-fiscaldata-mcp-server https://treasury-fiscaldata.caseyjhand.com/mcp
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "command": "bunx",
      "args": [
        "@cyanheads/treasury-fiscaldata-mcp-server@latest"
      ]
    }
  }
}
{
  "mcpServers": {
    "treasury-fiscaldata-mcp-server": {
      "type": "http",
      "url": "https://treasury-fiscaldata.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://treasury-fiscaldata.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

7

treasury_list_datasets

Browse the catalog of available US Treasury Fiscal Data API endpoints. Returns endpoint paths, field names, descriptions, and update cadence for each dataset. Use this tool before treasury_query_dataset to discover the correct endpoint path and field names — a typo in either causes a 400 error from the API. The catalog covers debt, interest rates, exchange rates, revenue/spending, savings bonds, and securities datasets.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_list_datasets",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "category": {
      "description": "Filter by category. Omit to list all datasets. Options: debt, interest_rates, exchange_rates, revenue_spending, savings_bonds, securities, other.",
      "type": "string",
      "enum": [
        "debt",
        "interest_rates",
        "exchange_rates",
        "revenue_spending",
        "savings_bonds",
        "securities",
        "other"
      ]
    },
    "search": {
      "description": "Keyword filter against dataset name and description (case-insensitive substring match). Useful for narrowing 80+ datasets when the category is uncertain.",
      "type": "string"
    }
  },
  "additionalProperties": false
}
view source ↗

treasury_query_dataset

Query any Treasury Fiscal Data endpoint by path, field list, filters, sort, and page. Call treasury_list_datasets first to get the correct endpoint path and exact field names — a typo in either causes a 400. Filter syntax: each condition is { field, operator, value } where operator is eq/gt/gte/lt/lte/in (e.g., record_date:gte:2024-01-01). Multiple conditions are ANDed together. All response values are strings per the API contract, including numbers and dates; "null" (string) means no value. Supply canvas_id to register the page result into a named DataCanvas dataframe and query it later with treasury_dataframe_query (requires CANVAS_PROVIDER_TYPE=duckdb on the server).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_query_dataset",
    "arguments": {
      "endpoint": "<endpoint>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "endpoint": {
      "type": "string",
      "description": "Endpoint path returned by treasury_list_datasets (e.g., \"/v2/accounting/od/debt_to_penny\"). Include the leading slash."
    },
    "fields": {
      "description": "Fields to return. Omit to return all fields. Specify field names exactly as listed by treasury_list_datasets — a typo causes a 400.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "filters": {
      "description": "Filter conditions (ANDed together). Multiple filters on different fields are combined in one filter= parameter.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "description": "Field name to filter on."
          },
          "operator": {
            "type": "string",
            "enum": [
              "eq",
              "gt",
              "gte",
              "lt",
              "lte",
              "in"
            ],
            "description": "Comparison operator. \"in\" matches any value in the provided list."
          },
          "value": {
            "anyOf": [
              {
                "type": "string",
                "description": "Single filter value. Dates use YYYY-MM-DD format."
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "List of values for \"in\" operator."
              }
            ],
            "description": "Filter value. For \"in\", pass an array of strings. Dates use YYYY-MM-DD format."
          }
        },
        "required": [
          "field",
          "operator",
          "value"
        ],
        "additionalProperties": false,
        "description": "One filter condition."
      }
    },
    "sort": {
      "description": "Sort expression: field name optionally prefixed with \"-\" for descending (e.g., \"-record_date\" for newest-first).",
      "type": "string"
    },
    "page_size": {
      "default": 100,
      "description": "Rows per page. Default 100. Raise to 10000 to minimize round trips for small datasets. For large time-series pulls, use canvas_id with treasury_dataframe_query instead.",
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    },
    "page_number": {
      "default": 1,
      "description": "Page to fetch (1-indexed). Check total_pages in the response to know if more pages exist.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "canvas_id": {
      "description": "DataCanvas ID to spill results into for SQL analysis. Omit to receive results inline. Requires CANVAS_PROVIDER_TYPE=duckdb on the server. When provided, the full page result is registered as a dataframe and a canvas_id is returned for use with treasury_dataframe_query.",
      "type": "string"
    }
  },
  "required": [
    "endpoint",
    "page_size",
    "page_number"
  ],
  "additionalProperties": false
}
view source ↗

treasury_get_debt

Fetch national debt (Debt to the Penny) — total public debt outstanding broken into publicly-held debt and intragovernmental holdings. Three modes: "latest" returns the most recent business day's record; "date" returns the record for a specific date (must be a business day — the API only records debt on days markets are open); "series" returns a date range and optionally spills results to DataCanvas for SQL analysis via treasury_dataframe_query. Records go back to 1993-01-04. As of 2026-05-28 the total debt is approximately $39.18T.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_get_debt",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "mode": {
      "default": "latest",
      "description": "\"latest\" returns the most recent day's record. \"date\" returns the record for a specific date. \"series\" returns a date range — use with start_date and end_date.",
      "type": "string",
      "enum": [
        "latest",
        "date",
        "series"
      ]
    },
    "date": {
      "description": "ISO 8601 date (YYYY-MM-DD) for mode=date. Must be a business day; the API only records debt on days the market is open.",
      "type": "string"
    },
    "start_date": {
      "description": "ISO 8601 start date for mode=series (inclusive). Fiscal Data has daily debt records back to 1993-01-04.",
      "type": "string"
    },
    "end_date": {
      "description": "ISO 8601 end date for mode=series (inclusive). Defaults to today.",
      "type": "string"
    },
    "canvas_id": {
      "description": "DataCanvas table name (df_XXXXX_XXXXX) to register series results into for SQL analysis. When provided, or when the series exceeds 500 rows, the full result is registered and the name is returned in canvas_id. Use treasury_dataframe_query to run SQL against it. Requires CANVAS_PROVIDER_TYPE=duckdb.",
      "type": "string"
    }
  },
  "required": [
    "mode"
  ],
  "additionalProperties": false
}
view source ↗

treasury_get_interest_rates

Average interest rates Treasury pays on its outstanding securities by security type. Answers "what is the government's cost of borrowing?" Covers Bills, Notes, Bonds, TIPS, Floating Rate Notes, and aggregate marketable/non-marketable totals. Updated monthly (end-of-month records). Mode "latest" returns the most recent month's rates for all or one security type; "series" returns a time history. As of 2026-04-30: Bills 3.696%, Notes 3.230%, Bonds 3.403%, TIPS 1.068%, FRN 3.764%, Total Interest-bearing Debt 3.340%.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_get_interest_rates",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "mode": {
      "default": "latest",
      "description": "\"latest\" returns the most recent month's rates. \"series\" returns a time range.",
      "type": "string",
      "enum": [
        "latest",
        "series"
      ]
    },
    "security_type": {
      "description": "Filter to one security type. Omit for all types. Use the exact string — the API does exact-match filtering on security_desc.",
      "type": "string",
      "enum": [
        "Treasury Bills",
        "Treasury Notes",
        "Treasury Bonds",
        "Treasury Inflation-Protected Securities (TIPS)",
        "Treasury Floating Rate Notes (FRN)",
        "Total Marketable",
        "Total Non-marketable",
        "Total Interest-bearing Debt"
      ]
    },
    "start_date": {
      "description": "ISO 8601 start date for mode=series (YYYY-MM-DD, must be end-of-month for meaningful results).",
      "type": "string"
    },
    "end_date": {
      "description": "ISO 8601 end date for mode=series. Defaults to today.",
      "type": "string"
    },
    "canvas_id": {
      "description": "DataCanvas table name (df_XXXXX_XXXXX) to register series results into for SQL analysis. When provided, or when mode=series and results exceed 200 rows, the result is registered and canvas_id is returned. Use treasury_dataframe_query to query it. Requires CANVAS_PROVIDER_TYPE=duckdb.",
      "type": "string"
    }
  },
  "required": [
    "mode"
  ],
  "additionalProperties": false
}
view source ↗

treasury_get_exchange_rates

Official Treasury reporting exchange rates for ~130 countries — the rates US federal agencies are required to use when converting foreign currency to USD for official reporting. Published quarterly (March 31, June 30, Sep 30, Dec 31). Rate is 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 and are not suitable for financial transaction pricing. The latest quarter available is 2026-03-31 (Q1 2026).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_get_exchange_rates",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "mode": {
      "default": "latest",
      "description": "\"latest\" returns the most recently published quarter's rates. \"series\" returns a date range of quarterly reports.",
      "type": "string",
      "enum": [
        "latest",
        "series"
      ]
    },
    "countries": {
      "description": "Filter to specific countries by exact country name (e.g., [\"Japan\", \"Germany\", \"France\"]). Case-sensitive, matches the \"country\" field. Omit for all ~130 countries in the quarter.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "start_date": {
      "description": "ISO 8601 start date for mode=series. Rates are published end-of-quarter (March 31, June 30, Sep 30, Dec 31).",
      "type": "string"
    },
    "end_date": {
      "description": "ISO 8601 end date for mode=series.",
      "type": "string"
    },
    "canvas_id": {
      "description": "DataCanvas table name (df_XXXXX_XXXXX) to register series results into for SQL analysis. Useful when pulling multi-year history for many countries (~18,800 rows total). When provided, or when mode=series and results exceed 500 rows, the result is registered and canvas_id is returned. Use treasury_dataframe_query to query it. Requires CANVAS_PROVIDER_TYPE=duckdb.",
      "type": "string"
    }
  },
  "required": [
    "mode"
  ],
  "additionalProperties": false
}
view source ↗

treasury_dataframe_describe

List DataCanvas dataframes materialized by treasury_query_dataset, treasury_get_debt, treasury_get_interest_rates, and treasury_get_exchange_rates. Each entry surfaces source tool, query parameters, creation/expiry timestamps, row count, and column schema. Use this tool before treasury_dataframe_query to discover table names and column types. Requires CANVAS_PROVIDER_TYPE=duckdb.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_dataframe_describe",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "description": "Optional dataframe table name (df_XXXXX_XXXXX) to describe a single dataframe. Omit to list all active dataframes.",
      "type": "string"
    }
  },
  "additionalProperties": false
}
view source ↗

treasury_dataframe_query

Run a single-statement SELECT against DataCanvas dataframes registered by treasury_query_dataset, treasury_get_debt, treasury_get_interest_rates, and treasury_get_exchange_rates. 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 denied at the bridge layer. All Treasury dataframe columns are VARCHAR — CAST to DECIMAL or DATE for arithmetic and date comparisons. Use treasury_dataframe_describe to list available table names and column schemas before querying.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "treasury_dataframe_query",
    "arguments": {
      "sql": "<sql>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "sql": {
      "type": "string",
      "minLength": 1,
      "description": "Single-statement SELECT against df_<id> tables. All values in Treasury dataframes are VARCHAR (strings) per the API contract — CAST to DECIMAL or DATE for arithmetic and date comparisons. Example: SELECT record_date, CAST(tot_pub_debt_out_amt AS DECIMAL) AS debt FROM df_xxxxx ORDER BY record_date DESC LIMIT 10."
    },
    "register_as": {
      "description": "Persist result as a new dataframe. Use to chain analyses. The name must match df_XXXXX_XXXXX format or be a fresh df_<id>.",
      "type": "string"
    },
    "preview": {
      "description": "Rows in the immediate response. Defaults to row_limit. Set lower when using register_as.",
      "type": "integer",
      "minimum": 0,
      "maximum": 10000
    },
    "row_limit": {
      "default": 1000,
      "description": "Hard cap on rows in the response. Default 1000, max 10000.",
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    }
  },
  "required": [
    "sql",
    "row_limit"
  ],
  "additionalProperties": false
}
view source ↗