@cliwant/mcp-sam-gov 1.3.0 → 1.5.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.
Files changed (149) hide show
  1. package/README.ja.md +20 -12
  2. package/README.ko.md +20 -12
  3. package/README.md +62 -14
  4. package/dist/bea.d.ts +1 -1
  5. package/dist/bea.js +1 -1
  6. package/dist/cbp-border.d.ts +51 -0
  7. package/dist/cbp-border.d.ts.map +1 -0
  8. package/dist/cbp-border.js +123 -0
  9. package/dist/cbp-border.js.map +1 -0
  10. package/dist/census-economic.d.ts +1 -1
  11. package/dist/census-economic.d.ts.map +1 -1
  12. package/dist/census-economic.js +12 -6
  13. package/dist/census-economic.js.map +1 -1
  14. package/dist/cms-facility.d.ts +112 -0
  15. package/dist/cms-facility.d.ts.map +1 -0
  16. package/dist/cms-facility.js +311 -0
  17. package/dist/cms-facility.js.map +1 -0
  18. package/dist/cms-hospital.d.ts +105 -0
  19. package/dist/cms-hospital.d.ts.map +1 -0
  20. package/dist/cms-hospital.js +290 -0
  21. package/dist/cms-hospital.js.map +1 -0
  22. package/dist/cms-supplier.d.ts +133 -0
  23. package/dist/cms-supplier.d.ts.map +1 -0
  24. package/dist/cms-supplier.js +414 -0
  25. package/dist/cms-supplier.js.map +1 -0
  26. package/dist/cms-utilization.d.ts +113 -0
  27. package/dist/cms-utilization.d.ts.map +1 -0
  28. package/dist/cms-utilization.js +328 -0
  29. package/dist/cms-utilization.js.map +1 -0
  30. package/dist/courtlistener.d.ts +115 -0
  31. package/dist/courtlistener.d.ts.map +1 -0
  32. package/dist/courtlistener.js +398 -0
  33. package/dist/courtlistener.js.map +1 -0
  34. package/dist/cpsc.d.ts +81 -0
  35. package/dist/cpsc.d.ts.map +1 -0
  36. package/dist/cpsc.js +283 -0
  37. package/dist/cpsc.js.map +1 -0
  38. package/dist/datagov-catalog.d.ts.map +1 -1
  39. package/dist/datagov-catalog.js +16 -2
  40. package/dist/datagov-catalog.js.map +1 -1
  41. package/dist/dol.d.ts +2 -2
  42. package/dist/dol.js +5 -5
  43. package/dist/dol.js.map +1 -1
  44. package/dist/ecfr.d.ts +2 -2
  45. package/dist/ecfr.d.ts.map +1 -1
  46. package/dist/ecfr.js +24 -10
  47. package/dist/ecfr.js.map +1 -1
  48. package/dist/edgar.d.ts.map +1 -1
  49. package/dist/edgar.js +26 -6
  50. package/dist/edgar.js.map +1 -1
  51. package/dist/epa-envirofacts.d.ts +97 -0
  52. package/dist/epa-envirofacts.d.ts.map +1 -0
  53. package/dist/epa-envirofacts.js +305 -0
  54. package/dist/epa-envirofacts.js.map +1 -0
  55. package/dist/errors.d.ts.map +1 -1
  56. package/dist/errors.js +11 -0
  57. package/dist/errors.js.map +1 -1
  58. package/dist/far.d.ts.map +1 -1
  59. package/dist/far.js +3 -1
  60. package/dist/far.js.map +1 -1
  61. package/dist/federal-register.d.ts +2 -2
  62. package/dist/federal-register.d.ts.map +1 -1
  63. package/dist/federal-register.js +26 -10
  64. package/dist/federal-register.js.map +1 -1
  65. package/dist/fema.d.ts +36 -0
  66. package/dist/fema.d.ts.map +1 -1
  67. package/dist/fema.js +124 -0
  68. package/dist/fema.js.map +1 -1
  69. package/dist/fred.d.ts +1 -1
  70. package/dist/fred.js +1 -1
  71. package/dist/gov-domains.d.ts +66 -0
  72. package/dist/gov-domains.d.ts.map +1 -0
  73. package/dist/gov-domains.js +211 -0
  74. package/dist/gov-domains.js.map +1 -0
  75. package/dist/keys.d.ts +6 -5
  76. package/dist/keys.d.ts.map +1 -1
  77. package/dist/keys.js +25 -6
  78. package/dist/keys.js.map +1 -1
  79. package/dist/nhtsa.d.ts +91 -0
  80. package/dist/nhtsa.d.ts.map +1 -0
  81. package/dist/nhtsa.js +263 -0
  82. package/dist/nhtsa.js.map +1 -0
  83. package/dist/nist-controls.d.ts +48 -0
  84. package/dist/nist-controls.d.ts.map +1 -0
  85. package/dist/nist-controls.js +174 -0
  86. package/dist/nist-controls.js.map +1 -0
  87. package/dist/nonprofit.d.ts +116 -0
  88. package/dist/nonprofit.d.ts.map +1 -0
  89. package/dist/nonprofit.js +342 -0
  90. package/dist/nonprofit.js.map +1 -0
  91. package/dist/nws-weather.d.ts +57 -0
  92. package/dist/nws-weather.d.ts.map +1 -0
  93. package/dist/nws-weather.js +131 -0
  94. package/dist/nws-weather.js.map +1 -0
  95. package/dist/openfda-device.d.ts +85 -0
  96. package/dist/openfda-device.d.ts.map +1 -0
  97. package/dist/openfda-device.js +277 -0
  98. package/dist/openfda-device.js.map +1 -0
  99. package/dist/openfda-drugsfda.d.ts +72 -0
  100. package/dist/openfda-drugsfda.d.ts.map +1 -0
  101. package/dist/openfda-drugsfda.js +230 -0
  102. package/dist/openfda-drugsfda.js.map +1 -0
  103. package/dist/openfda.d.ts +133 -0
  104. package/dist/openfda.d.ts.map +1 -0
  105. package/dist/openfda.js +425 -0
  106. package/dist/openfda.js.map +1 -0
  107. package/dist/server.d.ts.map +1 -1
  108. package/dist/server.js +996 -16
  109. package/dist/server.js.map +1 -1
  110. package/dist/treasury.d.ts +2 -0
  111. package/dist/treasury.d.ts.map +1 -1
  112. package/dist/treasury.js +7 -0
  113. package/dist/treasury.js.map +1 -1
  114. package/dist/usaspending.d.ts +32 -1
  115. package/dist/usaspending.d.ts.map +1 -1
  116. package/dist/usaspending.js +143 -16
  117. package/dist/usaspending.js.map +1 -1
  118. package/package.json +3 -2
  119. package/src/bea.ts +1 -1
  120. package/src/cbp-border.ts +177 -0
  121. package/src/census-economic.ts +12 -6
  122. package/src/cms-facility.ts +379 -0
  123. package/src/cms-hospital.ts +344 -0
  124. package/src/cms-supplier.ts +527 -0
  125. package/src/cms-utilization.ts +389 -0
  126. package/src/courtlistener.ts +465 -0
  127. package/src/cpsc.ts +333 -0
  128. package/src/datagov-catalog.ts +18 -2
  129. package/src/dol.ts +5 -5
  130. package/src/ecfr.ts +27 -10
  131. package/src/edgar.ts +39 -7
  132. package/src/epa-envirofacts.ts +358 -0
  133. package/src/errors.ts +11 -0
  134. package/src/far.ts +3 -1
  135. package/src/federal-register.ts +29 -10
  136. package/src/fema.ts +139 -0
  137. package/src/fred.ts +1 -1
  138. package/src/gov-domains.ts +237 -0
  139. package/src/keys.ts +27 -6
  140. package/src/nhtsa.ts +352 -0
  141. package/src/nist-controls.ts +219 -0
  142. package/src/nonprofit.ts +460 -0
  143. package/src/nws-weather.ts +167 -0
  144. package/src/openfda-device.ts +356 -0
  145. package/src/openfda-drugsfda.ts +313 -0
  146. package/src/openfda.ts +518 -0
  147. package/src/server.ts +1127 -27
  148. package/src/treasury.ts +7 -0
  149. package/src/usaspending.ts +189 -17
