
Access US federal award, recipient, agency, and spending analytics data from USAspending.gov.
Access US federal award, recipient, agency, and spending analytics data from USAspending.gov via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://usaspending.caseyjhand.com/mcp
Federal award, recipient, agency, and spending data from USAspending.gov, the US Treasury's DATA Act transparency platform. Search and trace awards down to transactions, subawards, and funding accounts; profile recipients and agencies; and aggregate spending by geography, category, time, and disaster appropriation. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| Tool | Description |
|---|---|
usaspending_list_agencies | List every top-tier federal agency with its toptier code, slug, and current-year budget totals |
usaspending_autocomplete_filters | Look up NAICS, PSC, CFDA, agency, or recipient codes from a free-text description |
usaspending_search_awards | Search awards by keyword, recipient, agency, award type, NAICS code, assistance listing, location, or date range |
usaspending_get_award | Fetch one award's full record: amounts, recipient, agencies, codes, parent IDV, DEF-code funding |
usaspending_get_award_transactions | List the transactions (modifications, amendments) on an award |
usaspending_get_award_subawards | List the subcontracts or subgrants under a prime award |
usaspending_get_award_federal_accounts | List the Treasury federal accounts that funded an award, with the amount from each |
usaspending_get_idv_awards | List the child orders and sub-IDVs placed under an IDV |
usaspending_search_recipients | Search recipients by name, UEI, or DUNS |
usaspending_get_recipient | Fetch a recipient's profile: address, business types, parent, and award totals |
usaspending_get_agency | Fetch an agency's mission, latest-year budget totals, sub-agencies, and DEF codes |
usaspending_spending_by_geography | Aggregate spending by state, county, or congressional district |
usaspending_spending_by_category | Aggregate spending by NAICS, PSC, agency, CFDA program, or recipient |
usaspending_spending_over_time | Aggregate spending by fiscal year, quarter, or month |
usaspending_disaster_spending | Break down disaster and emergency supplemental spending by agency, program, recipient, or geography |
usaspending_search_federal_accounts | Search federal accounts by title keyword or agency identifier |
usaspending_get_federal_account | Fetch a federal account's budget totals and its Treasury Account Symbol components |
usaspending_get_federal_account_breakdown | Break a federal account's obligations down by program activity or object class |
usaspending_list_agencies toolsort (agency_name, budget_authority_amount, obligated_amount, outlay_amount) and order; returns every agency in one unpaginated responsetoptier_code and agency_slug, both accepted by usaspending_get_agency, plus current-year budget_authority_amount, obligated_amount, and outlay_amountusaspending_autocomplete_filters tooltype (naics, psc, cfda, awarding_agency, recipient) plus search_text; limit 1–500, default 10code and name, with id for agencies and uei / duns for recipients; no match fails as no_match. A cfda code is what usaspending_search_awards takes in assistance_listingsnaics matches official NAICS title text: "software" resolves, "cybersecurity" does not, so search with the industry term a title would useusaspending_search_awards toolkeyword, agency_name, recipient_name, naics_codes, assistance_listings, time_period, and location_filter (country, state, FIPS county, city); award_type_codes defaults to contracts (A–D) and must stay in one group: IDVs IDV_A–IDV_E, grants 02–05/F001/F002, direct payments 06/10/F006/F007, loans 07/08/F003/F004, or other assistance 09/11/-1/F005/F008/F009/F010. limit up to 100assistance_listings takes Assistance Listing (CFDA) numbers such as 93.866 or 11.67A — look them up with usaspending_autocomplete_filters type: cfda — and matches awards carrying any of them. It needs an assistance group in award_type_codes; with contract or IDV codes, or the contract default, it fails as assistance_listings_type_mismatchsort depends on the award type group: loans sort by Loan Value (default), Subsidy Cost, Issued Date, Recipient Name, or Awarding Agency; every other group by Award Amount (default), Total Outlays, Start Date, End Date, Recipient Name, or Awarding Agency, except that IDVs have no End Date. Any other pairing fails as unsupported_sort with the group's listYYYY-MM-DD from 2007-10-01 on (month and day may be unpadded). Either end may be given alone, on the nested filters.time_period_start / time_period_end or by leaving one side of time_period blank ("") — a lone start runs through today (UTC), a lone end from 2007-10-01 — and the response echoes the range sent with a notice naming the filled field. A fully blank time_period means no date filter. A start after the end fails as date_range_invertedgenerated_internal_id for usaspending_get_award and agency_slug for usaspending_get_agency; loan rows carry loan_value, subsidy_cost, and issued_date in place of amounts and dates. There is no total, and page_metadata.has_next is true on any full pagepagination_limit_exceeded); go further with the last_record_sort_value + last_record_unique_id cursor, which is only returned below a 10,000-result offsetusaspending_get_award toolaward_id is a generated_unique_award_id, the generated_internal_id from search; an unknown ID fails as award_not_foundcategory, total_obligation, total_outlays, subaward_count, NAICS / PSC or CFDA codes, and account_obligations_by_defcrecipient.recipient_id chains to usaspending_get_recipient and parent_award.generated_unique_award_id to the parent IDV; category: "idv" awards list their children via usaspending_get_idv_awardsusaspending_get_award_transactions toolaward_id plus sort (action_date, federal_action_obligation, modification_number); limit up to 100action_date, modification_number, action_type, and a signed federal_action_obligation (negative is a deobligation)usaspending_get_award_subawards toolaward_id plus sort (subaward_number, description, action_date, amount, recipient_name); limit up to 100subaward_number, amount, action_date, recipient_name, recipient_uei, and place of performance; subaward_count on usaspending_get_award says whether any existusaspending_get_award_federal_accounts toolaward_id is a generated_unique_award_id; limit up to 100, with page_metadata.count as the totalfederal_account (AGENCY-MAIN, e.g. 080-0120) for usaspending_get_federal_account, total_transaction_obligated_amount, and the funding agency with its funding_agency_slugusaspending_get_idv_awards toolaward_id; type is child_awards (task and delivery orders, the default), child_idvs, or grandchild_awards; limit up to 100generated_unique_award_id for usaspending_get_award, obligated_amount, and performance dates; there is no total, and has_next is true on any full pageusaspending_search_recipients toolkeyword matches names, UEI, or DUNS, partial matches included; optional award_type scopes the totals; limit up to 100id (a hash suffixed -P parent, -C child, or -R standalone) for usaspending_get_recipient, plus uei, duns, recipient_level, and amount; page_metadata.total is the full match countusaspending_get_recipient toolrecipient_id from usaspending_search_recipients or usaspending_get_award; optional fiscal_year (2001–2030) and award_type scope the totals; an unknown ID fails as recipient_not_foundbusiness_types, parent_name / parent_uei, alternate_names, total_transaction_amount, total_transactions, and loan face-value totalsusaspending_get_agency tooltoptier_code (e.g. 097) or agency_slug (e.g. department-of-defense); page walks the sub-agency list 10 at a time. Failures are missing_input and agency_not_foundmission, plus budgetary_resources_amount, obligated_amount, and outlay_amount for the latest fiscal_year, sub_agencies with obligations and transaction and new-award counts, and def_codesusaspending_spending_by_geography toolscope (place_of_performance, recipient_location) and geo_layer (state, county, district) are required; filters takes keywords, award_type_codes, agency_name, recipient_id, naics_codes, and time_period_start / time_period_end (YYYY-MM-DD; either alone fills the other, as in usaspending_search_awards, applied_time_period_* echoes the range sent, a start after the end fails as date_range_inverted, and a range starting before 2007-10-01 fails as date_before_earliest); limit 1–500, default 50shape_code, display_name, aggregated_amount, population, per_capita, and award_count, ranked by amount; total_areas_available counts every match before the capapplied_award_type_default says so; subawards: true switches to subaward datausaspending_spending_by_category toolcategory is naics, psc, awarding_agency, awarding_subagency, funding_agency, funding_subagency, cfda, recipient_duns, or recipient_parent_duns; takes the same filters object as usaspending_spending_by_geography; limit up to 100id, code, name, and amount, ranked by obligationusaspending_spending_over_time toolgroup is fiscal_year, quarter, or month (fiscal month, where 1 is October); the same filters object, with award_type_codes defaulting to contracts and limited to one group; subawards: true switches to subaward datatime_period, aggregated_amount, and per-type contracts, grants, direct_payments, idvs, loans, and otherusaspending_disaster_spending tooldimension is overview, agency, cfda, recipient, or geography; every dimension except overview requires filters.def_codes (e.g. ["L", "M", "N", "O", "P"] for COVID-19); limit up to 100 on agency, cfda, and recipientobligation, outlay, and award_count, plus total_budgetary_resources on agency rows under spending_type: total; overview returns totals and funding_by_def_code. A recipient row's id is one recipient hash for usaspending_get_recipient — the recipient-level -R ID when USAspending lists several. The recipient total tops out at 10,000, and a response at that cap is flagged truncatedtotals for every matching row, as USAspending reports them: obligation, outlay, and either total_budgetary_resources (agency, total) or award_count. When the overview endpoint outlasts the request budget, the agency breakdown with spending_type: total still reports obligations, outlays, and budgetary resourcesspending_type (award, the default, or total) applies to the agency dimension only — USAspending returns the same recipient breakdown for either value; geography takes filters.geo_layer (state, county) and always reports obligationsusaspending_search_federal_accounts toolkeyword and 3-digit agency_identifier; sort_field is account_name, account_number, budgetary_resources (default), or managing_agency; limit up to 100account_number (e.g. 097-8097) for the federal-account tools, managing_agency, and budgetary_resources; page_metadata.count is the totalusaspending_get_federal_account toolaccount_code in AGENCY-MAIN format, from account_number in search results or federal_account on an award; an unknown code fails as account_not_foundtotal_obligated_amount, total_gross_outlay_amount, and total_budgetary_resources for fiscal_year, plus children: one entry per Treasury Account Symbol with its own amountsusaspending_get_federal_account_breakdown toolaccount_code plus dimension (program_activity or object_class); limit up to 100, with page_metadata.total as the row countcode, name, and obligations; program_activity rows add type, either PAC/PAN or PARKBuilt 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.
USAspending-specific:
date_before_earliest), and DoD contract data lags publication by 90 daysusaspending_spending_by_category puts nine category sub-routes behind one category enum, and usaspending_disaster_spending puts five disaster endpoints behind dimensionapi_timeout or api_unavailable with each tool's recovery hint, and a rejected request carries USAspending's own explanation in the error messageAgent-friendly output:
generated_internal_id, agency_slug, recipient.recipient_id, federal_account, and account_number, so agents follow the money without parsing display stringspage_metadata.has_next on every list, a total or count where the upstream publishes one, and truncated / shown / cap when a response is cappednotice echoing the filters and how to broaden them. The ID-keyed list tools (transactions, subawards, funding accounts, IDV children, account breakdown) return an empty list for an unknown ID rather than failingaward_not_found, recipient_not_found, agency_not_found, account_not_found, no_match, date_before_earliest, date_range_inverted, unsupported_sort, assistance_listings_type_mismatch, pagination_limit_exceededA public instance is available at https://usaspending.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"usaspending-mcp-server": {
"type": "streamable-http",
"url": "https://usaspending.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file. No API key is required.
{
"mcpServers": {
"usaspending-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/usaspending-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"usaspending-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/usaspending-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"usaspending-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/usaspending-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
git clone https://github.com/cyanheads/usaspending-mcp-server.git
cd usaspending-mcp-server
bun install
cp .env.example .env
# edit .env if you need to override defaults
No variable is required; the defaults work out of the box.
| Variable | Description | Default |
|---|---|---|
USASPENDING_BASE_URL | USAspending.gov API v2 base URL. | https://api.usaspending.gov/api/v2/ |
USASPENDING_TIMEOUT_MS | Per-attempt HTTP timeout, in ms (1000–120000). | 30000 |
USASPENDING_RETRY_BUDGET_MS | Wall-clock budget for one request across all retry attempts, in ms (1000–300000). | 1.5 × USASPENDING_TIMEOUT_MS |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. | stateless |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry. | false |
See .env.example for the full list of optional overrides.
Build and run:
# One-time build
bun run rebuild
# Run the built server
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 build -t usaspending-mcp-server .
docker run --rm -p 3010:3010 usaspending-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/usaspending-mcp-server. 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 the tools and initializes the USAspending service. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools/definitions | Tool definitions (*.tool.ts) plus shared filter, date, pagination, and formatting helpers. |
src/services/usaspending | USAspending.gov API client: request timeouts, retry budget, raw response types. |
tests/ | Unit tests for tools, the service, config, and scripts. |
See CLAUDE.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/mcp-server/tools/definitions/index.tsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.