@cliwant/mcp-sam-gov 0.2.1

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +184 -0
  3. package/README.ko.md +184 -0
  4. package/README.md +397 -0
  5. package/dist/ecfr.d.ts +44 -0
  6. package/dist/ecfr.d.ts.map +1 -0
  7. package/dist/ecfr.js +86 -0
  8. package/dist/ecfr.js.map +1 -0
  9. package/dist/federal-register.d.ts +82 -0
  10. package/dist/federal-register.d.ts.map +1 -0
  11. package/dist/federal-register.js +117 -0
  12. package/dist/federal-register.js.map +1 -0
  13. package/dist/grants.d.ts +63 -0
  14. package/dist/grants.d.ts.map +1 -0
  15. package/dist/grants.js +93 -0
  16. package/dist/grants.js.map +1 -0
  17. package/dist/sam-gov/client.d.ts +69 -0
  18. package/dist/sam-gov/client.d.ts.map +1 -0
  19. package/dist/sam-gov/client.js +401 -0
  20. package/dist/sam-gov/client.js.map +1 -0
  21. package/dist/sam-gov/index.d.ts +19 -0
  22. package/dist/sam-gov/index.d.ts.map +1 -0
  23. package/dist/sam-gov/index.js +18 -0
  24. package/dist/sam-gov/index.js.map +1 -0
  25. package/dist/sam-gov/types.d.ts +109 -0
  26. package/dist/sam-gov/types.d.ts.map +1 -0
  27. package/dist/sam-gov/types.js +7 -0
  28. package/dist/sam-gov/types.js.map +1 -0
  29. package/dist/server.d.ts +20 -0
  30. package/dist/server.d.ts.map +1 -0
  31. package/dist/server.js +685 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/usaspending.d.ts +369 -0
  34. package/dist/usaspending.d.ts.map +1 -0
  35. package/dist/usaspending.js +555 -0
  36. package/dist/usaspending.js.map +1 -0
  37. package/package.json +88 -0
  38. package/src/ecfr.ts +127 -0
  39. package/src/federal-register.ts +191 -0
  40. package/src/grants.ts +155 -0
  41. package/src/sam-gov/client.ts +492 -0
  42. package/src/sam-gov/index.ts +28 -0
  43. package/src/sam-gov/types.ts +130 -0
  44. package/src/server.ts +856 -0
  45. package/src/usaspending.ts +925 -0