@@ -0,0 +1,211 @@
1
+ /**
2
+ * get.gov — the authoritative US .gov domain registry (CISA). KEYLESS.
3
+ *
4
+ * The .gov program (run by CISA) publishes the COMPLETE registry as CSVs in its
5
+ * official repo github.com/cisagov/dotgov-data — the canonical published location
6
+ * (get.gov links there; there is no query API for the full set). It is NOT a .gov
7
+ * API host, so provenance is disclosed on every response (the ProPublica /
8
+ * CourtListener republisher pattern — except here CISA is the first-party registrar).
9
+ *
10
+ * B2G value: resolve WHICH organization owns a .gov domain, enumerate federal
11
+ * agencies, and MAP SLED entities (state / county / city / school-district /
12
+ * special-district / tribal) for market targeting — a distinct authoritative
13
+ * gov-org registry no other tool here exposes.
14
+ *
15
+ * SSRF: fixed host `raw.githubusercontent.com` + fixed path prefix
16
+ * `/cisagov/dotgov-data/main/` + a scope-selected FIXED filename (federal | full) —
17
+ * no free host, path, or filename. `redirect:"error"` on the fetch.
18
+ *
19
+ * PII: the CSV carries a "Security contact email" column (an ORG security mailbox,
20
+ * e.g. security@agency.gov). We DROP it — this tool resolves ORGANIZATIONS, not
21
+ * contacts, and excluding it keeps the output free of contact info.
22
+ *
23
+ * Filtering is CLIENT-SIDE over the full published CSV (the registry has no query
24
+ * API) — disclosed in `_meta.notes`. `totalAvailable` is the EXACT match count.
25
+ */
26
+ import { getText } from "./datasource.js";
27
+ import { driftError } from "./datasource.js";
28
+ import { memoize } from "./cache.js";
29
+ import { withMeta } from "./meta.js";
30
+ export const DOTGOV_HOST = "raw.githubusercontent.com";
31
+ const DOTGOV_PATH_PREFIX = "https://raw.githubusercontent.com/cisagov/dotgov-data/main/";
32
+ // scope → the pinned filename (no free path). "all" = federal + SLED (~16k rows),
33
+ // "federal" = federal only (~1.3k rows).
34
+ const DOTGOV_FILES = {
35
+ all: "current-full.csv",
36
+ federal: "current-federal.csv",
37
+ };
38
+ const SOURCE_LABEL = "getgov:cisagov/dotgov-data";
39
+ const PROVENANCE_NOTE = "Source: the CISA get.gov OFFICIAL .gov domain registry, published as CSV at github.com/cisagov/dotgov-data (the canonical location; get.gov links there). CISA is the first-party .gov registrar; this is authoritative public data served from GitHub, not a .gov API host.";
40
+ const CLIENT_FILTER_NOTE = "The registry has no query API — the full published CSV is fetched and filtered CLIENT-SIDE (organization/domain/city are case-insensitive SUBSTRING matches; state/domainType are case-insensitive). totalAvailable is the EXACT count of matching rows.";
41
+ const FRESHNESS_NOTE = "The CISA dotgov-data CSV is refreshed ~daily; this response reflects the currently-published snapshot (served from a 6-hour cache).";
42
+ const EMAIL_DROP_NOTE = "The registry's 'Security contact email' column (an organization security mailbox) is intentionally EXCLUDED — this tool resolves organizations, not contacts.";
43
+ // ─── Minimal RFC-4180 CSV parser (quoted fields + embedded commas/newlines) ──
44
+ /**
45
+ * Parse a full CSV document into rows of string fields. Handles double-quoted
46
+ * fields, escaped `""` quotes, and commas/newlines INSIDE quotes. Self-contained
47
+ * (no external dep) — the get.gov CSV is small (~1.4 MB) so a whole-string parse is
48
+ * fine. Returns every record's raw field array (including the header row).
49
+ */
50
+ export function parseCsv(text) {
51
+ const rows = [];
52
+ let field = "";
53
+ let row = [];
54
+ let inQuotes = false;
55
+ for (let i = 0; i < text.length; i++) {
56
+ const c = text[i];
57
+ if (inQuotes) {
58
+ if (c === '"') {
59
+ if (text[i + 1] === '"') {
60
+ field += '"';
61
+ i++; // consume the escaped quote
62
+ }
63
+ else {
64
+ inQuotes = false;
65
+ }
66
+ }
67
+ else {
68
+ field += c;
69
+ }
70
+ }
71
+ else if (c === '"') {
72
+ inQuotes = true;
73
+ }
74
+ else if (c === ",") {
75
+ row.push(field);
76
+ field = "";
77
+ }
78
+ else if (c === "\n") {
79
+ row.push(field);
80
+ rows.push(row);
81
+ row = [];
82
+ field = "";
83
+ }
84
+ else if (c === "\r") {
85
+ // CRLF: the \n case pushes the record; ignore the stray CR.
86
+ }
87
+ else {
88
+ field += c;
89
+ }
90
+ }
91
+ // Flush a trailing field/row if the file did not end with a newline.
92
+ if (field.length > 0 || row.length > 0) {
93
+ row.push(field);
94
+ rows.push(row);
95
+ }
96
+ return rows;
97
+ }
98
+ /** Coerce a CSV field to a trimmed non-empty string, else null (never ""). */
99
+ function s(v) {
100
+ if (v === undefined)
101
+ return null;
102
+ const t = v.trim();
103
+ return t.length > 0 ? t : null;
104
+ }
105
+ /**
106
+ * Fetch + parse ONE scope's registry CSV into rows, memoized ~6h. Header-mapped by
107
+ * COLUMN NAME (not fixed index) so an upstream column reorder does not silently
108
+ * mis-map; a missing required header ⇒ schema_drift (never a fake-empty). The
109
+ * "Security contact email" column is dropped at the map step.
110
+ */
111
+ async function loadRegistry(scope) {
112
+ return memoize(`getgov:${scope}`, async () => {
113
+ const url = `${DOTGOV_PATH_PREFIX}${DOTGOV_FILES[scope]}`;
114
+ // Belt-and-suspenders SSRF: the URL is built only from the pinned prefix +
115
+ // pinned filename, but assert it before the fetch.
116
+ const built = new URL(url);
117
+ if (built.hostname !== DOTGOV_HOST || built.protocol !== "https:") {
118
+ throw driftError(SOURCE_LABEL, `Constructed get.gov URL host ${JSON.stringify(built.hostname)} is not ${DOTGOV_HOST} over https — refusing to fetch (SSRF safety).`);
119
+ }
120
+ const text = await getText(url, { label: SOURCE_LABEL, redirect: "error", timeoutMs: 20_000 });
121
+ const rows = parseCsv(text);
122
+ const headerRow = rows[0];
123
+ if (!headerRow) {
124
+ throw driftError(SOURCE_LABEL, "get.gov registry CSV was empty — treating as schema drift, never a fake-empty result.");
125
+ }
126
+ const header = headerRow.map((h) => h.trim());
127
+ const idx = (name) => header.indexOf(name);
128
+ const iDomain = idx("Domain name");
129
+ const iType = idx("Domain type");
130
+ const iOrg = idx("Organization name");
131
+ const iSub = idx("Suborganization name");
132
+ const iCity = idx("City");
133
+ const iState = idx("State");
134
+ // The four load-bearing columns MUST be present (a rename ⇒ schema drift, not a
135
+ // silently mis-mapped/empty result).
136
+ if (iDomain < 0 || iType < 0 || iOrg < 0) {
137
+ throw driftError(SOURCE_LABEL, `get.gov registry CSV header is missing a required column (Domain name / Domain type / Organization name) — schema drift. Got: ${header.join(", ")}.`);
138
+ }
139
+ return rows.slice(1).map((r) => ({
140
+ domain: (r[iDomain] ?? "").trim(),
141
+ domainType: (r[iType] ?? "").trim(),
142
+ organization: (r[iOrg] ?? "").trim(),
143
+ suborganization: iSub >= 0 ? s(r[iSub]) : null,
144
+ city: iCity >= 0 ? s(r[iCity]) : null,
145
+ state: iState >= 0 ? s(r[iState]) : null,
146
+ // NOTE: "Security contact email" is deliberately NOT read/emitted.
147
+ }));
148
+ });
149
+ }
150
+ // ─── Tool: search_gov_domains ─────────────────────────────────────
151
+ /**
152
+ * Search the CISA get.gov .gov domain registry. Client-side filters over the
153
+ * published CSV: organization/domain/city are case-insensitive SUBSTRING matches;
154
+ * state (2-letter) and domainType are case-insensitive. scope 'all' (federal + SLED,
155
+ * default) | 'federal'. Honest `_meta` (exact match total; provenance + client-side
156
+ * disclosure).
157
+ */
158
+ export async function searchGovDomains(args) {
159
+ const scope = args.scope ?? "all";
160
+ const limit = args.limit ?? 50;
161
+ const offset = args.offset ?? 0;
162
+ const all = await loadRegistry(scope);
163
+ const filtersApplied = [];
164
+ const ci = (v) => (v ?? "").toLowerCase();
165
+ const orgQ = ci(args.organization);
166
+ const domQ = ci(args.domain);
167
+ const typeQ = ci(args.domainType);
168
+ const stateQ = ci(args.state);
169
+ const cityQ = ci(args.city);
170
+ if (args.organization !== undefined)
171
+ filtersApplied.push("organization");
172
+ if (args.domain !== undefined)
173
+ filtersApplied.push("domain");
174
+ if (args.domainType !== undefined)
175
+ filtersApplied.push("domainType");
176
+ if (args.state !== undefined)
177
+ filtersApplied.push("state");
178
+ if (args.city !== undefined)
179
+ filtersApplied.push("city");
180
+ const matched = all.filter((row) => {
181
+ if (orgQ && !row.organization.toLowerCase().includes(orgQ))
182
+ return false;
183
+ if (domQ && !row.domain.toLowerCase().includes(domQ))
184
+ return false;
185
+ if (typeQ && !row.domainType.toLowerCase().includes(typeQ))
186
+ return false;
187
+ if (stateQ && (row.state ?? "").toLowerCase() !== stateQ)
188
+ return false;
189
+ if (cityQ && !(row.city ?? "").toLowerCase().includes(cityQ))
190
+ return false;
191
+ return true;
192
+ });
193
+ const totalAvailable = matched.length;
194
+ const page = matched.slice(offset, offset + limit);
195
+ const returned = page.length;
196
+ const hasMore = offset + returned < totalAvailable;
197
+ const nextOffset = hasMore ? offset + returned : null;
198
+ return withMeta({ scope, domains: page }, {
199
+ source: `getgov ${DOTGOV_FILES[scope]} (CISA .gov registry, keyless)`,
200
+ keylessMode: true,
201
+ returned,
202
+ totalAvailable,
203
+ truncated: hasMore,
204
+ filtersApplied,
205
+ filtersDropped: [],
206
+ fieldsUnavailable: ["securityContactEmail (org mailbox — intentionally excluded)"],
207
+ pagination: { offset, limit, hasMore, nextOffset },
208
+ notes: [PROVENANCE_NOTE, CLIENT_FILTER_NOTE, FRESHNESS_NOTE, EMAIL_DROP_NOTE],
209
+ });
210
+ }
211
+ //# sourceMappingURL=gov-domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gov-domains.js","sourceRoot":"","sources":["../src/gov-domains.ts"],"names":[],"mappings":"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"}
package/dist/keys.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Why this exists
5
5
  * ----------------
