usaspending-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -0
- package/dist/api/client.d.ts +45 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +145 -0
- package/dist/api/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +17 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/awards.d.ts +10 -0
- package/dist/tools/awards.d.ts.map +1 -0
- package/dist/tools/awards.js +308 -0
- package/dist/tools/awards.js.map +1 -0
- package/dist/tools/recipients.d.ts +10 -0
- package/dist/tools/recipients.d.ts.map +1 -0
- package/dist/tools/recipients.js +148 -0
- package/dist/tools/recipients.js.map +1 -0
- package/dist/tools/references.d.ts +10 -0
- package/dist/tools/references.d.ts.map +1 -0
- package/dist/tools/references.js +80 -0
- package/dist/tools/references.js.map +1 -0
- package/dist/tools/search.d.ts +10 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +230 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/types/filters.d.ts +87 -0
- package/dist/types/filters.d.ts.map +1 -0
- package/dist/types/filters.js +150 -0
- package/dist/types/filters.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# usaspending-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for the [USASpending.gov API](https://api.usaspending.gov/) — 25 tools for querying federal spending data, tracking government contracts, and researching award recipients.
|
|
4
|
+
|
|
5
|
+
No API key required. Works with Claude Code, Claude Desktop, Claude.ai, and any MCP-compatible client.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### Claude Code (npx)
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"usaspending": {
|
|
15
|
+
"type": "stdio",
|
|
16
|
+
"command": "npx",
|
|
17
|
+
"args": ["-y", "usaspending-mcp"]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Claude Code (local)
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"usaspending": {
|
|
29
|
+
"type": "stdio",
|
|
30
|
+
"command": "node",
|
|
31
|
+
"args": ["/path/to/usaspending-mcp/dist/index.js"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Remote (Streamable HTTP)
|
|
38
|
+
|
|
39
|
+
Run on a server:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx usaspending-mcp --transport http --port 3001
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Connect from Claude Desktop or Claude.ai via your reverse proxy URL.
|
|
46
|
+
|
|
47
|
+
## Tools
|
|
48
|
+
|
|
49
|
+
### Search & Discovery (8 tools)
|
|
50
|
+
|
|
51
|
+
| Tool | Description |
|
|
52
|
+
|------|-------------|
|
|
53
|
+
| `search_awards` | Search federal awards with filters (agency, NAICS, PSC, keywords, date range, award type). Supports pagination. |
|
|
54
|
+
| `search_awards_count` | Get result counts by award type before running a full search. |
|
|
55
|
+
| `search_subawards` | Search subaward/subcontract records across all prime awards. |
|
|
56
|
+
| `search_by_category` | Aggregate spending by dimension (NAICS, PSC, recipient, agency, geography, etc.). |
|
|
57
|
+
| `search_new_awards_over_time` | Track new award volume over time by month, quarter, or fiscal year. |
|
|
58
|
+
| `search_spending_over_time` | Track spending amounts over time. |
|
|
59
|
+
| `search_spending_by_geography` | Break down spending by state, county, or congressional district. |
|
|
60
|
+
| `search_by_transaction` | Transaction-level search across all awards. |
|
|
61
|
+
|
|
62
|
+
### Award & IDV Detail (8 tools)
|
|
63
|
+
|
|
64
|
+
| Tool | Description |
|
|
65
|
+
|------|-------------|
|
|
66
|
+
| `get_award` | Full details for a specific award (recipient, amounts, dates, NAICS/PSC, agency). |
|
|
67
|
+
| `get_award_funding` | Funding sources — which federal accounts and agencies fund an award. |
|
|
68
|
+
| `get_award_subawards` | Subawards under a prime award. Key for mapping supply chains. |
|
|
69
|
+
| `get_award_transactions` | Transaction/modification history for an award. |
|
|
70
|
+
| `get_idv_amounts` | Funding summary for an IDV (IDIQ, GWAC, BPA, BOA, FSS). |
|
|
71
|
+
| `get_idv_awards` | Task orders under an IDV. Identifies all awardees on a contract vehicle. |
|
|
72
|
+
| `get_idv_activity` | Modification and activity history for an IDV. |
|
|
73
|
+
| `get_idv_funding` | IDV funding breakdown by federal account. |
|
|
74
|
+
|
|
75
|
+
### Recipient Intelligence (5 tools)
|
|
76
|
+
|
|
77
|
+
| Tool | Description |
|
|
78
|
+
|------|-------------|
|
|
79
|
+
| `autocomplete_recipient` | Quick recipient name search. First step in finding a company. |
|
|
80
|
+
| `list_recipients` | Search and filter recipients with award totals. |
|
|
81
|
+
| `get_recipient` | Full company profile — DUNS/UEI, parent company, award history by type. |
|
|
82
|
+
| `get_recipient_children` | Child/subsidiary organizations under a parent company. |
|
|
83
|
+
| `get_spending_by_recipient_for_agency` | Recipients ranked by award amount from a specific agency. |
|
|
84
|
+
|
|
85
|
+
### Reference Data (4 tools)
|
|
86
|
+
|
|
87
|
+
| Tool | Description |
|
|
88
|
+
|------|-------------|
|
|
89
|
+
| `list_agencies` | All top-tier federal agencies with codes and metadata. |
|
|
90
|
+
| `search_naics` | Search NAICS industry codes by keyword. |
|
|
91
|
+
| `search_psc` | Search Product/Service Classification codes by keyword. |
|
|
92
|
+
| `get_naics_hierarchy` | Browse the NAICS code tree. |
|
|
93
|
+
|
|
94
|
+
## Filtering
|
|
95
|
+
|
|
96
|
+
Search tools accept a shared filter object:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"keywords": ["cybersecurity"],
|
|
101
|
+
"award_type_codes": ["D"],
|
|
102
|
+
"time_period": [{ "start_date": "2025-01-01", "end_date": "2025-12-31" }],
|
|
103
|
+
"agencies": [{ "type": "awarding", "tier": "toptier", "name": "Department of Defense" }],
|
|
104
|
+
"naics_codes": ["541512"],
|
|
105
|
+
"psc_codes": ["D399"],
|
|
106
|
+
"recipient_search_text": ["Lockheed"],
|
|
107
|
+
"page": 1,
|
|
108
|
+
"limit": 20,
|
|
109
|
+
"sort": "Award Amount",
|
|
110
|
+
"order": "desc"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
All filter fields are optional — compose what you need.
|
|
115
|
+
|
|
116
|
+
### Award Type Codes
|
|
117
|
+
|
|
118
|
+
| Code | Type |
|
|
119
|
+
|------|------|
|
|
120
|
+
| `A` | BPA Call |
|
|
121
|
+
| `B` | Purchase Order |
|
|
122
|
+
| `C` | Delivery Order |
|
|
123
|
+
| `D` | Definitive Contract |
|
|
124
|
+
| `IDV_A` | GWAC |
|
|
125
|
+
| `IDV_B_A` | IDC / IDIQ |
|
|
126
|
+
| `IDV_B_B` | IDC / Indefinite |
|
|
127
|
+
| `IDV_B_C` | IDC / Definitive |
|
|
128
|
+
| `IDV_C` | FSS |
|
|
129
|
+
| `IDV_D` | BOA |
|
|
130
|
+
| `IDV_E` | BPA |
|
|
131
|
+
|
|
132
|
+
## Example Workflows
|
|
133
|
+
|
|
134
|
+
**Find DOD cybersecurity contracts:**
|
|
135
|
+
1. `search_naics` — find relevant codes (541512, 541519)
|
|
136
|
+
2. `search_awards` — filter by DOD + NAICS codes + award type "D" + date range
|
|
137
|
+
3. `get_award` — deep dive on a specific contract
|
|
138
|
+
4. `get_recipient` — profile the winning company
|
|
139
|
+
|
|
140
|
+
**Map a contractor's supply chain:**
|
|
141
|
+
1. `autocomplete_recipient` — find the prime by name
|
|
142
|
+
2. `get_recipient` — get their profile
|
|
143
|
+
3. `search_awards` — find their contracts
|
|
144
|
+
4. `get_award_subawards` — find subcontractors on each contract
|
|
145
|
+
|
|
146
|
+
**Explore an IDIQ/GWAC:**
|
|
147
|
+
1. `search_awards` — filter for IDV award types
|
|
148
|
+
2. `get_idv_awards` — list all task order holders
|
|
149
|
+
3. `get_idv_activity` — see recent activity
|
|
150
|
+
4. `get_recipient` — profile each awardee
|
|
151
|
+
|
|
152
|
+
## Development
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
git clone https://github.com/boejucci/usa-spending-mcp.git
|
|
156
|
+
cd usa-spending-mcp
|
|
157
|
+
npm install
|
|
158
|
+
npm run build
|
|
159
|
+
npm run dev # watch mode
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* USASpending API Client
|
|
3
|
+
*
|
|
4
|
+
* HTTP layer for all communication with the USASpending.gov API.
|
|
5
|
+
* Every MCP tool in this server routes through this client.
|
|
6
|
+
*/
|
|
7
|
+
export declare class USASpendingApiError extends Error {
|
|
8
|
+
readonly statusCode: number;
|
|
9
|
+
readonly statusText: string;
|
|
10
|
+
readonly body: string;
|
|
11
|
+
readonly url: string;
|
|
12
|
+
constructor(message: string, statusCode: number, statusText: string, body: string, url: string);
|
|
13
|
+
}
|
|
14
|
+
export interface PageMetadata {
|
|
15
|
+
page: number;
|
|
16
|
+
hasNext: boolean;
|
|
17
|
+
total?: number;
|
|
18
|
+
limit?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class USASpendingClient {
|
|
21
|
+
private readonly baseUrl;
|
|
22
|
+
private readonly timeoutMs;
|
|
23
|
+
constructor(baseUrl?: string, timeoutMs?: number);
|
|
24
|
+
get<T>(path: string): Promise<T>;
|
|
25
|
+
post<T>(path: string, body: Record<string, unknown>): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Injects a human-readable `_summary` field into a paginated API response.
|
|
28
|
+
*
|
|
29
|
+
* Only modifies the response if `page_metadata` is present.
|
|
30
|
+
*
|
|
31
|
+
* Format:
|
|
32
|
+
* "Page X of Y (Z total results). Showing N items. [context] [More pages available.]"
|
|
33
|
+
*/
|
|
34
|
+
addSummary<T extends Record<string, unknown>>(response: T, context?: string): T & {
|
|
35
|
+
_summary?: string;
|
|
36
|
+
};
|
|
37
|
+
private request;
|
|
38
|
+
/**
|
|
39
|
+
* Counts the number of result items in a response by looking for the first
|
|
40
|
+
* top-level array field (excluding metadata-like keys).
|
|
41
|
+
*/
|
|
42
|
+
private countItems;
|
|
43
|
+
}
|
|
44
|
+
export declare const client: USASpendingClient;
|
|
45
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,UAAU,EAAE,MAAM;aAClB,UAAU,EAAE,MAAM;aAClB,IAAI,EAAE,MAAM;aACZ,GAAG,EAAE,MAAM;gBAJ3B,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM;CAK9B;AAMD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,GAAE,MAAiB,EAAE,SAAS,GAAE,MAAmB;IAShE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAKhC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAYtE;;;;;;;OAOG;IACH,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,QAAQ,EAAE,CAAC,EACX,OAAO,CAAC,EAAE,MAAM,GACf,CAAC,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;YA4Cd,OAAO;IA4CrB;;;OAGG;IACH,OAAO,CAAC,UAAU;CASnB;AAMD,eAAO,MAAM,MAAM,mBAA0B,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* USASpending API Client
|
|
3
|
+
*
|
|
4
|
+
* HTTP layer for all communication with the USASpending.gov API.
|
|
5
|
+
* Every MCP tool in this server routes through this client.
|
|
6
|
+
*/
|
|
7
|
+
const BASE_URL = "https://api.usaspending.gov/api/v2";
|
|
8
|
+
const TIMEOUT_MS = 30_000;
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Error class
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export class USASpendingApiError extends Error {
|
|
13
|
+
statusCode;
|
|
14
|
+
statusText;
|
|
15
|
+
body;
|
|
16
|
+
url;
|
|
17
|
+
constructor(message, statusCode, statusText, body, url) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.statusCode = statusCode;
|
|
20
|
+
this.statusText = statusText;
|
|
21
|
+
this.body = body;
|
|
22
|
+
this.url = url;
|
|
23
|
+
this.name = "USASpendingApiError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Client
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
export class USASpendingClient {
|
|
30
|
+
baseUrl;
|
|
31
|
+
timeoutMs;
|
|
32
|
+
constructor(baseUrl = BASE_URL, timeoutMs = TIMEOUT_MS) {
|
|
33
|
+
this.baseUrl = baseUrl;
|
|
34
|
+
this.timeoutMs = timeoutMs;
|
|
35
|
+
}
|
|
36
|
+
// -------------------------------------------------------------------------
|
|
37
|
+
// Public HTTP methods
|
|
38
|
+
// -------------------------------------------------------------------------
|
|
39
|
+
async get(path) {
|
|
40
|
+
const url = `${this.baseUrl}${path}`;
|
|
41
|
+
return this.request(url, { method: "GET" });
|
|
42
|
+
}
|
|
43
|
+
async post(path, body) {
|
|
44
|
+
const url = `${this.baseUrl}${path}`;
|
|
45
|
+
return this.request(url, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
body: JSON.stringify(body),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// -------------------------------------------------------------------------
|
|
51
|
+
// Pagination summary injection
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Injects a human-readable `_summary` field into a paginated API response.
|
|
55
|
+
*
|
|
56
|
+
* Only modifies the response if `page_metadata` is present.
|
|
57
|
+
*
|
|
58
|
+
* Format:
|
|
59
|
+
* "Page X of Y (Z total results). Showing N items. [context] [More pages available.]"
|
|
60
|
+
*/
|
|
61
|
+
addSummary(response, context) {
|
|
62
|
+
const metadata = response.page_metadata;
|
|
63
|
+
if (!metadata) {
|
|
64
|
+
return response;
|
|
65
|
+
}
|
|
66
|
+
const { page, hasNext } = metadata;
|
|
67
|
+
// Some endpoints put total/limit in page_metadata, others at the top level
|
|
68
|
+
const total = metadata.total ?? response.total;
|
|
69
|
+
const limit = metadata.limit ?? response.limit;
|
|
70
|
+
// Determine how many items are on the current page.
|
|
71
|
+
const itemCount = this.countItems(response);
|
|
72
|
+
const parts = [];
|
|
73
|
+
if (total != null && limit != null) {
|
|
74
|
+
const totalPages = Math.max(1, Math.ceil(total / limit));
|
|
75
|
+
parts.push(`Page ${page} of ${totalPages} (${total.toLocaleString()} total results).`);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
parts.push(`Page ${page}.`);
|
|
79
|
+
}
|
|
80
|
+
parts.push(`Showing ${itemCount} items.`);
|
|
81
|
+
if (context) {
|
|
82
|
+
parts.push(context);
|
|
83
|
+
}
|
|
84
|
+
if (hasNext) {
|
|
85
|
+
parts.push("More pages available.");
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
...response,
|
|
89
|
+
_summary: parts.join(" "),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// -------------------------------------------------------------------------
|
|
93
|
+
// Internal helpers
|
|
94
|
+
// -------------------------------------------------------------------------
|
|
95
|
+
async request(url, init) {
|
|
96
|
+
const controller = new AbortController();
|
|
97
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
98
|
+
try {
|
|
99
|
+
const response = await fetch(url, {
|
|
100
|
+
...init,
|
|
101
|
+
signal: controller.signal,
|
|
102
|
+
headers: {
|
|
103
|
+
"Content-Type": "application/json",
|
|
104
|
+
...init.headers,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const body = await response.text();
|
|
109
|
+
throw new USASpendingApiError(`USASpending API error: ${response.status} ${response.statusText} for ${url}`, response.status, response.statusText, body, url);
|
|
110
|
+
}
|
|
111
|
+
return (await response.json());
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
if (error instanceof USASpendingApiError) {
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
if (error instanceof DOMException ||
|
|
118
|
+
(error instanceof Error && error.name === "AbortError")) {
|
|
119
|
+
throw new Error(`USASpending API request timed out after ${this.timeoutMs}ms: ${url}`);
|
|
120
|
+
}
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
clearTimeout(timer);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Counts the number of result items in a response by looking for the first
|
|
129
|
+
* top-level array field (excluding metadata-like keys).
|
|
130
|
+
*/
|
|
131
|
+
countItems(response) {
|
|
132
|
+
const skipKeys = new Set(["page_metadata", "_summary", "messages"]);
|
|
133
|
+
for (const [key, value] of Object.entries(response)) {
|
|
134
|
+
if (!skipKeys.has(key) && Array.isArray(value)) {
|
|
135
|
+
return value.length;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return 0;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Singleton export
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
export const client = new USASpendingClient();
|
|
145
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,QAAQ,GAAG,oCAAoC,CAAC;AACtD,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAG1B;IACA;IACA;IACA;IALlB,YACE,OAAe,EACC,UAAkB,EAClB,UAAkB,EAClB,IAAY,EACZ,GAAW;QAE3B,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,eAAU,GAAV,UAAU,CAAQ;QAClB,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;QACZ,QAAG,GAAH,GAAG,CAAQ;QAG3B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAaD,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,MAAM,OAAO,iBAAiB;IACX,OAAO,CAAS;IAChB,SAAS,CAAS;IAEnC,YAAY,UAAkB,QAAQ,EAAE,YAAoB,UAAU;QACpE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,4EAA4E;IAC5E,sBAAsB;IACtB,4EAA4E;IAE5E,KAAK,CAAC,GAAG,CAAI,IAAY;QACvB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,OAAO,CAAI,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAA6B;QACvD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,OAAO,CAAI,GAAG,EAAE;YAC1B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,+BAA+B;IAC/B,4EAA4E;IAE5E;;;;;;;OAOG;IACH,UAAU,CACR,QAAW,EACX,OAAgB;QAEhB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAyC,CAAC;QAEpE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QACnC,2EAA2E;QAC3E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAK,QAAQ,CAAC,KAA4B,CAAC;QACvE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAK,QAAQ,CAAC,KAA4B,CAAC;QAEvE,oDAAoD;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,UAAU,KAAK,KAAK,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;QAC9B,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,WAAW,SAAS,SAAS,CAAC,CAAC;QAE1C,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACtC,CAAC;QAED,OAAO;YACL,GAAG,QAAQ;YACX,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,mBAAmB;IACnB,4EAA4E;IAEpE,KAAK,CAAC,OAAO,CAAI,GAAW,EAAE,IAAiB;QACrD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAEnE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,GAAG,IAAI;gBACP,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,GAAI,IAAI,CAAC,OAA8C;iBACxD;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,mBAAmB,CAC3B,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,QAAQ,GAAG,EAAE,EAC7E,QAAQ,CAAC,MAAM,EACf,QAAQ,CAAC,UAAU,EACnB,IAAI,EACJ,GAAG,CACJ,CAAC;YACJ,CAAC;YAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;QACtC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;gBACzC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IACE,KAAK,YAAY,YAAY;gBAC7B,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,EACvD,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,2CAA2C,IAAI,CAAC,SAAS,OAAO,GAAG,EAAE,CACtE,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,UAAU,CAAC,QAAiC;QAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QACpE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/C,OAAO,KAAK,CAAC,MAAM,CAAC;YACtB,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;CACF;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import express from "express";
|
|
6
|
+
import { randomUUID } from "node:crypto";
|
|
7
|
+
import { createServer } from "./server.js";
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
const transportFlag = args.includes("--transport")
|
|
10
|
+
? args[args.indexOf("--transport") + 1]
|
|
11
|
+
: "stdio";
|
|
12
|
+
const portFlag = args.includes("--port")
|
|
13
|
+
? parseInt(args[args.indexOf("--port") + 1], 10)
|
|
14
|
+
: 3001;
|
|
15
|
+
async function main() {
|
|
16
|
+
if (transportFlag === "stdio") {
|
|
17
|
+
const server = createServer();
|
|
18
|
+
const transport = new StdioServerTransport();
|
|
19
|
+
await server.connect(transport);
|
|
20
|
+
console.error("USASpending MCP server running on stdio");
|
|
21
|
+
}
|
|
22
|
+
else if (transportFlag === "http") {
|
|
23
|
+
const app = express();
|
|
24
|
+
app.use(express.json());
|
|
25
|
+
const transports = new Map();
|
|
26
|
+
app.post("/mcp", async (req, res) => {
|
|
27
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
28
|
+
if (sessionId && transports.has(sessionId)) {
|
|
29
|
+
const transport = transports.get(sessionId);
|
|
30
|
+
await transport.handleRequest(req, res, req.body);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!sessionId && isInitializeRequest(req.body)) {
|
|
34
|
+
const transport = new StreamableHTTPServerTransport({
|
|
35
|
+
sessionIdGenerator: () => randomUUID(),
|
|
36
|
+
onsessioninitialized: (sid) => {
|
|
37
|
+
transports.set(sid, transport);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
transport.onclose = () => {
|
|
41
|
+
const sid = [...transports.entries()].find(([, t]) => t === transport)?.[0];
|
|
42
|
+
if (sid)
|
|
43
|
+
transports.delete(sid);
|
|
44
|
+
};
|
|
45
|
+
const server = createServer();
|
|
46
|
+
await server.connect(transport);
|
|
47
|
+
await transport.handleRequest(req, res, req.body);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
res.status(400).json({ error: "Invalid request" });
|
|
51
|
+
});
|
|
52
|
+
app.get("/mcp", async (req, res) => {
|
|
53
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
54
|
+
if (sessionId && transports.has(sessionId)) {
|
|
55
|
+
const transport = transports.get(sessionId);
|
|
56
|
+
await transport.handleRequest(req, res);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
res.status(400).json({ error: "Invalid request - no session" });
|
|
60
|
+
});
|
|
61
|
+
app.delete("/mcp", async (req, res) => {
|
|
62
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
63
|
+
if (sessionId && transports.has(sessionId)) {
|
|
64
|
+
const transport = transports.get(sessionId);
|
|
65
|
+
await transport.handleRequest(req, res);
|
|
66
|
+
transports.delete(sessionId);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
res.status(400).json({ error: "Invalid request - no session" });
|
|
70
|
+
});
|
|
71
|
+
app.listen(portFlag, () => {
|
|
72
|
+
console.error(`USASpending MCP server running on http://localhost:${portFlag}/mcp`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.error(`Unknown transport: ${transportFlag}. Use "stdio" or "http".`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
main().catch((error) => {
|
|
81
|
+
console.error("Fatal error:", error);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,wBAAgB,YAAY,IAAI,SAAS,CAYxC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { registerReferenceTools } from "./tools/references.js";
|
|
3
|
+
import { registerRecipientTools } from "./tools/recipients.js";
|
|
4
|
+
import { registerSearchTools } from "./tools/search.js";
|
|
5
|
+
import { registerAwardTools } from "./tools/awards.js";
|
|
6
|
+
export function createServer() {
|
|
7
|
+
const server = new McpServer({
|
|
8
|
+
name: "usaspending-mcp",
|
|
9
|
+
version: "0.1.0",
|
|
10
|
+
});
|
|
11
|
+
registerReferenceTools(server);
|
|
12
|
+
registerRecipientTools(server);
|
|
13
|
+
registerSearchTools(server);
|
|
14
|
+
registerAwardTools(server);
|
|
15
|
+
return server;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE3B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Award & IDV Detail Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for drilling into specific awards and Indefinite Delivery Vehicles (IDVs).
|
|
5
|
+
* Once a user finds an award via search, these tools provide full details,
|
|
6
|
+
* funding breakdowns, subaward chains, transaction histories, and IDV structure.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
export declare function registerAwardTools(server: McpServer): void;
|
|
10
|
+
//# sourceMappingURL=awards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"awards.d.ts","sourceRoot":"","sources":["../../src/tools/awards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0W1D"}
|