@cliwant/mcp-sam-gov 1.8.0 → 1.10.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.ja.md +5 -5
- package/README.ko.md +5 -5
- package/README.md +8 -7
- package/dist/arcgis-feature.d.ts +68 -0
- package/dist/arcgis-feature.d.ts.map +1 -0
- package/dist/arcgis-feature.js +206 -0
- package/dist/arcgis-feature.js.map +1 -0
- package/dist/arcgis-hub.d.ts +90 -0
- package/dist/arcgis-hub.d.ts.map +1 -0
- package/dist/arcgis-hub.js +210 -0
- package/dist/arcgis-hub.js.map +1 -0
- package/dist/bonfire.d.ts +69 -0
- package/dist/bonfire.d.ts.map +1 -0
- package/dist/bonfire.js +208 -0
- package/dist/bonfire.js.map +1 -0
- package/dist/ecfr.d.ts +14 -0
- package/dist/ecfr.d.ts.map +1 -1
- package/dist/ecfr.js +127 -1
- package/dist/ecfr.js.map +1 -1
- package/dist/opengov.d.ts +96 -0
- package/dist/opengov.d.ts.map +1 -0
- package/dist/opengov.js +244 -0
- package/dist/opengov.js.map +1 -0
- package/dist/pricing.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +189 -3
- package/dist/server.js.map +1 -1
- package/dist/socrata.d.ts +27 -16
- package/dist/socrata.d.ts.map +1 -1
- package/dist/socrata.js +128 -18
- package/dist/socrata.js.map +1 -1
- package/package.json +2 -2
- package/src/arcgis-feature.ts +232 -0
- package/src/arcgis-hub.ts +270 -0
- package/src/bonfire.ts +245 -0
- package/src/ecfr.ts +154 -1
- package/src/opengov.ts +309 -0
- package/src/server.ts +203 -3
- package/src/socrata.ts +132 -18
package/dist/socrata.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Socrata / SODA — keyless open data for state / local (SLED) + E-rate portals.
|
|
2
|
+
* Socrata / SODA — keyless open data for state / local (SLED) + federal + E-rate portals.
|
|
3
3
|
*
|
|
4
4
|
* First SLED source (ADR-0004); 3rd consumer of the fetch/map/meta shape after
|
|
5
5
|
* treasury.ts / edgar.ts. Fully PUBLIC, KEYLESS. ONE connector reaches ~a dozen
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 4x4 dataset id. Hosts are a CURATED allowlist (see SSRF below); the caller
|
|
8
8
|
* never supplies a free host or a free path.
|
|
9
9
|
* Row query: https://{domain}/resource/{4x4}.json?$select=…&$where=…&$limit=…
|
|
10
|
-
* Catalog:
|
|
10
|
+
* Catalog (host-scoped): https://{domain}/api/catalog/v1?search_context={domain}&q=…
|
|
11
|
+
* Catalog (all-host): https://api.us.socrata.com/api/catalog/v1?domains=…&q=…
|
|
11
12
|
*
|
|
12
13
|
* Three layers (mirror treasury.ts / edgar.ts):
|
|
13
14
|
* fetch — `getSocrataResource` / `getCatalog`: SSRF-guard, build the URL,
|
|
@@ -67,14 +68,19 @@
|
|
|
67
68
|
* wrong shape (possible upstream API change). A hard schema_drift throw is
|
|
68
69
|
* reserved for a PRIMARY query (rows / catalog), NEVER the secondary count.
|
|
69
70
|
*
|
|
70
|
-
* ALLOWLIST —
|
|
71
|
-
*
|
|
71
|
+
* ALLOWLIST — each entry carries a real sample 4x4, live-verified on its tier's
|
|
72
|
+
* date (base state slice 2026-07-10; local + major-city + federal 2026-07-18).
|
|
73
|
+
* All `.gov` except the documented non-.gov exceptions: `opendata.usac.org` and
|
|
74
|
+
* the four major-city portals (.us/.org — see the inline blocks below):
|
|
72
75
|
* m6 — `opendata.usac.org` is a `.org` (USAC, a Congress-designated non-profit;
|
|
73
76
|
* E-rate). It is on the periodic re-verification checklist. NOTE: the
|
|
74
|
-
*
|
|
75
|
-
* (
|
|
76
|
-
* surface it
|
|
77
|
-
* (
|
|
77
|
+
* FEDERATED discovery catalog (api.us.socrata.com) does NOT index USAC
|
|
78
|
+
* (resultSetSize 0), so the ALL-HOST `socrata_discover_datasets` (domain
|
|
79
|
+
* omitted) won't surface it; as of loop cycle 8 a DOMAIN-scoped discover
|
|
80
|
+
* uses USAC's own catalog (search_context) and DOES surface it (live:
|
|
81
|
+
* opendata.usac.org/api/catalog/v1?search_context=… → resultSetSize 8).
|
|
82
|
+
* `socrata_query` works regardless with a known 4x4 (live:
|
|
83
|
+
* opendata.usac.org/resource/avi8-svp9.json → 200 bare array).
|
|
78
84
|
* M1 — MA is DROPPED from slice 1: `cthru.data.socrata.com` is a commercial
|
|
79
85
|
* vendor host (Tyler Technologies `.socrata.com`, not gov-controlled) and
|
|
80
86
|
* no `.gov` MA Socrata host verifies (`data.mass.gov` → the catalog
|
|
@@ -103,7 +109,7 @@
|
|
|
103
109
|
import { num } from "./coerce.js";
|
|
104
110
|
import { type MetaBundle } from "./meta.js";
|
|
105
111
|
export { num };
|
|
106
|
-
export declare const SOCRATA_DOMAINS: readonly ["data.ny.gov", "data.colorado.gov", "data.ct.gov", "data.texas.gov", "data.wa.gov", "opendata.maryland.gov", "data.vermont.gov", "data.nj.gov", "data.oregon.gov", "data.pa.gov", "data.mo.gov", "data.delaware.gov", "opendata.usac.org"];
|
|
112
|
+
export declare const SOCRATA_DOMAINS: readonly ["data.ny.gov", "data.colorado.gov", "data.ct.gov", "data.texas.gov", "data.wa.gov", "opendata.maryland.gov", "data.vermont.gov", "data.nj.gov", "data.oregon.gov", "data.pa.gov", "data.mo.gov", "data.delaware.gov", "data.austintexas.gov", "data.kingcounty.gov", "data.montgomerycountymd.gov", "data.mesaaz.gov", "data.cambridgema.gov", "data.transportation.gov", "data.cdc.gov", "data.bts.gov", "datacatalog.cookcountyil.gov", "data.illinois.gov", "data.cincinnati-oh.gov", "data.cityofnewyork.us", "data.cityofchicago.org", "data.sfgov.org", "controllerdata.lacity.org", "opendata.usac.org", "data.kcmo.org", "data.brla.gov", "www.dallasopendata.com", "data.lacity.org", "data.ramseycountymn.gov", "data.richmondgov.com"];
|
|
107
113
|
export type SocrataDomain = (typeof SOCRATA_DOMAINS)[number];
|
|
108
114
|
export type SocrataRow = Record<string, unknown>;
|
|
109
115
|
/**
|
|
@@ -138,16 +144,21 @@ export type CatalogDataset = {
|
|
|
138
144
|
link: string | null;
|
|
139
145
|
};
|
|
140
146
|
/**
|
|
141
|
-
* Discover dataset 4x4 ids via the Socrata catalog (memoized ~10 min).
|
|
142
|
-
* `domain`
|
|
143
|
-
*
|
|
144
|
-
*
|
|
147
|
+
* Discover dataset 4x4 ids via the Socrata catalog (memoized ~10 min). Passing a
|
|
148
|
+
* `domain` queries that portal's OWN catalog (search_context) — a COMPLETE
|
|
149
|
+
* per-host index; omitting it searches the WHOLE allowlist via the federated
|
|
150
|
+
* api.us.socrata.com aggregator (repeated `domains=`). Returns `[{ id, name,
|
|
151
|
+
* description, domain, updatedAt, link }]` + `totalAvailable = resultSetSize`.
|
|
152
|
+
* Feeds `datasetId` to socrata_query.
|
|
145
153
|
*
|
|
146
154
|
* m3 — this is the catalog's PRIMARY response: a non-number `resultSetSize` is a
|
|
147
155
|
* hard schema_drift throw (nothing valid to return), never a fabricated total.
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
156
|
+
*
|
|
157
|
+
* UNDER-INDEX (loop cycle 8 fix): the FEDERATED aggregator under-indexes many
|
|
158
|
+
* hosts (USAC → 0; DOT → 3 of 1,873), so the all-host search (domain omitted) can
|
|
159
|
+
* miss datasets — its `_meta` note discloses this. A DOMAIN-scoped search now
|
|
160
|
+
* uses that host's OWN catalog, which indexes it completely (USAC/DOT/etc. fully
|
|
161
|
+
* discoverable). socrata_query works regardless with a known 4x4.
|
|
151
162
|
*/
|
|
152
163
|
export declare function discoverDatasets(args: {
|
|
153
164
|
q: string;
|
package/dist/socrata.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socrata.d.ts","sourceRoot":"","sources":["../src/socrata.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"socrata.d.ts","sourceRoot":"","sources":["../src/socrata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2GG;AAIH,OAAO,EAAE,GAAG,EAAO,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAY,KAAK,UAAU,EAAqB,MAAM,WAAW,CAAC;AAKzE,OAAO,EAAE,GAAG,EAAE,CAAC;AAOf,eAAO,MAAM,eAAe,6tBAuElB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAyC7D,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAuKjD;;;;;;;;;;;GAWG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkGtB;AAGD,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAqBF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmEtB"}
|
package/dist/socrata.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Socrata / SODA — keyless open data for state / local (SLED) + E-rate portals.
|
|
2
|
+
* Socrata / SODA — keyless open data for state / local (SLED) + federal + E-rate portals.
|
|
3
3
|
*
|
|
4
4
|
* First SLED source (ADR-0004); 3rd consumer of the fetch/map/meta shape after
|
|
5
5
|
* treasury.ts / edgar.ts. Fully PUBLIC, KEYLESS. ONE connector reaches ~a dozen
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 4x4 dataset id. Hosts are a CURATED allowlist (see SSRF below); the caller
|
|
8
8
|
* never supplies a free host or a free path.
|
|
9
9
|
* Row query: https://{domain}/resource/{4x4}.json?$select=…&$where=…&$limit=…
|
|
10
|
-
* Catalog:
|
|
10
|
+
* Catalog (host-scoped): https://{domain}/api/catalog/v1?search_context={domain}&q=…
|
|
11
|
+
* Catalog (all-host): https://api.us.socrata.com/api/catalog/v1?domains=…&q=…
|
|
11
12
|
*
|
|
12
13
|
* Three layers (mirror treasury.ts / edgar.ts):
|
|
13
14
|
* fetch — `getSocrataResource` / `getCatalog`: SSRF-guard, build the URL,
|
|
@@ -67,14 +68,19 @@
|
|
|
67
68
|
* wrong shape (possible upstream API change). A hard schema_drift throw is
|
|
68
69
|
* reserved for a PRIMARY query (rows / catalog), NEVER the secondary count.
|
|
69
70
|
*
|
|
70
|
-
* ALLOWLIST —
|
|
71
|
-
*
|
|
71
|
+
* ALLOWLIST — each entry carries a real sample 4x4, live-verified on its tier's
|
|
72
|
+
* date (base state slice 2026-07-10; local + major-city + federal 2026-07-18).
|
|
73
|
+
* All `.gov` except the documented non-.gov exceptions: `opendata.usac.org` and
|
|
74
|
+
* the four major-city portals (.us/.org — see the inline blocks below):
|
|
72
75
|
* m6 — `opendata.usac.org` is a `.org` (USAC, a Congress-designated non-profit;
|
|
73
76
|
* E-rate). It is on the periodic re-verification checklist. NOTE: the
|
|
74
|
-
*
|
|
75
|
-
* (
|
|
76
|
-
* surface it
|
|
77
|
-
* (
|
|
77
|
+
* FEDERATED discovery catalog (api.us.socrata.com) does NOT index USAC
|
|
78
|
+
* (resultSetSize 0), so the ALL-HOST `socrata_discover_datasets` (domain
|
|
79
|
+
* omitted) won't surface it; as of loop cycle 8 a DOMAIN-scoped discover
|
|
80
|
+
* uses USAC's own catalog (search_context) and DOES surface it (live:
|
|
81
|
+
* opendata.usac.org/api/catalog/v1?search_context=… → resultSetSize 8).
|
|
82
|
+
* `socrata_query` works regardless with a known 4x4 (live:
|
|
83
|
+
* opendata.usac.org/resource/avi8-svp9.json → 200 bare array).
|
|
78
84
|
* M1 — MA is DROPPED from slice 1: `cthru.data.socrata.com` is a commercial
|
|
79
85
|
* vendor host (Tyler Technologies `.socrata.com`, not gov-controlled) and
|
|
80
86
|
* no `.gov` MA Socrata host verifies (`data.mass.gov` → the catalog
|
|
@@ -127,7 +133,64 @@ export const SOCRATA_DOMAINS = [
|
|
|
127
133
|
"data.pa.gov", // PA — e.g. mcba-yywm
|
|
128
134
|
"data.mo.gov", // MO — e.g. gfq7-aa86
|
|
129
135
|
"data.delaware.gov", // DE — e.g. 5zy2-grhr
|
|
136
|
+
// ── SLED city/county tier (loop cycle 1, 2026-07-18; host-scoped catalog +
|
|
137
|
+
// /resource/<4x4>.json 200 bare-array live-verified; all .gov; B2G
|
|
138
|
+
// procurement/vendor/contract data — the fragmented local layer above the
|
|
139
|
+
// state portals). ─────────────────────────────────────────────────────
|
|
140
|
+
"data.austintexas.gov", // Austin TX (city) — e.g. 3ebq-e9iz (Purchase Orders)
|
|
141
|
+
"data.kingcounty.gov", // King County WA — e.g. dqit-zt74 (Procurement Contracts)
|
|
142
|
+
"data.montgomerycountymd.gov", // Montgomery County MD — e.g. vmu2-pnrc (Contracts)
|
|
143
|
+
"data.mesaaz.gov", // Mesa AZ (city) — e.g. j7s9-qiuq (Vendor Payments)
|
|
144
|
+
"data.cambridgema.gov", // Cambridge MA (city) — e.g. gp98-ja4f (Contracts bid list)
|
|
145
|
+
// ── Federal open-data portal tier (loop cycle 7, 2026-07-18). The FIRST
|
|
146
|
+
// federal Socrata hosts (prior tiers were state + local only); all .gov,
|
|
147
|
+
// host-scoped catalog + /resource/<4x4>.json 200 bare-array + count(*)
|
|
148
|
+
// companion live-verified. High-value B2G federal datasets (carrier/company
|
|
149
|
+
// census, transportation infrastructure & stats, public health).
|
|
150
|
+
// NOTE (m3/under-index): the FEDERATED aggregator (api.us.socrata.com)
|
|
151
|
+
// under-indexes these hosts (DOT: 3 federated vs 1,873 host-scoped). As of
|
|
152
|
+
// loop cycle 8, `socrata_discover_datasets` WITH a domain uses each host's
|
|
153
|
+
// OWN catalog (search_context) → complete per-host discovery; only the
|
|
154
|
+
// all-host search (domain omitted) still relies on the federated aggregator
|
|
155
|
+
// (its `_meta` note discloses the gap). ──────────────────────────────────
|
|
156
|
+
"data.transportation.gov", // US DOT — e.g. az4n-8mr2 (Company Census File, ~4.47M carriers)
|
|
157
|
+
"data.cdc.gov", // US CDC — e.g. 9bhg-hcku (Provisional COVID-19 Deaths)
|
|
158
|
+
"data.bts.gov", // US BTS (DOT) — e.g. keg4-3bc2 (Border Crossing Entry Data)
|
|
159
|
+
// ── SLED procurement bid-catalog tier (loop cycle 11, 2026-07-19; from the
|
|
160
|
+
// exhaustive US state+local bid-site research). All .gov; host-scoped catalog
|
|
161
|
+
// + /resource/<4x4>.json 200 bare-array live-verified. Distinctive value:
|
|
162
|
+
// these carry LIVE bid-cycle data (bid tabulations / anticipated
|
|
163
|
+
// solicitations), not only award/spend. (★4 other candidate hosts —
|
|
164
|
+
// data.iowa.gov, data.scottsdaleaz.gov, data.gilbertaz.gov, opendata.hawaii.gov
|
|
165
|
+
// — were REJECTED: their /api/catalog/v1 AND /resource endpoints 404 (Next.js/
|
|
166
|
+
// Express apps, not Socrata — a research-agent "Socrata" claim that live
|
|
167
|
+
// verification disproved). Never add a host without a 200 bare-array probe.) ─
|
|
168
|
+
"datacatalog.cookcountyil.gov", // Cook County IL — e.g. 32au-zaqn (Bid Tabulations ~5,607; +awards qh8j-6k63, intent-to-award bgq7-v7ms — 17 procurement datasets)
|
|
169
|
+
"data.illinois.gov", // IL — e.g. 6rb8-ntpm (Future Solicitations = anticipated construction bids); re-included (cycle-1 excluded on federated-discover 0, but host-scoped catalog + /resource verified 2026-07-19)
|
|
170
|
+
"data.cincinnati-oh.gov", // Cincinnati OH (city) — e.g. 2iq3-bugw (Certified Vendors MBE/WBE; +contracts 85xi-xdtw)
|
|
171
|
+
// ── Major-city OFFICIAL portals (loop cycle 5, 2026-07-18). NON-.gov but the
|
|
172
|
+
// unambiguously-official municipal open-data portals for the largest local
|
|
173
|
+
// procurement markets (NYC OpenData / Chicago / DataSF / LA Controller) —
|
|
174
|
+
// host-scoped catalog + /resource 200 bare-array verified. Trust-boundary
|
|
175
|
+
// (like the USAC .org exception): the SSRF guard is the CURATED, FROZEN
|
|
176
|
+
// allowlist, not the TLD; these five are the documented non-.gov entries. ──
|
|
177
|
+
"data.cityofnewyork.us", // NYC OpenData (.us, official) — e.g. dg92-zbpx (City Record: procurement notices)
|
|
178
|
+
"data.cityofchicago.org", // Chicago (.org, official) — e.g. rsxa-ify5 (Contracts)
|
|
179
|
+
"data.sfgov.org", // San Francisco / DataSF (.org, official) — e.g. cqi5-hm2d (Supplier Contracts)
|
|
180
|
+
"controllerdata.lacity.org", // LA City Controller (.org, official) — e.g. pggv-e4fn (Checkbook L.A.)
|
|
130
181
|
"opendata.usac.org", // USAC E-rate (.org, m6) — e.g. avi8-svp9
|
|
182
|
+
// ── County/city procurement sweep (loop cycle 17, 2026-07-20). Discovered via
|
|
183
|
+
// the Socrata federated catalog (api.us.socrata.com) filtered to procurement/
|
|
184
|
+
// bid/contract datasets, then each host-scoped $select=count(*) + /resource
|
|
185
|
+
// 200 bare-array live-verified. US local govs only (Canada/AU + demo/test +
|
|
186
|
+
// off-theme aggregate hosts filtered out). Mix of official .gov/.org/.com
|
|
187
|
+
// municipal portals (same documented non-.gov trust-boundary as above). ──
|
|
188
|
+
"data.kcmo.org", // Kansas City MO (.org, official) — e.g. 4mdg-usvj (Vendor Payments ~144k; 22 procurement datasets)
|
|
189
|
+
"data.brla.gov", // Baton Rouge / East Baton Rouge Parish LA (.gov) — e.g. e5pk-us93 (Upcoming Procurement Opportunities; 19 procurement datasets)
|
|
190
|
+
"www.dallasopendata.com", // Dallas TX (.com, official) — e.g. x5ih-idh7 (Vendor Payments FY2019–present ~166k)
|
|
191
|
+
"data.lacity.org", // Los Angeles CA (.org, official) — e.g. hf3r-utnq (RAMP Open Bid Opportunities — live bids)
|
|
192
|
+
"data.ramseycountymn.gov", // Ramsey County MN (.gov) — e.g. iu7r-dzmj (Solicitations & Addenda, with due_date/download_url ~516)
|
|
193
|
+
"data.richmondgov.com", // Richmond VA (.com, official) — e.g. xqn7-jvv2 (City Contracts: contract_value/supplier/procurement_type ~1,387)
|
|
131
194
|
];
|
|
132
195
|
const SOCRATA_DOMAIN_SET = new Set(SOCRATA_DOMAINS);
|
|
133
196
|
const CATALOG_HOST = "api.us.socrata.com";
|
|
@@ -230,6 +293,40 @@ async function getCatalog(params) {
|
|
|
230
293
|
redirect: "error",
|
|
231
294
|
});
|
|
232
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* GET a HOST-SCOPED discovery catalog (`https://{domain}/api/catalog/v1?
|
|
298
|
+
* search_context={domain}&…`). Unlike the FEDERATED `getCatalog`
|
|
299
|
+
* (api.us.socrata.com), each portal's OWN catalog COMPLETELY indexes its own
|
|
300
|
+
* datasets — the federated aggregator under-indexes many hosts (loop cycle 8:
|
|
301
|
+
* USAC → 0, DOT → 3 of 1,873). Used whenever a specific `domain` is requested;
|
|
302
|
+
* the all-host search (domain omitted) still needs the federated aggregator.
|
|
303
|
+
* SSRF: identical guard to getSocrataResource — domain ∈ allowlist + the
|
|
304
|
+
* CONSTRUCTED URL's hostname === domain (https); redirect:"error" (B1); the
|
|
305
|
+
* host-only label carries the domain (never the token, m7).
|
|
306
|
+
*/
|
|
307
|
+
async function getHostCatalog(domain, params) {
|
|
308
|
+
if (!SOCRATA_DOMAIN_SET.has(domain)) {
|
|
309
|
+
throw new ToolErrorCarrier({
|
|
310
|
+
kind: "invalid_input",
|
|
311
|
+
message: `Socrata domain ${JSON.stringify(domain)} is not on the curated allowlist. Allowed: ${SOCRATA_DOMAINS.join(", ")}.`,
|
|
312
|
+
retryable: false,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
const url = `https://${domain}/api/catalog/v1?${params.toString()}`;
|
|
316
|
+
const built = new URL(url);
|
|
317
|
+
if (built.hostname !== domain || built.protocol !== "https:") {
|
|
318
|
+
throw new ToolErrorCarrier({
|
|
319
|
+
kind: "invalid_input",
|
|
320
|
+
message: `Constructed Socrata host-catalog URL host ${JSON.stringify(built.hostname)} (${built.protocol}) does not match the allowlisted domain ${JSON.stringify(domain)} over https — refusing to fetch (SSRF safety).`,
|
|
321
|
+
retryable: false,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
return getJson(url, {
|
|
325
|
+
label: "socrata:catalog:" + domain,
|
|
326
|
+
headers: appTokenHeader(),
|
|
327
|
+
redirect: "error",
|
|
328
|
+
});
|
|
329
|
+
}
|
|
233
330
|
// ─── map + meta helpers ───────────────────────────────────────────
|
|
234
331
|
const STRING_COERCION_NOTE = "Row value fields arrive as strings verbatim from SODA (e.g. \"13650.00\", \"1\") — parse client-side. A missing value is absent, never 0.";
|
|
235
332
|
const SOURCE_SUFFIX = "via Socrata SODA (keyless)";
|
|
@@ -387,16 +484,21 @@ function mapCatalogRow(row) {
|
|
|
387
484
|
};
|
|
388
485
|
}
|
|
389
486
|
/**
|
|
390
|
-
* Discover dataset 4x4 ids via the Socrata catalog (memoized ~10 min).
|
|
391
|
-
* `domain`
|
|
392
|
-
*
|
|
393
|
-
*
|
|
487
|
+
* Discover dataset 4x4 ids via the Socrata catalog (memoized ~10 min). Passing a
|
|
488
|
+
* `domain` queries that portal's OWN catalog (search_context) — a COMPLETE
|
|
489
|
+
* per-host index; omitting it searches the WHOLE allowlist via the federated
|
|
490
|
+
* api.us.socrata.com aggregator (repeated `domains=`). Returns `[{ id, name,
|
|
491
|
+
* description, domain, updatedAt, link }]` + `totalAvailable = resultSetSize`.
|
|
492
|
+
* Feeds `datasetId` to socrata_query.
|
|
394
493
|
*
|
|
395
494
|
* m3 — this is the catalog's PRIMARY response: a non-number `resultSetSize` is a
|
|
396
495
|
* hard schema_drift throw (nothing valid to return), never a fabricated total.
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
496
|
+
*
|
|
497
|
+
* UNDER-INDEX (loop cycle 8 fix): the FEDERATED aggregator under-indexes many
|
|
498
|
+
* hosts (USAC → 0; DOT → 3 of 1,873), so the all-host search (domain omitted) can
|
|
499
|
+
* miss datasets — its `_meta` note discloses this. A DOMAIN-scoped search now
|
|
500
|
+
* uses that host's OWN catalog, which indexes it completely (USAC/DOT/etc. fully
|
|
501
|
+
* discoverable). socrata_query works regardless with a known 4x4.
|
|
400
502
|
*/
|
|
401
503
|
export async function discoverDatasets(args) {
|
|
402
504
|
const limit = args.limit ?? 20;
|
|
@@ -404,8 +506,11 @@ export async function discoverDatasets(args) {
|
|
|
404
506
|
params.set("q", args.q);
|
|
405
507
|
params.set("only", "datasets");
|
|
406
508
|
params.set("limit", String(limit));
|
|
509
|
+
// A specific domain → that portal's OWN catalog (search_context), a COMPLETE
|
|
510
|
+
// per-host index. Omitting domain → the federated aggregator (repeated
|
|
511
|
+
// domains=), the only way to search across all hosts (loop cycle 8).
|
|
407
512
|
if (args.domain) {
|
|
408
|
-
params.
|
|
513
|
+
params.set("search_context", args.domain);
|
|
409
514
|
}
|
|
410
515
|
else {
|
|
411
516
|
for (const d of SOCRATA_DOMAINS)
|
|
@@ -413,7 +518,9 @@ export async function discoverDatasets(args) {
|
|
|
413
518
|
}
|
|
414
519
|
const key = `socrata:catalog:${args.domain ?? "*"}:${args.q}:${limit}`;
|
|
415
520
|
const { totalAvailable, results } = await memoize(key, async () => {
|
|
416
|
-
const body =
|
|
521
|
+
const body = args.domain
|
|
522
|
+
? await getHostCatalog(args.domain, params)
|
|
523
|
+
: await getCatalog(params);
|
|
417
524
|
const b = (body ?? {});
|
|
418
525
|
// m3 — hard drift on the PRIMARY response (contrast the best-effort count).
|
|
419
526
|
// The check stays INSIDE the memoize callback so a bad shape is never
|
|
@@ -429,13 +536,16 @@ export async function discoverDatasets(args) {
|
|
|
429
536
|
const scope = args.domain ? `domain ${args.domain}` : `the ${SOCRATA_DOMAINS.length}-host allowlist`;
|
|
430
537
|
const notes = [
|
|
431
538
|
`Catalog search over ${scope} (only=datasets). Feed a result's id to socrata_query as datasetId.`,
|
|
539
|
+
args.domain
|
|
540
|
+
? `Source: the ${args.domain} portal's OWN catalog (search_context) — a COMPLETE per-host index.`
|
|
541
|
+
: `Source: the federated ${CATALOG_HOST} aggregator, which UNDER-INDEXES some hosts (e.g. USAC, DOT) — pass a specific domain to use that host's own complete catalog.`,
|
|
432
542
|
`App token: ${appTokenPresent() ? "present (X-App-Token sent; value never logged)" : "absent (keyless)"}.`,
|
|
433
543
|
];
|
|
434
544
|
if (totalAvailable !== null && returned < totalAvailable) {
|
|
435
545
|
notes.push(`Showing ${returned} of ${totalAvailable} matches; raise limit (≤100) or narrow q for the rest.`);
|
|
436
546
|
}
|
|
437
547
|
return withMeta({ query: args.q, domain: args.domain ?? null, results }, {
|
|
438
|
-
source: `${CATALOG_HOST} catalog ${SOURCE_SUFFIX}`,
|
|
548
|
+
source: `${args.domain ?? CATALOG_HOST} catalog ${SOURCE_SUFFIX}`,
|
|
439
549
|
keylessMode: true,
|
|
440
550
|
returned,
|
|
441
551
|
totalAvailable,
|
package/dist/socrata.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socrata.js","sourceRoot":"","sources":["../src/socrata.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"socrata.js","sourceRoot":"","sources":["../src/socrata.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cliwant/mcp-sam-gov",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"mcpName": "io.github.cliwant/mcp-sam-gov",
|
|
5
|
-
"description": "Most comprehensive keyless MCP server for US federal contracting + spending + regulation: SAM.gov, USAspending, Federal Register, eCFR, Grants.gov.
|
|
5
|
+
"description": "Most comprehensive keyless MCP server for US federal contracting + spending + regulation: SAM.gov, USAspending, Federal Register, eCFR, Grants.gov. 144 tools, no API key, plug into Claude Desktop / Claude Code / Codex CLI / Cursor / Continue / Gemini CLI.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
8
8
|
"model-context-protocol",
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* arcgis-feature.ts — generic ArcGIS REST FeatureServer/MapServer layer query
|
|
3
|
+
* over a CURATED service allowlist (loop — SLED bid campaign, 2026-07-19).
|
|
4
|
+
*
|
|
5
|
+
* WHAT IT ADDS: an enormous amount of US government data (esp. SLED procurement /
|
|
6
|
+
* GIS / infrastructure) is published as ArcGIS REST feature layers. This is the
|
|
7
|
+
* QUERY companion to `arcgis_hub_discover_datasets` (which DISCOVERS Hub datasets):
|
|
8
|
+
* it queries the ROWS of a curated set of high-value ArcGIS layers. First payload:
|
|
9
|
+
* the DC OCP "PASS" procurement layers (solicitations / contracts / purchase
|
|
10
|
+
* orders / payments) — DC's live open-solicitation feed with 46 fields, keyless.
|
|
11
|
+
*
|
|
12
|
+
* The module REUSES `getJson` (redirect:"error") / `driftError` / `num`·`str` /
|
|
13
|
+
* `withMeta`·`buildMeta`, mirroring socrata.ts (curated allowlist) + datagov-
|
|
14
|
+
* catalog.ts. KEYLESS.
|
|
15
|
+
*
|
|
16
|
+
* ★ SSRF: the caller supplies a `service` ENUM key (never a free host/URL); each
|
|
17
|
+
* allowlist entry is a FIXED, live-verified ArcGIS layer base URL. The query
|
|
18
|
+
* URL is built on that fixed base, and a post-construction assertion requires
|
|
19
|
+
* the built hostname === the allowlist entry's host (over https) BEFORE the
|
|
20
|
+
* fetch; `redirect:"error"`. `where`/`outFields`/`orderByFields` ride in
|
|
21
|
+
* URLSearchParams (encoded) — they filter/project the read-only layer and
|
|
22
|
+
* CANNOT alter the host (a malformed `where` ⇒ upstream 400 ⇒ invalid_input,
|
|
23
|
+
* surfaced, never silent). Adding a service later = an allowlist SOURCE edit +
|
|
24
|
+
* a live count/`/query` verification — NEVER a free runtime param.
|
|
25
|
+
*
|
|
26
|
+
* ★ HONESTY PILLARS (captured live 2026-07-19):
|
|
27
|
+
* P1: totalAvailable = the layer's EXACT match count (a `returnCountOnly=true`
|
|
28
|
+
* companion query), NEVER the page length. Best-effort: a count failure ⇒
|
|
29
|
+
* totalAvailable:null + a note (the rows are still returned) — never a fake
|
|
30
|
+
* total. `exceededTransferLimit` also forces hasMore.
|
|
31
|
+
* P2: getJson THROWS on 429/5xx/timeout; an ArcGIS `{error:{code,message}}`
|
|
32
|
+
* body (HTTP 200) is classified (400 ⇒ invalid_input, else upstream) and
|
|
33
|
+
* THROWN — never a fake empty. A genuine no-match (features:[], count:0) ⇒
|
|
34
|
+
* honest empty.
|
|
35
|
+
* P3: attributes pass through VERBATIM (they are the layer's own record). NOTE
|
|
36
|
+
* (disclosed every response): ArcGIS date fields are epoch MILLISECONDS and a
|
|
37
|
+
* negative/sentinel value (e.g. -2209093200000 ≈ year 1900) is a placeholder,
|
|
38
|
+
* not a real date — surfaced verbatim, never coerced.
|
|
39
|
+
* P4: `body.features` absent/non-array (and no error) ⇒ driftError; a 200
|
|
40
|
+
* non-JSON body ⇒ schema_drift via the catch-ladder.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { ToolErrorCarrier } from "./errors.js";
|
|
44
|
+
import { getJson, driftError } from "./datasource.js";
|
|
45
|
+
import { num } from "./coerce.js";
|
|
46
|
+
import { withMeta, type MetaBundle, type ResponseMeta } from "./meta.js";
|
|
47
|
+
|
|
48
|
+
export { num };
|
|
49
|
+
|
|
50
|
+
// ─── Curated service allowlist (SSRF core) — LIVE-VERIFIED 2026-07-19 ──
|
|
51
|
+
// Each `base` is an ArcGIS FeatureServer/MapServer LAYER endpoint; the tool
|
|
52
|
+
// appends `/query`. All keyless. The Zod `service` enum in server.ts is built
|
|
53
|
+
// FROM `key`s (single source of truth).
|
|
54
|
+
export type ArcgisService = { key: string; base: string; label: string; note: string };
|
|
55
|
+
export const ARCGIS_SERVICES: readonly ArcgisService[] = [
|
|
56
|
+
{ key: "dc_pass_solicitations", base: "https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Government_Operations/MapServer/19", label: "DC OCP PASS — Solicitations", note: "DC Office of Contracting & Procurement live solicitations (SOLICITATIONNUMBER, SOLICITATIONTITLE, DUE_DATE, OPENDATE, CLOSEDATE, NIGPCODE, CONTRACTINGOFFICER, AWARD_TO…). ~25k." },
|
|
57
|
+
{ key: "dc_pass_contracts", base: "https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Government_Operations/MapServer/37", label: "DC OCP PASS — Contracts", note: "DC awarded contracts. ~50k." },
|
|
58
|
+
{ key: "dc_pass_purchase_orders", base: "https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Government_Operations/MapServer/16", label: "DC OCP PASS — Purchase Orders", note: "DC purchase orders. ~275k." },
|
|
59
|
+
{ key: "dc_pass_payments", base: "https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Government_Operations/MapServer/17", label: "DC OCP PASS — Payments", note: "DC vendor payments. ~1.55M." },
|
|
60
|
+
// ── Additional US local-gov procurement layers (loop, 2026-07-19) — found via
|
|
61
|
+
// arcgis_hub_discover_datasets, each on a reachable Esri-hosted services*.
|
|
62
|
+
// arcgis.com endpoint (NOT WAF-gated) + live-verified returnCountOnly. ──
|
|
63
|
+
{ key: "asheville_purchase_orders", base: "https://services.arcgis.com/aJ16ENn1AaqdFlqx/ArcGIS/rest/services/Financials/FeatureServer/9", label: "Asheville NC — Purchase Order Line Items", note: "City of Asheville NC purchase-order line items. ~62.8k." },
|
|
64
|
+
{ key: "asheville_po_summary", base: "https://services.arcgis.com/aJ16ENn1AaqdFlqx/ArcGIS/rest/services/Financials/FeatureServer/8", label: "Asheville NC — Purchase Order Summary", note: "City of Asheville NC purchase-order summary. ~18.7k." },
|
|
65
|
+
{ key: "bellevue_vendor_payments", base: "https://services1.arcgis.com/EYzEZbDhXZjURPbP/arcgis/rest/services/YTD_Vendor_Payments/FeatureServer/0", label: "Bellevue WA — YTD Vendor Payments", note: "City of Bellevue WA year-to-date vendor payments. ~15.8k." },
|
|
66
|
+
{ key: "bellevue_awarded_contracts", base: "https://services1.arcgis.com/EYzEZbDhXZjURPbP/arcgis/rest/services/Annual_Awarded_Contracts/FeatureServer/0", label: "Bellevue WA — Annual Awarded Contracts", note: "City of Bellevue WA annual awarded contracts. ~2.0k." },
|
|
67
|
+
{ key: "miamidade_purchase_orders_2017", base: "https://services.arcgis.com/8Pc9XBTAsYuxx9Ny/arcgis/rest/services/miamidade_procurement_data_2017/FeatureServer/0", label: "Miami-Dade County FL — Purchase Orders (ADPICS) 2017", note: "Miami-Dade County FL purchase orders — a 2017 snapshot (historical, disclosed). ~94.8k." },
|
|
68
|
+
{ key: "miamidade_purchase_orders_2025", base: "https://services.arcgis.com/8Pc9XBTAsYuxx9Ny/arcgis/rest/services/miamidade_procurement_data_informs_2025/FeatureServer/0", label: "Miami-Dade County FL — Purchase Orders (INFORMS) 2025", note: "Miami-Dade County FL purchase orders — CURRENT (2025 INFORMS). ~25k." },
|
|
69
|
+
{ key: "suffolk_county_ny_contracts_2018", base: "https://services.arcgis.com/JsDD4qdG5r2a7hR5/arcgis/rest/services/County_Contracts_2018/FeatureServer/0", label: "Suffolk County NY — County Contracts 2018", note: "Suffolk County NY contracts — a 2018 snapshot (historical, disclosed). ~1.4k." },
|
|
70
|
+
{ key: "matsu_borough_ak_checkbook", base: "https://services.arcgis.com/fX5IGselyy1TirdY/arcgis/rest/services/Logos_Checkbook_Data/FeatureServer/0", label: "Matanuska-Susitna Borough AK — Checkbook", note: "Matanuska-Susitna Borough AK checkbook (vendor spend). ~1.2k." },
|
|
71
|
+
{ key: "lasvegas_checkbook", base: "https://services1.arcgis.com/F1v0ufATbBQScMtY/arcgis/rest/services/Processed_Checkbook_Table_View/FeatureServer/0", label: "City of Las Vegas NV — Open Checkbook", note: "City of Las Vegas NV checkbook (DEPARTMENT/VENDOR/TRANSACTION_AMOUNT/TRANSACTION_DATE). ~373k." },
|
|
72
|
+
{ key: "baltimore_checkbook", base: "https://services1.arcgis.com/UWYHeuuJISiGmgXx/arcgis/rest/services/OpenCheckbookFY2022_Through_Present/FeatureServer/0", label: "Baltimore City MD — Open Checkbook (FY2022–present)", note: "Baltimore City MD checkbook, FY2022 through present (Supplier_Name/Payment_Amount/Supplier_Contract_Number/Agency). ~367k." },
|
|
73
|
+
{ key: "naperville_vendor_payments", base: "https://services1.arcgis.com/rXJ6QApc2sOtl1Pd/arcgis/rest/services/Expenditures_2018_to_Current_Year/FeatureServer/0", label: "City of Naperville IL — Vendor Payments (2018–current)", note: "City of Naperville IL vendor payments, 2018 to current year (Vendor_Name/Payment_Amount/Purch_Order_No/Check_Date). ~127k." },
|
|
74
|
+
{ key: "worcester_ma_checkbook_fy25", base: "https://services1.arcgis.com/j8dqo2DJE7mVUBU1/arcgis/rest/services/Fiscal_Year_2025_Open_Checkbook/FeatureServer/0", label: "City of Worcester MA — Open Checkbook FY2025", note: "City of Worcester MA open checkbook, FY2025 (Payee/Pmt_Amount/Departments/Spend_Categories/Pmt_Date). ~38k." },
|
|
75
|
+
{ key: "lasvegas_purchasing_contracts", base: "https://services1.arcgis.com/F1v0ufATbBQScMtY/arcgis/rest/services/Purchasing_Contracts__view/FeatureServer/0", label: "City of Las Vegas NV — Purchasing Contracts", note: "City of Las Vegas NV purchasing contract register (Project_Number/Project_Name/Supplier_Name/Award_Date/Termination_Date). ~3.4k, all with a supplier. Complements lasvegas_checkbook (payments)." },
|
|
76
|
+
{ key: "txdot_construction_projects", base: "https://services.arcgis.com/KTcxiTD9dsQw4r7Z/arcgis/rest/services/TxDOT_Projects_Info_All/FeatureServer/0", label: "Texas DOT — Projects (with awarded construction company)", note: "Texas Department of Transportation highway projects (CNSTR_CMPNY_NM awarded construction company/CNSTR_NTPD_DT notice-to-proceed/TYPE_OF_WORK/HWY_NBR). ~85k rows, ~14.1k with an awarded contractor (filter CNSTR_CMPNY_NM IS NOT NULL for awards)." },
|
|
77
|
+
{ key: "akdot_construction_awards", base: "https://services.arcgis.com/r4A0V7UzH9fcLVvv/arcgis/rest/services/AWARDS_DASHBOARD_AWARDS_TABLE_POINTS/FeatureServer/0", label: "Alaska DOT&PF — Construction Bid Awards", note: "Alaska Department of Transportation & Public Facilities construction bid awards (ContractID/Contractor/Bids_Received/Engineer_Est/Award_Amount/Advertised_Date/Bid_Opening_Date/Reg_Award_Date/DOT_Region). ~1.1k." },
|
|
78
|
+
{ key: "akdot_aashtoware_proposals", base: "https://services.arcgis.com/r4A0V7UzH9fcLVvv/arcgis/rest/services/AASHTOWARE_Proposals_Points/FeatureServer/0", label: "Alaska DOT&PF — AASHTOWARE Proposals/Lettings", note: "Alaska DOT&PF AASHTOWARE proposals & lettings with awarded vendor (ProposalId/LettingId/StateProjectNumber/RefVendor_LongName/RefVendor_DBECertStatus/AwardedAmount/Contract_ID/FundType). ~1k, ~1,035 with an AwardedAmount>0. Complements akdot_construction_awards." },
|
|
79
|
+
{ key: "iowadot_public_bid_awards", base: "https://services.arcgis.com/8lRhdTsQyJpO52F1/arcgis/rest/services/Project_Scheduling_Public_Bid_Point_View/FeatureServer/0", label: "Iowa DOT — Public Bid / Project Scheduling", note: "Iowa Department of Transportation public bid & project scheduling (PROJECT_NUMBER/WORK_DESC/LETTING_FISCAL_YEAR/PROGRAM_ESTIMATE/CONTRACT_AWARDED/AWARDED/FINAL_CONTRACT/CONTRACTOR/CONTRACT_ID/STATUS). ~360." },
|
|
80
|
+
{ key: "okdot_cirb_contract_status", base: "https://services6.arcgis.com/RBtoEUQ2lmN0K3GY/arcgis/rest/services/CIRB_Project_Status/FeatureServer/0", label: "Oklahoma DOT — CIRB Contract Status", note: "Oklahoma Department of Transportation County Improvements for Roads & Bridges (CIRB) contract status (T_PROJECT/JP_DESCRIPTION/A_CONTRACT_AMOUNT/A_AMOUNT_EARNED/A_AMOUNT_PAID/D_LET_DATE/D_CONTRACT_AWARD_DATE/D_WORK_ORDER_DATE). ~780." },
|
|
81
|
+
{ key: "topeka_checkbook_aggregate", base: "https://services1.arcgis.com/EvtgI3PZ9PyCGJZS/arcgis/rest/services/Checkbook_Aggregate/FeatureServer/0", label: "City of Topeka KS — Open Checkbook (aggregate FY2015–2023)", note: "City of Topeka KS open checkbook, all years aggregated FY2015–2023 (fiscal_year/fiscal_period/department/program/fund/vendor_name/description/dollars). ~332k rows, ~323.6k with dollars>0." },
|
|
82
|
+
] as const;
|
|
83
|
+
|
|
84
|
+
const SERVICE_BY_KEY: ReadonlyMap<string, ArcgisService> = new Map(ARCGIS_SERVICES.map((s) => [s.key, s]));
|
|
85
|
+
|
|
86
|
+
const DATE_NOTE =
|
|
87
|
+
"ArcGIS date fields are epoch MILLISECONDS (e.g. DUE_DATE, OPENDATE, CLOSEDATE); a negative/sentinel value (≈ year 1900) is a placeholder, not a real date — surfaced verbatim, parse client-side.";
|
|
88
|
+
|
|
89
|
+
// ─── SSRF-guarded fetch (fixed allowlist base + hostname assertion) ──
|
|
90
|
+
async function getArcgisQuery(svc: ArcgisService, params: URLSearchParams): Promise<unknown> {
|
|
91
|
+
const url = `${svc.base}/query?${params.toString()}`;
|
|
92
|
+
const allowedHost = new URL(svc.base).hostname;
|
|
93
|
+
const built = new URL(url);
|
|
94
|
+
if (built.hostname !== allowedHost || built.protocol !== "https:") {
|
|
95
|
+
throw new ToolErrorCarrier({
|
|
96
|
+
kind: "invalid_input",
|
|
97
|
+
message: `Constructed ArcGIS URL host ${JSON.stringify(built.hostname)} (${built.protocol}) does not match the allowlisted service host ${JSON.stringify(allowedHost)} over https — refusing to fetch (SSRF safety).`,
|
|
98
|
+
retryable: false,
|
|
99
|
+
upstreamEndpoint: `arcgis:${svc.key}`,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return getJson(url, { label: `arcgis:${svc.key}`, redirect: "error" });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ArcGIS returns HTTP 200 + `{error:{code,message}}` for BOTH a bad query AND a
|
|
106
|
+
// transient server hiccup, and the messages OVERLAP (live-verified 2026-07-19):
|
|
107
|
+
// - "Failed to execute query." ⇒ a bad column/field/where (the caller's query).
|
|
108
|
+
// - "Unable to complete operation." ⇒ AMBIGUOUS — a bad SQL syntax OR a transient
|
|
109
|
+
// server blip (observed intermittently on a valid query).
|
|
110
|
+
// So classify a clearly-input message as invalid_input (non-retryable), but treat
|
|
111
|
+
// the ambiguous/generic one as upstream_unavailable (RETRYABLE) — misclassifying a
|
|
112
|
+
// server blip as invalid_input would falsely blame the caller for an outage.
|
|
113
|
+
const ARCGIS_INPUT_ERROR_RE =
|
|
114
|
+
/failed to execute query|invalid|parameter|field|syntax|parse|not supported|does not exist|cannot find|out of range/i;
|
|
115
|
+
|
|
116
|
+
/** An ArcGIS `{error:{code,message}}` body (HTTP 200) ⇒ throw the right kind. */
|
|
117
|
+
function throwIfArcgisError(svc: ArcgisService, body: unknown): void {
|
|
118
|
+
const e = (body as { error?: { code?: unknown; message?: unknown } } | null)?.error;
|
|
119
|
+
if (e && typeof e === "object") {
|
|
120
|
+
const code = num((e as { code?: unknown }).code);
|
|
121
|
+
const msg = String((e as { message?: unknown }).message ?? "ArcGIS query error");
|
|
122
|
+
const inputish = code === 400 && ARCGIS_INPUT_ERROR_RE.test(msg);
|
|
123
|
+
throw new ToolErrorCarrier({
|
|
124
|
+
kind: inputish ? "invalid_input" : "upstream_unavailable",
|
|
125
|
+
message: `ArcGIS ${svc.key} error${code !== null ? ` (${code})` : ""}: ${msg}`.slice(0, 300),
|
|
126
|
+
retryable: !inputish,
|
|
127
|
+
upstreamEndpoint: `arcgis:${svc.key}`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ─── Tool: arcgis_feature_query ───────────────────────────────────
|
|
133
|
+
export type ArcgisFeatureQueryArgs = {
|
|
134
|
+
service: string;
|
|
135
|
+
where?: string;
|
|
136
|
+
outFields?: string;
|
|
137
|
+
orderByFields?: string;
|
|
138
|
+
limit?: number;
|
|
139
|
+
offset?: number;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Query rows from a curated ArcGIS REST feature layer. `service` is an allowlist
|
|
144
|
+
* enum; `where` (SQL-ish filter, default 1=1), `outFields` (default *),
|
|
145
|
+
* `orderByFields`, `limit`/`offset`. Returns curated record attributes + honest
|
|
146
|
+
* `_meta` (totalAvailable = the layer's exact match count via a returnCountOnly
|
|
147
|
+
* companion; epoch-ms date disclosure).
|
|
148
|
+
*/
|
|
149
|
+
export async function featureQuery(args: ArcgisFeatureQueryArgs): Promise<MetaBundle> {
|
|
150
|
+
const svc = SERVICE_BY_KEY.get(args.service);
|
|
151
|
+
if (!svc) {
|
|
152
|
+
throw new ToolErrorCarrier({
|
|
153
|
+
kind: "invalid_input",
|
|
154
|
+
message: `Unknown ArcGIS service ${JSON.stringify(args.service)}. Allowed: ${ARCGIS_SERVICES.map((s) => s.key).join(", ")}.`,
|
|
155
|
+
retryable: false,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const limit = args.limit ?? 50;
|
|
159
|
+
const offset = args.offset ?? 0;
|
|
160
|
+
const where = args.where && args.where.trim() ? args.where.trim() : "1=1";
|
|
161
|
+
const outFields = args.outFields && args.outFields.trim() ? args.outFields.trim() : "*";
|
|
162
|
+
const filtersApplied: string[] = ["service"];
|
|
163
|
+
if (args.where && args.where.trim()) filtersApplied.push("where");
|
|
164
|
+
|
|
165
|
+
// ── Primary rows query. ──
|
|
166
|
+
const rowParams = new URLSearchParams();
|
|
167
|
+
rowParams.set("where", where);
|
|
168
|
+
rowParams.set("outFields", outFields);
|
|
169
|
+
rowParams.set("returnGeometry", "false");
|
|
170
|
+
rowParams.set("resultOffset", String(offset));
|
|
171
|
+
rowParams.set("resultRecordCount", String(limit));
|
|
172
|
+
if (args.orderByFields && args.orderByFields.trim()) rowParams.set("orderByFields", args.orderByFields.trim());
|
|
173
|
+
rowParams.set("f", "json");
|
|
174
|
+
|
|
175
|
+
let body: unknown;
|
|
176
|
+
try {
|
|
177
|
+
body = await getArcgisQuery(svc, rowParams);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
if (e instanceof ToolErrorCarrier) throw e;
|
|
180
|
+
if (e instanceof SyntaxError) throw driftError(`arcgis:${svc.key}`, "ArcGIS returned a non-JSON body at HTTP 200 — schema drift.");
|
|
181
|
+
throw e;
|
|
182
|
+
}
|
|
183
|
+
throwIfArcgisError(svc, body); // P2: a 200 {error} body ⇒ throw (never a fake empty)
|
|
184
|
+
|
|
185
|
+
const b = (body ?? {}) as { features?: unknown; exceededTransferLimit?: unknown };
|
|
186
|
+
// P4: features MUST be an array (a missing/non-array, with no error, is drift).
|
|
187
|
+
if (!Array.isArray(b.features)) {
|
|
188
|
+
throw driftError(`arcgis:${svc.key}`, "ArcGIS shape drift — response.features must be an array.");
|
|
189
|
+
}
|
|
190
|
+
const records = (b.features as unknown[]).map((f) => (f as { attributes?: unknown })?.attributes ?? {});
|
|
191
|
+
const returned = records.length;
|
|
192
|
+
|
|
193
|
+
// ── P1: totalAvailable = the layer's exact match count (returnCountOnly
|
|
194
|
+
// companion). BEST-EFFORT: any count failure ⇒ null + note (rows kept). ──
|
|
195
|
+
let totalAvailable: number | null = null;
|
|
196
|
+
let countNote: string | null = null;
|
|
197
|
+
try {
|
|
198
|
+
const countParams = new URLSearchParams();
|
|
199
|
+
countParams.set("where", where);
|
|
200
|
+
countParams.set("returnCountOnly", "true");
|
|
201
|
+
countParams.set("f", "json");
|
|
202
|
+
const cbody = await getArcgisQuery(svc, countParams);
|
|
203
|
+
throwIfArcgisError(svc, cbody);
|
|
204
|
+
const c = num((cbody as { count?: unknown })?.count);
|
|
205
|
+
if (c !== null) totalAvailable = c;
|
|
206
|
+
else countNote = "The returnCountOnly companion returned an unexpected shape — totalAvailable is unknown (null); the rows are still complete.";
|
|
207
|
+
} catch {
|
|
208
|
+
countNote = "The returnCountOnly companion failed (transient) — totalAvailable is unknown (null); the rows are still returned.";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const exceeded = b.exceededTransferLimit === true;
|
|
212
|
+
const hasMore = totalAvailable !== null ? offset + returned < totalAvailable : (exceeded || returned >= limit);
|
|
213
|
+
const nextOffset = hasMore ? offset + returned : null;
|
|
214
|
+
|
|
215
|
+
const notes: string[] = [`Source: ${svc.label} (ArcGIS REST feature layer, keyless). ${svc.note}`, DATE_NOTE];
|
|
216
|
+
if (countNote) notes.push(countNote);
|
|
217
|
+
|
|
218
|
+
return withMeta(
|
|
219
|
+
{ service: svc.key, records },
|
|
220
|
+
{
|
|
221
|
+
source: `${new URL(svc.base).hostname} via ArcGIS REST (keyless)`,
|
|
222
|
+
keylessMode: true,
|
|
223
|
+
returned,
|
|
224
|
+
totalAvailable,
|
|
225
|
+
filtersApplied,
|
|
226
|
+
filtersDropped: [],
|
|
227
|
+
fieldsUnavailable: [],
|
|
228
|
+
pagination: { offset, limit, hasMore, nextOffset },
|
|
229
|
+
notes,
|
|
230
|
+
} satisfies Partial<ResponseMeta>,
|
|
231
|
+
);
|
|
232
|
+
}
|