6
- * The server rides 31 federal sources. MOST are fully keyless. But the set of
6
+ * The server rides dozens of federal data sources. MOST are fully keyless. But the set of
7
7
  * *optional* keys (raise a rate limit, unlock one filter) plus the four *required*
8
8
  * keys (Census business-patterns, FRED, BEA Regional, DOL data) has grown to the point where a user — or
9
9
  * the AI driving the server — cannot tell, without reading source code:
@@ -20,8 +20,9 @@
20
20
  * `process.env.<NAME>` — DATA_GOV_API_KEY (datagovKey.ts), SAM_GOV_API_KEY
21
21
  * (server.ts), BLS_API_KEY (bls.ts), NVD_API_KEY (nvd.ts), SOCRATA_APP_TOKEN
22
22
  * (socrata.ts), CENSUS_API_KEY (census-economic.ts), FRED_API_KEY (fred.ts),
23
- * BEA_API_KEY (bea.ts), DOL_API_KEY (dol.ts), LDA_API_KEY (lda.ts). No invented
24
- * keys, sources, or signup URLs.
23
+ * BEA_API_KEY (bea.ts), DOL_API_KEY (dol.ts), LDA_API_KEY (lda.ts),
24
+ * OPENFDA_API_KEY (openfda.ts), COURTLISTENER_API_TOKEN (courtlistener.ts).
25
+ * No invented keys, sources, or signup URLs.
25
26
  */
