@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.
- package/LICENSE +21 -0
- package/README.ja.md +184 -0
- package/README.ko.md +184 -0
- package/README.md +397 -0
- package/dist/ecfr.d.ts +44 -0
- package/dist/ecfr.d.ts.map +1 -0
- package/dist/ecfr.js +86 -0
- package/dist/ecfr.js.map +1 -0
- package/dist/federal-register.d.ts +82 -0
- package/dist/federal-register.d.ts.map +1 -0
- package/dist/federal-register.js +117 -0
- package/dist/federal-register.js.map +1 -0
- package/dist/grants.d.ts +63 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +93 -0
- package/dist/grants.js.map +1 -0
- package/dist/sam-gov/client.d.ts +69 -0
- package/dist/sam-gov/client.d.ts.map +1 -0
- package/dist/sam-gov/client.js +401 -0
- package/dist/sam-gov/client.js.map +1 -0
- package/dist/sam-gov/index.d.ts +19 -0
- package/dist/sam-gov/index.d.ts.map +1 -0
- package/dist/sam-gov/index.js +18 -0
- package/dist/sam-gov/index.js.map +1 -0
- package/dist/sam-gov/types.d.ts +109 -0
- package/dist/sam-gov/types.d.ts.map +1 -0
- package/dist/sam-gov/types.js +7 -0
- package/dist/sam-gov/types.js.map +1 -0
- package/dist/server.d.ts +20 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +685 -0
- package/dist/server.js.map +1 -0
- package/dist/usaspending.d.ts +369 -0
- package/dist/usaspending.d.ts.map +1 -0
- package/dist/usaspending.js +555 -0
- package/dist/usaspending.js.map +1 -0
- package/package.json +88 -0
- package/src/ecfr.ts +127 -0
- package/src/federal-register.ts +191 -0
- package/src/grants.ts +155 -0
- package/src/sam-gov/client.ts +492 -0
- package/src/sam-gov/index.ts +28 -0
- package/src/sam-gov/types.ts +130 -0
- package/src/server.ts +856 -0
- package/src/usaspending.ts +925 -0
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
const FED_REG = "https://www.federalregister.gov/api/v1";
|
|
20
|
+
async function fetchJson(url) {
|
|
21
|
+
const r = await fetch(url, {
|
|
22
|
+
headers: { Accept: "application/json" },
|
|
23
|
+
signal: AbortSignal.timeout(15_000),
|
|
24
|
+
});
|
|
25
|
+
if (!r.ok) {
|
|
26
|
+
throw new Error(`Federal Register ${url} returned ${r.status}`);
|
|
27
|
+
}
|
|
28
|
+
return (await r.json());
|
|
29
|
+
}
|
|
30
|
+
const TYPE_MAP = {
|
|
31
|
+
Rule: "RULE",
|
|
32
|
+
"Proposed Rule": "PRORULE",
|
|
33
|
+
Notice: "NOTICE",
|
|
34
|
+
"Presidential Document": "PRESDOCU",
|
|
35
|
+
};
|
|
36
|
+
export async function searchDocuments(args) {
|
|
37
|
+
const url = new URL(`${FED_REG}/documents.json`);
|
|
38
|
+
url.searchParams.set("per_page", String(args.perPage ?? 10));
|
|
39
|
+
if (args.query) {
|
|
40
|
+
url.searchParams.set("conditions[term]", args.query);
|
|
41
|
+
}
|
|
42
|
+
for (const slug of args.agencySlugs ?? []) {
|
|
43
|
+
url.searchParams.append("conditions[agencies][]", slug);
|
|
44
|
+
}
|
|
45
|
+
if (args.type) {
|
|
46
|
+
url.searchParams.append("conditions[type][]", args.type);
|
|
47
|
+
}
|
|
48
|
+
if (args.publicationDateFrom) {
|
|
49
|
+
url.searchParams.set("conditions[publication_date][gte]", args.publicationDateFrom);
|
|
50
|
+
}
|
|
51
|
+
if (args.publicationDateTo) {
|
|
52
|
+
url.searchParams.set("conditions[publication_date][lte]", args.publicationDateTo);
|
|
53
|
+
}
|
|
54
|
+
if (args.effectiveDateFrom) {
|
|
55
|
+
url.searchParams.set("conditions[effective_date][gte]", args.effectiveDateFrom);
|
|
56
|
+
}
|
|
57
|
+
const json = await fetchJson(url.toString());
|
|
58
|
+
return {
|
|
59
|
+
totalRecords: json.count ?? 0,
|
|
60
|
+
totalPages: json.total_pages ?? 0,
|
|
61
|
+
documents: (json.results ?? []).map((d) => ({
|
|
62
|
+
documentNumber: d.document_number ?? "",
|
|
63
|
+
title: d.title ?? "",
|
|
64
|
+
type: TYPE_MAP[d.type ?? ""] ?? "UNKNOWN",
|
|
65
|
+
typeDisplay: d.type ?? "",
|
|
66
|
+
abstract: d.abstract ?? "",
|
|
67
|
+
htmlUrl: d.html_url ?? "",
|
|
68
|
+
pdfUrl: d.pdf_url,
|
|
69
|
+
publicationDate: d.publication_date ?? "",
|
|
70
|
+
effectiveDate: d.effective_on,
|
|
71
|
+
agencies: (d.agencies ?? []).map((a) => ({
|
|
72
|
+
name: a.name ?? "",
|
|
73
|
+
slug: a.slug ?? "",
|
|
74
|
+
})),
|
|
75
|
+
})),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export async function getDocument(documentNumber) {
|
|
79
|
+
const json = await fetchJson(`${FED_REG}/documents/${encodeURIComponent(documentNumber)}.json`);
|
|
80
|
+
return {
|
|
81
|
+
documentNumber: json.document_number ?? "",
|
|
82
|
+
title: json.title ?? "",
|
|
83
|
+
type: TYPE_MAP[json.type ?? ""] ?? "UNKNOWN",
|
|
84
|
+
typeDisplay: json.type ?? "",
|
|
85
|
+
abstract: json.abstract ?? "",
|
|
86
|
+
htmlUrl: json.html_url ?? "",
|
|
87
|
+
pdfUrl: json.pdf_url,
|
|
88
|
+
rawTextUrl: json.raw_text_url,
|
|
89
|
+
publicationDate: json.publication_date ?? "",
|
|
90
|
+
effectiveDate: json.effective_on,
|
|
91
|
+
citation: json.citation,
|
|
92
|
+
pageCount: json.page_length,
|
|
93
|
+
agencies: (json.agencies ?? []).map((a) => ({
|
|
94
|
+
name: a.name ?? "",
|
|
95
|
+
slug: a.slug ?? "",
|
|
96
|
+
})),
|
|
97
|
+
cfrReferences: (json.cfr_references ?? []).map((c) => ({
|
|
98
|
+
title: c.title ?? "",
|
|
99
|
+
part: c.part,
|
|
100
|
+
chapter: c.chapter,
|
|
101
|
+
})),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export async function listAgencies(args) {
|
|
105
|
+
const json = await fetchJson(`${FED_REG}/agencies.json?per_page=${args.perPage ?? 100}`);
|
|
106
|
+
return {
|
|
107
|
+
agencies: (json ?? []).map((a) => ({
|
|
108
|
+
id: a.id ?? 0,
|
|
109
|
+
name: a.name ?? "",
|
|
110
|
+
shortName: a.short_name,
|
|
111
|
+
slug: a.slug ?? "",
|
|
112
|
+
description: a.description ?? "",
|
|
113
|
+
parentId: a.parent_id,
|
|
114
|
+
})),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=federal-register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federal-register.js","sourceRoot":"","sources":["../src/federal-register.ts"],"names":[],"mappings":"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"}
|
package/dist/grants.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grants.gov v1 API wrappers (keyless).
|
|
3
|
+
*
|
|
4
|
+
* Grants.gov hosts federal financial-assistance opportunities (grants,
|
|
5
|
+
* cooperative agreements). Distinct from SAM.gov contracts but the
|
|
6
|
+
* same pursuit ICP often cares about both.
|
|
7
|
+
*
|
|
8
|
+
* Endpoints (POST JSON, no key):
|
|
9
|
+
* - /v1/api/search2 — search opportunities
|
|
10
|
+
* - /v1/api/fetchOpportunity — single grant detail
|
|
11
|
+
*
|
|
12
|
+
* Documented at https://grants.gov/web/grants/s2s/grantor/schemas/grants-search-2-soap.html
|
|
13
|
+
*/
|
|
14
|
+
export type GrantStatus = "forecasted" | "posted" | "closed" | "archived";
|
|
15
|
+
export declare function searchGrants(args: {
|
|
16
|
+
keyword?: string;
|
|
17
|
+
cfda?: string;
|
|
18
|
+
agency?: string;
|
|
19
|
+
oppNum?: string;
|
|
20
|
+
oppStatuses?: GrantStatus[];
|
|
21
|
+
rows?: number;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
totalRecords: number;
|
|
24
|
+
grants: {
|
|
25
|
+
id: string;
|
|
26
|
+
opportunityNumber: string;
|
|
27
|
+
title: string;
|
|
28
|
+
agencyCode: string;
|
|
29
|
+
agencyName: string;
|
|
30
|
+
openDate: string | undefined;
|
|
31
|
+
closeDate: string | undefined;
|
|
32
|
+
status: string | undefined;
|
|
33
|
+
docType: string | undefined;
|
|
34
|
+
cfdaList: string | undefined;
|
|
35
|
+
}[];
|
|
36
|
+
}>;
|
|
37
|
+
export declare function getGrant(args: {
|
|
38
|
+
opportunityId: string;
|
|
39
|
+
}): Promise<{
|
|
40
|
+
id: number;
|
|
41
|
+
opportunityNumber: string;
|
|
42
|
+
title: string;
|
|
43
|
+
agency: {
|
|
44
|
+
code: string | undefined;
|
|
45
|
+
name: string | undefined;
|
|
46
|
+
};
|
|
47
|
+
description: string;
|
|
48
|
+
postingDate: string | undefined;
|
|
49
|
+
responseDate: string | undefined;
|
|
50
|
+
archiveDate: string | undefined;
|
|
51
|
+
awardCeiling: number | undefined;
|
|
52
|
+
awardFloor: number | undefined;
|
|
53
|
+
estimatedFunding: number | undefined;
|
|
54
|
+
expectedNumberOfAwards: number | undefined;
|
|
55
|
+
applicantTypes: string[];
|
|
56
|
+
fundingInstruments: string[];
|
|
57
|
+
fundingCategories: string[];
|
|
58
|
+
cfdaPrograms: {
|
|
59
|
+
number: string;
|
|
60
|
+
title: string;
|
|
61
|
+
}[];
|
|
62
|
+
}>;
|
|
63
|
+
//# sourceMappingURL=grants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAoBH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE1E,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;;;;;;;;;;;;;GA+CA;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;oBAoDpC,MAAM,EAAE;wBAGR,MAAM,EAAE;uBAGR,MAAM,EAAE;;;;;GAMjC"}
|
package/dist/grants.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grants.gov v1 API wrappers (keyless).
|
|
3
|
+
*
|
|
4
|
+
* Grants.gov hosts federal financial-assistance opportunities (grants,
|
|
5
|
+
* cooperative agreements). Distinct from SAM.gov contracts but the
|
|
6
|
+
* same pursuit ICP often cares about both.
|
|
7
|
+
*
|
|
8
|
+
* Endpoints (POST JSON, no key):
|
|
9
|
+
* - /v1/api/search2 — search opportunities
|
|
10
|
+
* - /v1/api/fetchOpportunity — single grant detail
|
|
11
|
+
*
|
|
12
|
+
* Documented at https://grants.gov/web/grants/s2s/grantor/schemas/grants-search-2-soap.html
|
|
13
|
+
*/
|
|
14
|
+
const GRANTS = "https://api.grants.gov/v1/api";
|
|
15
|
+
async function postJson(endpoint, body) {
|
|
16
|
+
const r = await fetch(`${GRANTS}/${endpoint}`, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: { "Content-Type": "application/json" },
|
|
19
|
+
body: JSON.stringify(body),
|
|
20
|
+
signal: AbortSignal.timeout(15_000),
|
|
21
|
+
});
|
|
22
|
+
if (!r.ok) {
|
|
23
|
+
throw new Error(`Grants.gov ${endpoint} returned ${r.status}`);
|
|
24
|
+
}
|
|
25
|
+
return (await r.json());
|
|
26
|
+
}
|
|
27
|
+
export async function searchGrants(args) {
|
|
28
|
+
const body = {
|
|
29
|
+
rows: args.rows ?? 10,
|
|
30
|
+
keyword: args.keyword ?? "",
|
|
31
|
+
cfda: args.cfda ?? "",
|
|
32
|
+
agencies: args.agency ?? "",
|
|
33
|
+
oppNum: args.oppNum ?? "",
|
|
34
|
+
oppStatuses: (args.oppStatuses ?? ["forecasted", "posted"]).join("|"),
|
|
35
|
+
};
|
|
36
|
+
const json = await postJson("search2", body);
|
|
37
|
+
if (json.errorcode && json.errorcode !== 0) {
|
|
38
|
+
throw new Error(`Grants.gov error: ${json.msg ?? "unknown"}`);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
totalRecords: json.data?.hitCount ?? 0,
|
|
42
|
+
grants: (json.data?.oppHits ?? []).map((g) => ({
|
|
43
|
+
id: g.id ?? "",
|
|
44
|
+
opportunityNumber: g.number ?? "",
|
|
45
|
+
title: g.title ?? "",
|
|
46
|
+
agencyCode: g.agencyCode ?? "",
|
|
47
|
+
agencyName: g.agencyName ?? "",
|
|
48
|
+
openDate: g.openDate,
|
|
49
|
+
closeDate: g.closeDate,
|
|
50
|
+
status: g.oppStatus,
|
|
51
|
+
docType: g.docType,
|
|
52
|
+
cfdaList: g.cfdaList,
|
|
53
|
+
})),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export async function getGrant(args) {
|
|
57
|
+
const json = await postJson("fetchOpportunity", {
|
|
58
|
+
opportunityId: args.opportunityId,
|
|
59
|
+
});
|
|
60
|
+
if (json.errorcode && json.errorcode !== 0) {
|
|
61
|
+
throw new Error(`Grants.gov error: ${json.msg ?? "unknown"}`);
|
|
62
|
+
}
|
|
63
|
+
const d = json.data ?? {};
|
|
64
|
+
const s = d.synopsis ?? {};
|
|
65
|
+
return {
|
|
66
|
+
id: d.id ?? 0,
|
|
67
|
+
opportunityNumber: d.opportunityNumber ?? "",
|
|
68
|
+
title: d.opportunityTitle ?? "",
|
|
69
|
+
agency: { code: s.agencyCode ?? d.owningAgencyCode, name: s.agencyName },
|
|
70
|
+
description: s.synopsisDesc ?? d.synopsisDesc ?? "",
|
|
71
|
+
postingDate: s.postingDate,
|
|
72
|
+
responseDate: s.responseDate,
|
|
73
|
+
archiveDate: s.archiveDate,
|
|
74
|
+
awardCeiling: s.awardCeiling,
|
|
75
|
+
awardFloor: s.awardFloor,
|
|
76
|
+
estimatedFunding: s.estimatedFunding,
|
|
77
|
+
expectedNumberOfAwards: s.expectedNumberOfAwards,
|
|
78
|
+
applicantTypes: (s.applicantTypes ?? [])
|
|
79
|
+
.map((a) => a.description)
|
|
80
|
+
.filter(Boolean),
|
|
81
|
+
fundingInstruments: (s.fundingInstruments ?? [])
|
|
82
|
+
.map((f) => f.description)
|
|
83
|
+
.filter(Boolean),
|
|
84
|
+
fundingCategories: (s.fundingActivityCategories ?? [])
|
|
85
|
+
.map((f) => f.description)
|
|
86
|
+
.filter(Boolean),
|
|
87
|
+
cfdaPrograms: (d.cfdas ?? []).map((c) => ({
|
|
88
|
+
number: c.cfdaNumber ?? "",
|
|
89
|
+
title: c.programTitle ?? "",
|
|
90
|
+
})),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=grants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grants.js","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,GAAG,+BAA+B,CAAC;AAE/C,KAAK,UAAU,QAAQ,CACrB,QAAgB,EAChB,IAA6B;IAE7B,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,IAAI,QAAQ,EAAE,EAAE;QAC7C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC1B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAM,CAAC;AAC/B,CAAC;AAID,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAOlC;IACC,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,QAAQ,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;QACzB,WAAW,EAAE,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KACtE,CAAC;IAoBF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAO,SAAS,EAAE,IAAI,CAAC,CAAC;IACnD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,CAAC;QACtC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE;YACd,iBAAiB,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;YACjC,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;YAC9B,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;YAC9B,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,MAAM,EAAE,CAAC,CAAC,SAAS;YACnB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAA+B;IA6B5D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAO,kBAAkB,EAAE;QACpD,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC3B,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC;QACb,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,IAAI,EAAE;QAC5C,KAAK,EAAE,CAAC,CAAC,gBAAgB,IAAI,EAAE;QAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE;QACxE,WAAW,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,IAAI,EAAE;QACnD,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;QACpC,sBAAsB,EAAE,CAAC,CAAC,sBAAsB;QAChD,cAAc,EAAE,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC;aACrC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;aACzB,MAAM,CAAC,OAAO,CAAa;QAC9B,kBAAkB,EAAE,CAAC,CAAC,CAAC,kBAAkB,IAAI,EAAE,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;aACzB,MAAM,CAAC,OAAO,CAAa;QAC9B,iBAAiB,EAAE,CAAC,CAAC,CAAC,yBAAyB,IAAI,EAAE,CAAC;aACnD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;aACzB,MAAM,CAAC,OAAO,CAAa;QAC9B,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,MAAM,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;YAC1B,KAAK,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE;SAC5B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @cliwant/mcp-sam-gov/sam-gov — keyless SAM.gov client.
|
|
3
|
+
*
|
|
4
|
+
* Two endpoint layers, one normalized contract:
|
|
5
|
+
* 1. Authenticated `api.sam.gov/opportunities/v2/search` —
|
|
6
|
+
* higher rate limit + full historical archive. Used when the
|
|
7
|
+
* caller passes an API key.
|
|
8
|
+
* 2. Keyless `sam.gov/api/prod/sgs/v1/search/` (HAL JSON) —
|
|
9
|
+
* the same data the SAM.gov website uses to render itself.
|
|
10
|
+
* No registration. Reasonable rate.
|
|
11
|
+
*
|
|
12
|
+
* The client picks layer 1 if an API key is available, falling back
|
|
13
|
+
* to layer 2 transparently. Callers don't have to care.
|
|
14
|
+
*/
|
|
15
|
+
import type { EntitySearchResult, SamGovClientOptions, SamOpportunity, SamSearchFilters, SamSearchResult } from "./types.js";
|
|
16
|
+
export declare class SamGovClient {
|
|
17
|
+
private readonly apiKey?;
|
|
18
|
+
private readonly userAgent;
|
|
19
|
+
private readonly fetchImpl;
|
|
20
|
+
private readonly logger;
|
|
21
|
+
constructor(options?: SamGovClientOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Search SAM.gov opportunities.
|
|
24
|
+
*
|
|
25
|
+
* Three-tier fallback:
|
|
26
|
+
* 1. Authenticated v2 search (if `apiKey` configured)
|
|
27
|
+
* 2. Keyless HAL search
|
|
28
|
+
* 3. Empty result (caller can decide how to surface "no data")
|
|
29
|
+
*/
|
|
30
|
+
searchOpportunities(filters: SamSearchFilters): Promise<SamSearchResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a single opportunity by `noticeId` (32-char hex).
|
|
33
|
+
*
|
|
34
|
+
* Three-tier fallback:
|
|
35
|
+
* 1. Authenticated v2 search filtered by noticeId (if key)
|
|
36
|
+
* 2. Keyless detail endpoint + resources + org enrichment
|
|
37
|
+
* 3. null
|
|
38
|
+
*/
|
|
39
|
+
getOpportunity(noticeId: string): Promise<SamOpportunity | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetch the full description body for an opportunity.
|
|
42
|
+
*
|
|
43
|
+
* Handles three input shapes:
|
|
44
|
+
* 1. Already-extracted text (no `http://`) — pass-through
|
|
45
|
+
* 2. `api.sam.gov/.../v1/api/getDescription/...` — append `?api_key=`
|
|
46
|
+
* 3. Public sam.gov URL — HAL headers, no key
|
|
47
|
+
*/
|
|
48
|
+
fetchOpportunityDescription(input: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Look up registered SAM.gov entities by legal business name.
|
|
51
|
+
* Requires an API key (the entity registration API has no public
|
|
52
|
+
* keyless mirror — it's the one place BYOK is genuinely needed).
|
|
53
|
+
*/
|
|
54
|
+
searchEntities(query: string): Promise<EntitySearchResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Build the keyless download URL for an attachment, given the
|
|
57
|
+
* resourceId from getPublicResourceLinks(). Returns a 303 redirect
|
|
58
|
+
* to a signed S3 URL when fetched. Useful for embedding viewers.
|
|
59
|
+
*/
|
|
60
|
+
publicDownloadUrl(resourceId: string): string;
|
|
61
|
+
private buildAuthSearchUrl;
|
|
62
|
+
private searchPublic;
|
|
63
|
+
private getOpportunityPublic;
|
|
64
|
+
private getPublicResourceLinks;
|
|
65
|
+
private getPublicOrgName;
|
|
66
|
+
private publicHeaders;
|
|
67
|
+
private warn;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/sam-gov/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAC;AASpB,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAE7D,OAAO,GAAE,mBAAwB;IAO7C;;;;;;;OAOG;IACG,mBAAmB,CACvB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC;IA2B3B;;;;;;;OAOG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAqCtE;;;;;;;OAOG;IACG,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsDjE;;;;OAIG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkDhE;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAM7C,OAAO,CAAC,kBAAkB;YA2BZ,YAAY;YAyEZ,oBAAoB;YA8DpB,sBAAsB;YAwBtB,gBAAgB;IAuB9B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,IAAI;CAGb"}
|