package/README.md ADDED
@@ -0,0 +1,397 @@
1
+ # @cliwant/mcp-sam-gov
2
+
3
+ > **The most comprehensive keyless federal-data MCP server.**
4
+ > 36 tools for SAM.gov + USAspending + Federal Register + eCFR + Grants.gov.
5
+ > No API key, no registration, no signup. Works in Claude Desktop, Claude Code,
6
+ > Codex CLI, Cursor, Continue, Gemini CLI, and any MCP-aware host.
7
+
8
+ [한국어 README](./README.ko.md) · [日本語 README](./README.ja.md)
9
+
10
+ ---
11
+
12
+ ## What this gives Claude (and other AI agents)
13
+
14
+ | Domain | What you can ask | Tools |
15
+ |---|---|---|
16
+ | 🔍 **Active opportunities** | "Find SAM.gov solicitations under NAICS 541512 closing this month" | 5 SAM.gov tools |
17
+ | 💰 **Awards & recipients** | "Show me Booz Allen wins at VA last fiscal year" | 8 USAspending tools |
18
+ | 📊 **Aggregate analysis** | "Top 10 PSC categories at DoD by spending FY26" | 6 USAspending tools |
19
+ | 🏛 **Agency profiles** | "What's VA's mission? FY25 budget breakdown?" | 3 USAspending tools |
20
+ | 🏢 **Recipient profiles** | "Pull Booz Allen's full recipient profile + alternate names" | 2 USAspending tools |
21
+ | 🧠 **Anti-hallucination** | NAICS / recipient / agency autocomplete + glossary | 5 USAspending tools |
22
+ | 📜 **Federal Register** | "What VA cybersecurity rules were published this quarter?" | 3 tools |
23
+ | ⚖️ **Regulations (FAR/CFR)** | "Find FAR sections about SDVOSB set-aside" | 2 eCFR tools |
24
+ | 🎓 **Federal grants** | "Cybersecurity grants posted in the last 30 days" | 2 Grants.gov tools |
25
+
26
+ **36 tools total. Zero API keys. p50 latency 257ms, p95 766ms** (live benchmarks against federal APIs).
27
+
28
+ ---
29
+
30
+ ## How do I install it? Pick the path that matches you.
31
+
32
+ ### 🟢 Path 1 — Claude Desktop, one-click (no terminal needed)
33
+
34
+ Best for non-developers. Just download a file and double-click.
35
+
36
+ 1. Download **`mcp-sam-gov.mcpb`** from the [latest release](https://github.com/cliwant/mcp-sam-gov/releases/latest).
37
+ 2. Double-click the file. Claude Desktop opens with an "Install Extension" dialog.
38
+ 3. Click **Install**.
39
+ 4. Done. Start a new conversation and ask "Find active SAM.gov opportunities under NAICS 541512".
40
+
41
+ That's it. No PowerShell, no `npm`, nothing.
42
+
43
+ > Requires Claude Desktop ≥ 1.0 (which ships its own Node.js runtime).
44
+
45
+ ### 🟡 Path 2 — Claude Code, one command
46
+
47
+ If you already use Claude Code (the CLI):
48
+
49
+ ```bash
50
+ /plugin install cliwant/mcp-sam-gov
51
+ ```
52
+
53
+ This installs the MCP server **plus** a [SKILL.md](./skills/sam-gov/SKILL.md) workflow guide that teaches Claude when + how to use each of the 36 tools.
54
+
55
+ ### 🔵 Path 3 — Manual install for any MCP host (Codex, Cursor, Continue, Gemini)
56
+
57
+ For Codex CLI / Cursor / Continue / Gemini CLI / anything that speaks MCP:
58
+
59
+ ```bash
60
+ gh repo clone cliwant/mcp-sam-gov
61
+ cd mcp-sam-gov
62
+ npm install --omit=dev
63
+ npm install -g .
64
+ ```
65
+
66
+ After install, the binary `mcp-sam-gov` is on your PATH. Add this to your host config:
67
+
68
+ ```json
69
+ {
70
+ "mcpServers": {
71
+ "sam-gov": {
72
+ "command": "mcp-sam-gov"
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ Specific config locations per host: see [Host configurations](#host-configurations) below.
79
+
80
+ ### ⚪ Path 4 — Direct path (zero install, just point at the file)
81
+
82
+ Skip installation entirely:
83
+
84
+ ```bash
85
+ gh repo clone cliwant/mcp-sam-gov
86
+ cd mcp-sam-gov
87
+ npm install --omit=dev # only runtime deps; dist/ is pre-built
88
+ ```
89
+
90
+ Then point your host config at the absolute path:
91
+
92
+ ```jsonc
93
+ {
94
+ "mcpServers": {
95
+ "sam-gov": {
96
+ "command": "node",
97
+ "args": ["C:\\Users\\you\\mcp-sam-gov\\dist\\server.js"]
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Host configurations
106
+
107
+ ### Claude Desktop
108
+
109
+ `%APPDATA%\Claude\claude_desktop_config.json` (Windows) or `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
110
+
111
+ ```json
112
+ {
113
+ "mcpServers": {
114
+ "sam-gov": { "command": "mcp-sam-gov" }
115
+ }
116
+ }
117
+ ```
118
+
119
+ (Or skip this entirely — use Path 1's `.mcpb` and it auto-configures.)
120
+
121
+ Restart Claude Desktop fully (system tray quit on Windows / Quit menu on macOS), then look for the 🔨 icon. You should see "sam-gov (36 tools)".
122
+
123
+ ### Claude Code
124
+
125
+ Per-project `.mcp.json`:
126
+
127
+ ```json
128
+ { "mcpServers": { "sam-gov": { "command": "mcp-sam-gov" } } }
129
+ ```
130
+
131
+ Or globally:
132
+
133
+ ```bash
134
+ claude mcp add sam-gov mcp-sam-gov
135
+ ```
136
+
137
+ ### Codex CLI
138
+
139
+ `~/.codex/config.toml`:
140
+
141
+ ```toml
142
+ [mcp_servers.sam-gov]
143
+ command = "mcp-sam-gov"
144
+ args = []
145
+ ```
146
+
147
+ ### Cursor
148
+
149
+ Settings → MCP → Add new MCP server:
150
+
151
+ ```json
152
+ { "mcpServers": { "sam-gov": { "command": "mcp-sam-gov" } } }
153
+ ```
154
+
155
+ ### Continue
156
+
157
+ `~/.continue/config.json`:
158
+
159
+ ```json
160
+ {
161
+ "experimental": {
162
+ "modelContextProtocolServer": {
163
+ "transport": { "type": "stdio", "command": "mcp-sam-gov" }
164
+ }
165
+ }
166
+ }
167
+ ```
168
+
169
+ ### Gemini CLI
170
+
171
+ `~/.gemini/settings.json`:
172
+
173
+ ```json
174
+ { "mcpServers": { "sam-gov": { "command": "mcp-sam-gov" } } }
175
+ ```
176
+
177
+ ### Anything else
178
+
179
+ If your host speaks MCP over stdio, point it at `mcp-sam-gov`. No host-specific code.
180
+
181
+ ---
182
+
183
+ ## What questions can I ask?
184
+
185
+ Once installed, you can ask in natural language. The agent picks the right tool sequence automatically.
186
+
187
+ ### Discovery
188
+ - "NAICS 541512 의 메릴랜드 입찰 중 30일 안에 마감되는 것 찾아줘"
189
+ - "Find active SAM.gov solicitations under NAICS 541512, MD only, closing in 30 days"
190
+ - "What's the canonical NAICS code for 'computer systems design'?"
191
+
192
+ ### RFP analysis
193
+ - "Pull noticeId 5ef3db5daeb54099a96d487783a38bd0 — give me the SOW, contracting officer, and attachments"
194
+ - "Show me the full RFP body for that notice"
195
+
196
+ ### Competitive landscape
197
+ - "Top 5 recipients of VA contracts in NAICS 541519 last fiscal year"
198
+ - "Show me Booz Allen's individual awards at DISA"
199
+ - "Who are the sub-contractors on Leidos' VA contracts?"
200
+ - "What's CMS in USAspending? (resolve the abbreviation)"
201
+
202
+ ### Trends & aggregation
203
+ - "How has VA 541512 spending trended over the last 5 fiscal years?"
204
+ - "Top 10 states by federal contracting spend in 541512"
205
+ - "Top PSC categories at DoD by spending"
206
+ - "Federal grant programs in cybersecurity by total $"
207
+
208
+ ### Agency intelligence (capture brief)
209
+ - "Give me a capture brief on VA: mission, FY26 budget breakdown, top sub-agencies"
210
+ - "What's VA's transaction volume for FY25?"
211
+
212
+ ### Recompete radar
213
+ - "VA 541512 contracts expiring in next 12 months over $1M"
214
+ - "Pull period of performance for award CONT_AWD_..."
215
+
216
+ ### Regulatory
217
+ - "Find FAR sections about SDVOSB set-aside requirements"
218
+ - "What new VA cybersecurity rules were published this quarter?"
219
+ - "Is there a Federal Register doc number 2026-08333? Pull the citation."
220
+
221
+ ### Grants
222
+ - "Cybersecurity grants posted in the last 30 days"
223
+ - "Pull grant id 361238"
224
+
225
+ ---
226
+
227
+ ## Optional — higher rate limits + archives
228
+
229
+ The MCP server runs **keyless** by default. For higher SAM.gov rate limits + the full archive (notices older than ~12 months), set `SAM_GOV_API_KEY` in your host's env block:
230
+
231
+ ```json
232
+ {
233
+ "mcpServers": {
234
+ "sam-gov": {
235
+ "command": "mcp-sam-gov",
236
+ "env": { "SAM_GOV_API_KEY": "your-key-here" }
237
+ }
238
+ }
239
+ }
240
+ ```
241
+
242
+ Get a free key at [sam.gov/SAM/pages/public/searchKeyData.jsf](https://sam.gov/SAM/pages/public/searchKeyData.jsf). The agent doesn't need to know — the key path is transparent.
243
+
244
+ ---
245
+
246
+ ## Tool catalog (36 tools)
247
+
248
+ <details>
249
+ <summary><b>SAM.gov — opportunities + attachments (5 tools)</b></summary>
250
+
251
+ - `sam_search_opportunities` — keyless HAL search (~47K active)
252
+ - `sam_get_opportunity` — full detail by 32-char hex noticeId (POCs + attachments + body)
253
+ - `sam_fetch_description` — full RFP body as plain text
254
+ - `sam_attachment_url` — public download URL for resourceId
255
+ - `sam_lookup_organization` — federal-organization id → fullParentPathName
256
+ </details>
257
+
258
+ <details>
259
+ <summary><b>USAspending — awards + recipients (8 tools)</b></summary>
260
+
261
+ - `usas_search_awards` — share-of-wallet at agency × NAICS
262
+ - `usas_search_individual_awards` — line items (returns generatedInternalId)
263
+ - `usas_search_subagency_spending` — buyer-office breakdown
264
+ - `usas_lookup_agency` — abbreviation → canonical name
265
+ - `usas_search_awards_by_recipient` — recipient win history
266
+ - `usas_search_subawards` — supply-chain / teaming
267
+ - `usas_search_expiring_contracts` — recompete radar
268
+ - `usas_get_award_detail` — period of performance, options, set-aside, competition
269
+ </details>
270
+
271
+ <details>
272
+ <summary><b>USAspending — aggregate analysis (6 tools)</b></summary>
273
+
274
+ - `usas_spending_over_time` — fiscal_year / quarter / month time series
275
+ - `usas_search_psc_spending` — PSC market structure
276
+ - `usas_search_state_spending` — geographic distribution
277
+ - `usas_search_cfda_spending` — grant programs
278
+ - `usas_search_federal_account_spending` — Treasury Account Symbols (TAS)
279
+ - `usas_search_agency_spending` — top buying agencies for NAICS / set-aside
280
+ </details>
281
+
282
+ <details>
283
+ <summary><b>USAspending — agency profile (3 tools)</b></summary>
284
+
285
+ - `usas_get_agency_profile` — mission, abbreviation, website
286
+ - `usas_get_agency_awards_summary` — transaction count + obligations
287
+ - `usas_get_agency_budget_function` — budget breakdown by program area
288
+ </details>
289
+
290
+ <details>
291
+ <summary><b>USAspending — recipient profile (2 tools)</b></summary>
292
+
293
+ - `usas_search_recipients` — list with parent/child hierarchy
294
+ - `usas_get_recipient_profile` — full detail (DUNS, UEI, alternate names, totals)
295
+ </details>
296
+
297
+ <details>
298
+ <summary><b>USAspending — reference / autocomplete (5 tools)</b></summary>
299
+
300
+ - `usas_autocomplete_naics` — anti-hallucination NAICS guard
301
+ - `usas_autocomplete_recipient` — anti-hallucination recipient guard
302
+ - `usas_naics_hierarchy` — navigate NAICS tree
303
+ - `usas_glossary` — 151 federal-spending terms
304
+ - `usas_list_toptier_agencies` — list all toptier agencies + obligations
305
+ </details>
306
+
307
+ <details>
308
+ <summary><b>Federal Register — rules + notices (3 tools)</b></summary>
309
+
310
+ - `fed_register_search_documents` — search by query / agency / type / date
311
+ - `fed_register_get_document` — citation, body URL, CFR refs
312
+ - `fed_register_list_agencies` — agency slugs reference
313
+ </details>
314
+
315
+ <details>
316
+ <summary><b>eCFR — Code of Federal Regulations (2 tools)</b></summary>
317
+
318
+ - `ecfr_search` — full-text search (titleNumber=48 for FAR)
319
+ - `ecfr_list_titles` — all 50 CFR titles + last-amended dates
320
+ </details>
321
+
322
+ <details>
323
+ <summary><b>Grants.gov — federal grants (2 tools)</b></summary>
324
+
325
+ - `grants_search` — opportunity search
326
+ - `grants_get_opportunity` — full grant detail
327
+ </details>
328
+
329
+ ---
330
+
331
+ ## Troubleshooting
332
+
333
+ | Symptom | Fix |
334
+ |---|---|
335
+ | Claude Desktop 🔨 menu doesn't show `sam-gov` | Fully quit Claude Desktop (system tray on Windows / Quit menu on macOS) and reopen. Check `%APPDATA%\Claude\logs\mcp*.log` |
336
+ | `command not found: mcp-sam-gov` | Confirm `npm install -g .` succeeded; check that npm's global bin is on PATH (`npm config get prefix`) |
337
+ | `MODULE_NOT_FOUND ...dist/server.js` after `npm install -g github:...` | npm bug with git-dep symlinks on Windows. Use the clone + `npm install -g .` recipe (Path 3) instead. |
338
+ | `EPERM: operation not permitted, rmdir` during install | Previous failed install left dangling files. Run `rmdir /s /q "%APPDATA%\npm\node_modules\@cliwant"` (or `@govicon` if you installed an early version) then retry. |
339
+ | `npm install` fails with "private repo" / 404 | The repo is now public — should not happen. If it does, try `git clone https://github.com/cliwant/mcp-sam-gov.git` directly. |
340
+ | Tools return empty results | SAM.gov rate-limits aggressive callers. Wait 1 minute. Or set `SAM_GOV_API_KEY` for the higher-rate authenticated path. |
341
+ | "Tool error: USAspending POST returned 400" | Usually means a field has a wrong type (e.g. fiscal year as string). Check the tool input schema in your host's tool browser. |
342
+
343
+ ---
344
+
345
+ ## Use as a TypeScript / JavaScript library (no MCP)
346
+
347
+ Beyond the MCP server, this package also exports the underlying federal-data
348
+ clients as importable modules. Useful if you're building your own SaaS, AI
349
+ agent, or CLI and want programmatic access without spawning an MCP server.
350
+
351
+ ```bash
352
+ npm install @cliwant/mcp-sam-gov
353
+ ```
354
+
355
+ ```ts
356
+ // SAM.gov client
357
+ import { SamGovClient } from "@cliwant/mcp-sam-gov/sam-gov";
358
+
359
+ const sam = new SamGovClient(); // keyless
360
+ const result = await sam.searchOpportunities({ ncode: "541512", limit: 5 });
361
+ const opp = await sam.getOpportunity("5ef3db5daeb54099a96d487783a38bd0");
362
+ ```
363
+
364
+ ```ts
365
+ // USAspending wrappers (22 functions)
366
+ import * as usas from "@cliwant/mcp-sam-gov/usaspending";
367
+
368
+ const recompete = await usas.searchExpiringContracts({
369
+ agency: "Department of Veterans Affairs",
370
+ naics: "541512",
371
+ monthsUntilExpiry: 12,
372
+ });
373
+ const recipient = await usas.getRecipientProfile("ed02855e-60d7-2540-...-P");
374
+ ```
375
+
376
+ ```ts
377
+ // Federal Register / eCFR / Grants.gov
378
+ import * as fedreg from "@cliwant/mcp-sam-gov/federal-register";
379
+ import * as ecfr from "@cliwant/mcp-sam-gov/ecfr";
380
+ import * as grants from "@cliwant/mcp-sam-gov/grants";
381
+
382
+ const farResults = await ecfr.search({ query: "SDVOSB", titleNumber: 48 });
383
+ ```
384
+
385
+ This is the canonical home for the Cliwant federal-data libraries — there
386
+ is no separate library package. Two earlier repos (`govicon-sam-gov` and
387
+ `govicon-mcp-sam-gov`) have been archived and consolidated here. All
388
+ client code lives in `src/sam-gov/`, `src/usaspending.ts`,
389
+ `src/federal-register.ts`, `src/ecfr.ts`, `src/grants.ts`.
390
+
391
+ ## License
392
+
393
+ MIT — see [LICENSE](./LICENSE).
394
+
395
+ ## Disclaimer
396
+
397
+ This server uses **publicly available** federal API endpoints. It is not affiliated with the General Services Administration, SAM.gov, USAspending.gov, the Office of the Federal Register, the National Archives, Grants.gov, or any federal agency. Federal procurement, spending, and regulation data is in the public domain.
package/dist/ecfr.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * eCFR (Electronic Code of Federal Regulations) wrappers (keyless).
3
+ *
4
+ * eCFR is the up-to-date version of the CFR — Title 48 = FAR (Federal
5
+ * Acquisition Regulation), Title 2 = Federal financial assistance, etc.
6
+ * For a federal contractor, eCFR is the primary source for regulation
7
+ * text the agent should quote when answering compliance questions.
8
+ *
9
+ * Endpoints:
10
+ * - /versioner/v1/titles.json — list 50 CFR titles + last-amended dates
11
+ * - /search/v1/results — full-text search across the entire CFR
12
+ *
13
+ * Both keyless. Documented at https://www.ecfr.gov/developers/.
14
+ */
15
+ export declare function listTitles(): Promise<{
16
+ titles: {
17
+ number: number;
18
+ name: string;
19
+ latestAmendedOn: string | undefined;
20
+ latestIssueDate: string | undefined;
21
+ upToDateAsOf: string | undefined;
22
+ reserved: boolean;
23
+ }[];
24
+ }>;
25
+ export declare function search(args: {
26
+ query: string;
27
+ titleNumber?: number;
28
+ perPage?: number;
29
+ }): Promise<{
30
+ results: {
31
+ type: string;
32
+ title: string;
33
+ chapter: string | undefined;
34
+ part: string | undefined;
35
+ subpart: string | undefined;
36
+ section: string | undefined;
37
+ headingPath: string;
38
+ excerpt: string;
39
+ score: number;
40
+ ecfrUrl: string;
41
+ effectiveOn: string;
42
+ }[];
43
+ }>;
44
+ //# sourceMappingURL=ecfr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecfr.d.ts","sourceRoot":"","sources":["../src/ecfr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAeH,wBAAsB,UAAU;;;;;;;;;GAsB/B;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;;;GAkDA"}
package/dist/ecfr.js ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * eCFR (Electronic Code of Federal Regulations) wrappers (keyless).
3
+ *
4
+ * eCFR is the up-to-date version of the CFR — Title 48 = FAR (Federal
5
+ * Acquisition Regulation), Title 2 = Federal financial assistance, etc.
6
+ * For a federal contractor, eCFR is the primary source for regulation
7
+ * text the agent should quote when answering compliance questions.
8
+ *
9
+ * Endpoints:
10
+ * - /versioner/v1/titles.json — list 50 CFR titles + last-amended dates
11
+ * - /search/v1/results — full-text search across the entire CFR
12
+ *
13
+ * Both keyless. Documented at https://www.ecfr.gov/developers/.
14
+ */
15
+ const ECFR = "https://www.ecfr.gov/api";
16
+ async function fetchJson(url) {
17
+ const r = await fetch(url, {
18
+ headers: { Accept: "application/json" },
19
+ signal: AbortSignal.timeout(15_000),
20
+ });
21
+ if (!r.ok) {
22
+ throw new Error(`eCFR ${url} returned ${r.status}`);
23
+ }
24
+ return (await r.json());
25
+ }
26
+ export async function listTitles() {
27
+ const json = await fetchJson(`${ECFR}/versioner/v1/titles.json`);
28
+ return {
29
+ titles: (json.titles ?? []).map((t) => ({
30
+ number: t.number ?? 0,
31
+ name: t.name ?? "",
32
+ latestAmendedOn: t.latest_amended_on,
33
+ latestIssueDate: t.latest_issue_date,
34
+ upToDateAsOf: t.up_to_date_as_of,
35
+ reserved: !!t.reserved,
36
+ })),
37
+ };
38
+ }
39
+ export async function search(args) {
40
+ const url = new URL(`${ECFR}/search/v1/results`);
41
+ url.searchParams.set("query", args.query);
42
+ url.searchParams.set("per_page", String(args.perPage ?? 5));
43
+ if (args.titleNumber) {
44
+ // eCFR search filter: hierarchy[title]=N (NOT just title=N — that's
45
+ // an "unpermitted parameter" error from the eCFR API).
46
+ url.searchParams.set("hierarchy[title]", String(args.titleNumber));
47
+ }
48
+ const json = await fetchJson(url.toString());
49
+ return {
50
+ results: (json.results ?? []).map((r) => ({
51
+ type: r.type ?? "",
52
+ title: r.hierarchy?.title ?? "",
53
+ chapter: r.hierarchy?.chapter,
54
+ part: r.hierarchy?.part,
55
+ subpart: r.hierarchy?.subpart,
56
+ section: r.hierarchy?.section,
57
+ headingPath: Object.values(r.hierarchy_headings ?? {})
58
+ .filter(Boolean)
59
+ .join(" › "),
60
+ excerpt: stripHtml(r.full_text_excerpt ?? ""),
61
+ score: r.score ?? 0,
62
+ // Stable ecfr.gov URL pattern from the hierarchy
63
+ ecfrUrl: r.hierarchy
64
+ ? buildEcfrUrl(r.hierarchy)
65
+ : "",
66
+ effectiveOn: r.starts_on ?? "",
67
+ })),
68
+ };
69
+ }
70
+ function stripHtml(s) {
71
+ return s
72
+ .replace(/<[^>]+>/g, "")
73
+ .replace(/\s+/g, " ")
74
+ .trim();
75
+ }
76
+ function buildEcfrUrl(h) {
77
+ const base = `https://www.ecfr.gov/current/title-${h.title}`;
78
+ if (h.section)
79
+ return `${base}/section-${h.section}`;
80
+ if (h.part)
81
+ return `${base}/part-${h.part}`;
82
+ if (h.chapter)
83
+ return `${base}/chapter-${h.chapter}`;
84
+ return base;
85
+ }
86
+ //# sourceMappingURL=ecfr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecfr.js","sourceRoot":"","sources":["../src/ecfr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,IAAI,GAAG,0BAA0B,CAAC;AAExC,KAAK,UAAU,SAAS,CAAI,GAAW;IACrC,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACzB,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;QACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAM,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAW9B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAO,GAAG,IAAI,2BAA2B,CAAC,CAAC;IACvE,OAAO;QACL,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC;YACrB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YAClB,eAAe,EAAE,CAAC,CAAC,iBAAiB;YACpC,eAAe,EAAE,CAAC,CAAC,iBAAiB;YACpC,YAAY,EAAE,CAAC,CAAC,gBAAgB;YAChC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;SACvB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAI5B;IACC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;IACjD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5D,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,oEAAoE;QACpE,uDAAuD;QACvD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACrE,CAAC;IAqBD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnD,OAAO;QACL,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YAClB,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YAC/B,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO;YAC7B,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI;YACvB,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO;YAC7B,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO;YAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,IAAI,EAAE,CAAC;iBACnD,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,KAAK,CAAC;YACd,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC;YAC7C,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;YACnB,iDAAiD;YACjD,OAAO,EAAE,CAAC,CAAC,SAAS;gBAClB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC3B,CAAC,CAAC,EAAE;YACN,WAAW,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE;SAC/B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC;SACL,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,YAAY,CAAC,CAKrB;IACC,MAAM,IAAI,GAAG,sCAAsC,CAAC,CAAC,KAAK,EAAE,CAAC;IAC7D,IAAI,CAAC,CAAC,OAAO;QAAE,OAAO,GAAG,IAAI,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IACrD,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,GAAG,IAAI,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,IAAI,CAAC,CAAC,OAAO;QAAE,OAAO,GAAG,IAAI,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Federal Register API v1 wrappers (keyless, no registration).
3
+ *
4
+ * Federal Register is the daily journal of the US federal government —
5
+ * proposed rules, final rules, presidential documents, public notices.
6
+ * Critical context for any federal contracting question that touches
7
+ * regulation, set-aside policy, or new acquisition guidance.
8
+ *
9
+ * Endpoints:
10
+ * - documents.json — search across documents (filters: agencies,
11
+ * conditions, type, date range)
12
+ * - documents/{number}.json — single document detail (full body URL,
13
+ * abstract, citation, effective date)
14
+ * - agencies.json — agency reference list
15
+ *
16
+ * All endpoints are public + keyless (no API key, no registration).
17
+ * Rate-limit: documented as ~1000 req/hour per IP (informal).
18
+ */
19
+ export type FedRegDocumentType = "RULE" | "PRORULE" | "NOTICE" | "PRESDOCU" | "UNKNOWN";
20
+ export declare function searchDocuments(args: {
21
+ query?: string;
22
+ agencySlugs?: string[];
23
+ type?: "RULE" | "PRORULE" | "NOTICE" | "PRESDOCU";
24
+ publicationDateFrom?: string;
25
+ publicationDateTo?: string;
26
+ effectiveDateFrom?: string;
27
+ perPage?: number;
28
+ }): Promise<{
29
+ totalRecords: number;
30
+ totalPages: number;
31
+ documents: {
32
+ documentNumber: string;
33
+ title: string;
34
+ type: FedRegDocumentType;
35
+ typeDisplay: string;
36
+ abstract: string;
37
+ htmlUrl: string;
38
+ pdfUrl: string | undefined;
39
+ publicationDate: string;
40
+ effectiveDate: string | undefined;
41
+ agencies: {
42
+ name: string;
43
+ slug: string;
44
+ }[];
45
+ }[];
46
+ }>;
47
+ export declare function getDocument(documentNumber: string): Promise<{
48
+ documentNumber: string;
49
+ title: string;
50
+ type: FedRegDocumentType;
51
+ typeDisplay: string;
52
+ abstract: string;
53
+ htmlUrl: string;
54
+ pdfUrl: string | undefined;
55
+ rawTextUrl: string | undefined;
56
+ publicationDate: string;
57
+ effectiveDate: string | undefined;
58
+ citation: string | undefined;
59
+ pageCount: number | undefined;
60
+ agencies: {
61
+ name: string;
62
+ slug: string;
63
+ }[];
64
+ cfrReferences: {
65
+ title: string;
66
+ part: string | undefined;
67
+ chapter: string | undefined;
68
+ }[];
69
+ }>;
70
+ export declare function listAgencies(args: {
71
+ perPage?: number;
72
+ }): Promise<{
73
+ agencies: {
74
+ id: number;
75
+ name: string;
76
+ shortName: string | undefined;
77
+ slug: string;
78
+ description: string;
79
+ parentId: number | null | undefined;
80
+ }[];
81
+ }>;
82
+ //# sourceMappingURL=federal-register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federal-register.d.ts","sourceRoot":"","sources":["../src/federal-register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAeH,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,SAAS,GACT,QAAQ,GACR,UAAU,GACV,SAAS,CAAC;AASd,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IAClD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;;;;;;;GAkEA;AAED,wBAAsB,WAAW,CAAC,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;GA2CvD;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;GAuB5D"}