26
27
  /** One registry entry describing a single API key the server can use. */
27
28
  export type KeyRegistryEntry = {
@@ -39,11 +40,11 @@ export type KeyRegistryEntry = {
39
40
  note: string;
40
41
  };
41
42
  /**
42
- * The 10 keys the server reads — code-grounded, no inventions.
43
+ * The 12 keys the server reads — code-grounded, no inventions.
43
44
  *
44
45
  * REQUIRED (4): CENSUS_API_KEY, FRED_API_KEY, BEA_API_KEY, DOL_API_KEY — those sources
45
46
  * have no keyless tier, so the tool throws without them (DOL_API_KEY gates ONLY
46
- * dol_get_dataset; the DOL catalog, dol_list_datasets, is keyless). OPTIONAL (6):
47
+ * dol_get_dataset; the DOL catalog, dol_list_datasets, is keyless). OPTIONAL (8):
47
48
  * everything else works keyless; a key only raises a rate limit or unlocks a single filter.
48
49
  */
49
50
  export declare const KEY_REGISTRY: readonly KeyRegistryEntry[];
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,gBAAgB,EA8F1C,CAAC;AAQX,sFAAsF;AACtF,MAAM,MAAM,SAAS,GAAG,gBAAgB,GAAG;IAAE,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC;AAErE,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,sFAAsF;IACtF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kDAAkD;IAClD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAYjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CA4C/C"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,gBAAgB,EAkH1C,CAAC;AAQX,sFAAsF;AACtF,MAAM,MAAM,SAAS,GAAG,gBAAgB,GAAG;IAAE,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC;AAErE,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,sFAAsF;IACtF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kDAAkD;IAClD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAYjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CA4C/C"}
package/dist/keys.js CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Why this exists
5
5
  * ----------------
