An MCP server to help agents interact with USASpending.gov api
Server has 4 well-structured tools with mostly clear naming and documented descriptions. All tools have input schemas with typed parameters. However, descriptions lack LLM-optimization guidance, output schemas are not formally documented, error messages are generic, and parameter descriptions are sparse. The server follows basic MCP patterns but misses several production-quality signal patterns for agent optimization.
Get US agencies and their ids and codes - Use this when you want to get a list of all the us agencies and their metadata Usage: get_us_agencies()
Get award details for a given generated_unique_award_id from usaspending.gov - Use this when you have a generated unique award id from another tool and want to get details on that specific award - Only use this with award IDs. Generally these award IDs will come from GetSpendingAwardsByAgencyID Args: generated_unique_award_id: the unique id associated to the award
Get government spending awards from usaspending.gov for a fiscal year for a given agency id - Use this tool when you have an agency id and want to get awards for a given year Args: year: fiscal year for which you want data toptier_agency: toptier agency code
Search USASpending.gove for details of spending awards. - You should only use this tool when you want to do a broad search for awards by keyword - Use this tool when you are looking up broad keywords. - Returns 20 results ordered by Award Amount
Output schemas undocumented. All 4 tools return Dict[str, Any] or List[...] with no documented field structure. Agents cannot plan downstream operations or extract required IDs.
Parameter validation absent. 'year' accepts any string (could be '2024' or 'abc'), no enum constraint. 'agency_id' is opaque string with no format guidance. No minimum/maximum constraints, no regex patterns documented.
Error messages generic. All errors return INTERNAL_ERROR with raw HTTP status/exception repr. Does not tell agent what to do: retryable? user-fixable? fatal? No guidance on next steps.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 55 | - | v1 |
Descriptions lack LLM-optimization. Several descriptions under 100 chars or vague (GetAgencies: 89 chars; missing field structure info). Baseline A+ tools use 50-200 chars with explicit WHAT/WHEN/HOW structure.
No pagination metadata in return types. SearchByKeywords hardcodes limit=20 and returns exact count, but response structure doesn't indicate if there are more results. Agents cannot iterate safely.
Response field naming inconsistency. SearchByKeywords uses Pydantic aliases (award_id aliases 'Award ID'), mapping hidden from agent. If agent needs to chain to GetAwardInfoByGeneratedUniqueAwardId, it must use generated_unique_award_id field (not award_id).