6
- * The server rides 31 federal sources. MOST are fully keyless. But the set of
6
+ * The server rides dozens of federal data sources. MOST are fully keyless. But the set of
7
7
  * *optional* keys (raise a rate limit, unlock one filter) plus the four *required*
8
8
  * keys (Census business-patterns, FRED, BEA Regional, DOL data) has grown to the point where a user — or
9
9
  * the AI driving the server — cannot tell, without reading source code:
@@ -20,17 +20,18 @@
20
20
  * `process.env.<NAME>` — DATA_GOV_API_KEY (datagovKey.ts), SAM_GOV_API_KEY
21
21
  * (server.ts), BLS_API_KEY (bls.ts), NVD_API_KEY (nvd.ts), SOCRATA_APP_TOKEN
22
22
  * (socrata.ts), CENSUS_API_KEY (census-economic.ts), FRED_API_KEY (fred.ts),
23
- * BEA_API_KEY (bea.ts), DOL_API_KEY (dol.ts), LDA_API_KEY (lda.ts). No invented
24
- * keys, sources, or signup URLs.
23
+ * BEA_API_KEY (bea.ts), DOL_API_KEY (dol.ts), LDA_API_KEY (lda.ts),
24
+ * OPENFDA_API_KEY (openfda.ts), COURTLISTENER_API_TOKEN (courtlistener.ts).
25
+ * No invented keys, sources, or signup URLs.
25
26
  */
26
27
  import { readFileSync } from "node:fs";
27
28
  import { join } from "node:path";
28
29
  /**
29
- * The 10 keys the server reads — code-grounded, no inventions.
30
+ * The 12 keys the server reads — code-grounded, no inventions.
30
31
  *
31
32
  * REQUIRED (4): CENSUS_API_KEY, FRED_API_KEY, BEA_API_KEY, DOL_API_KEY — those sources
32
33
  * have no keyless tier, so the tool throws without them (DOL_API_KEY gates ONLY
33
- * dol_get_dataset; the DOL catalog, dol_list_datasets, is keyless). OPTIONAL (6):
34
+ * dol_get_dataset; the DOL catalog, dol_list_datasets, is keyless). OPTIONAL (8):
34
35
  * everything else works keyless; a key only raises a rate limit or unlocks a single filter.
35
36
  */
36
37
  export const KEY_REGISTRY = [
@@ -106,7 +107,7 @@ export const KEY_REGISTRY = [
106
107
  "US DOL enforcement data (dol_get_dataset; dol_list_datasets is keyless)",
107
108
  ],
108
109
  required: true,
109
- signupUrl: "https://dol.gov/developer",
110
+ signupUrl: "https://dataportal.dol.gov/registration",
110
111
  unlocks: "the dol_get_dataset tool (dataset records need a free key; dol_list_datasets works keyless)",
111
112
  note: "The DOL data endpoint needs a free key; the dataset CATALOG (dol_list_datasets) and agency list are keyless.",
112
113
  },
@@ -118,6 +119,24 @@ export const KEY_REGISTRY = [
118
119
  unlocks: "higher LDA API rate limits (anonymous access already works without it)",
119
120
  note: "Keyless by default (anonymous 200); a free token only raises the rate limit.",
120
121
  },
122
+ {
123
+ envVar: "OPENFDA_API_KEY",
124
+ sources: ["openFDA enforcement (openfda_enforcement)"],
125
+ required: false,
126
+ signupUrl: "https://open.fda.gov/apis/authentication/",
127
+ unlocks: "higher openFDA rate limits (keyless works without it — ~1000/day)",
128
+ note: "Keyless by default; a free key raises the rate limit.",
129
+ },
130
+ {
131
+ envVar: "COURTLISTENER_API_TOKEN",
132
+ sources: [
133
+ "CourtListener federal court opinions (courtlistener_search_opinions)",
134
+ ],
135
+ required: false,
136
+ signupUrl: "https://www.courtlistener.com/help/api/rest/",
137
+ unlocks: "higher CourtListener rate limits (anonymous search works without it)",
138
+ note: "Keyless by default (anonymous 200); a free token only raises the rate limit. Data = US federal court public records via CourtListener/Free Law Project.",
139
+ },
121
140
  ];
122
141
  /** true iff the env var is set to a non-empty (after-trim) string. */
123
142
  function isSet(envVar) {
package/dist/keys.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * nhtsa.ts — NHTSA VEHICLE SAFETY (api.nhtsa.gov) — the vehicle / parts /
3
+ * fleet supplier PRODUCT-SAFETY vetting lane (ADR-0057). Two keyless tools:
4
+ * • nhtsa_recalls — /recalls/recallsByVehicle?make=&model=&modelYear=
5
+ * • nhtsa_complaints — /complaints/complaintsByVehicle?make=&model=&modelYear=
6
+ * The cross-agency product-safety family alongside openFDA (medical) / CPSC
7
+ * (consumer goods): a manufacturer/component/safety-signal history for B2G
8
+ * supplier vetting.
9
+ *
10
+ * ★ KEYLESS — there is NO API key at all (no parameter, no header). This module
11
+ * touches NO key seam (no KEY_REGISTRY / keys.ts / API_KEYS.md). It REUSES the
12
+ * shared `getJson` (redirect:"error") / `driftError` fetch envelope, the `num`/
13
+ * `str` coercions (null-never-empty-string; a genuine 0 stays 0), and
14
+ * `withMeta`/`buildMeta` — and mirrors datagov-catalog.ts's fixed-host SSRF
15
+ * idiom + schema_drift catch-ladder verbatim.
16
+ *
17
+ * ★ PII — the complaints upstream response carries a `vin` field (an individual
18
+ * vehicle identifier). It is DELIBERATELY OMITTED from the curated output
19
+ * entirely — never surfaced, logged, or stored. The B2G value is the
20
+ * manufacturer / component / safety signal, NOT the VIN.
21
+ *
22
+ * ★ THE HONESTY PILLARS (P1-P4, live-verified 2026-07-15):
23
+ * P1: totalAvailable = `Count` (recalls) / `count` (complaints) — the REAL total.
24
+ * NHTSA returns the COMPLETE filtered set (no pagination), so in the normal
25
+ * case Count === results.length ⇒ complete:true. totalAvailable is NEVER
26
+ * fabricated: a PRESENT numeric Count is trusted verbatim; a MISSING Count
27
+ * falls back to results.length WITH an honest note (never invented).
28
+ * P2: results:[] (Count 0) ⇒ an HONEST EMPTY (returned:0, complete:true) — a bad
29
+ * make/model that returns 200+Count 0 is an honest no-match, NOT an error. A
30
+ * 4xx ⇒ invalid_input; a 5xx/timeout ⇒ THROW (never a fake empty); a 200
31
+ * non-JSON body ⇒ schema_drift.
32
+ * P3: booleans (crash/fire/parkIt/parkOutSide/overTheAirUpdate) preserved AS
33
+ * booleans (a non-boolean ⇒ null, never a fabricated false); counts
34
+ * (numberOfInjuries/numberOfDeaths) via `num` (a genuine 0 stays 0, NEVER
35
+ * null-for-0); dates as strings via `str`; Count/count via `num`.
36
+ * P4: `results` non-array ⇒ driftError; a Count/count that is PRESENT but a
37
+ * non-number ⇒ driftError (a broken total contract, never a fabricated empty).
38
+ * SSRF: fixed host `api.nhtsa.gov` (compile-time literal) + post-construction
39
+ * hostname/protocol assertion + redirect:"error"; make/model ride
40
+ * URLSearchParams (module-built, no raw passthrough); modelYear is
41
+ * ^\d{4}$; make/model are charclass-validated (letters/digits/space/hyphen,
42
+ * so a `../` or `%` can never reach the fixed path).
43
+ */
44
+ import { type MetaBundle } from "./meta.js";
45
+ export declare const NHTSA_HOST = "api.nhtsa.gov";
46
+ export declare const NHTSA_MODEL_YEAR_RE: RegExp;
47
+ export declare const NHTSA_MAKE_MODEL_RE: RegExp;
48
+ export type NhtsaVehicleArgs = {
49
+ make: string;
50
+ model: string;
51
+ modelYear: string;
52
+ };
53
+ export type NhtsaRecall = {
54
+ campaignNumber: string | null;
55
+ manufacturer: string | null;
56
+ component: string | null;
57
+ summary: string | null;
58
+ consequence: string | null;
59
+ remedy: string | null;
60
+ reportReceivedDate: string | null;
61
+ parkIt: boolean | null;
62
+ parkOutside: boolean | null;
63
+ overTheAirUpdate: boolean | null;
64
+ };
65
+ export type NhtsaComplaint = {
66
+ odiNumber: string | null;
67
+ manufacturer: string | null;
68
+ component: string | null;
69
+ summary: string | null;
70
+ crash: boolean | null;
71
+ fire: boolean | null;
72
+ numberOfInjuries: number | null;
73
+ numberOfDeaths: number | null;
74
+ dateOfIncident: string | null;
75
+ dateComplaintFiled: string | null;
76
+ };
77
+ /**
78
+ * Fetch NHTSA safety RECALLS for a make/model/modelYear → curated recall rows +
79
+ * honest `_meta`. KEYLESS. totalAvailable = the upstream `Count` (the REAL total —
80
+ * NHTSA returns the complete set, no pagination). A no-match (Count 0) ⇒ an honest
81
+ * empty; a 4xx ⇒ invalid_input; a 5xx/timeout ⇒ THROW; a 200 non-JSON ⇒ drift.
82
+ */
83
+ export declare function recalls(args: NhtsaVehicleArgs): Promise<MetaBundle>;
84
+ /**
85
+ * Fetch NHTSA consumer COMPLAINTS for a make/model/modelYear → curated complaint
86
+ * rows (★NO vin — PII omitted) + honest `_meta`. KEYLESS. totalAvailable = the
87
+ * upstream `count` (the REAL total). A no-match ⇒ honest empty; a 4xx ⇒
88
+ * invalid_input; a 5xx/timeout ⇒ THROW; a 200 non-JSON ⇒ drift.
89
+ */
90
+ export declare function complaints(args: NhtsaVehicleArgs): Promise<MetaBundle>;
91
+ //# sourceMappingURL=nhtsa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nhtsa.d.ts","sourceRoot":"","sources":["../src/nhtsa.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAKH,OAAO,EAAY,KAAK,UAAU,EAAqB,MAAM,WAAW,CAAC;AAGzE,eAAO,MAAM,UAAU,kBAAkB,CAAC;AAY1C,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAC7C,eAAO,MAAM,mBAAmB,QAAqB,CAAC;AActD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAiHF,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AA4CF;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmCzE;AAGD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuC5E"}