geotap-mcp-server 3.0.2 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,503 +1,123 @@
1
- # GeoTap Developer
1
+ # GeoTap MCP Server
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/geotap-mcp-server.svg)](https://www.npmjs.com/package/geotap-mcp-server)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- **One API for 37 US federal environmental and infrastructure data sources.**
6
+ **Connect Claude, Cursor, Windsurf, and other AI tools to 80+ US federal environmental and infrastructure data sources.**
7
7
 
8
- GeoTap aggregates data from FEMA, USGS, EPA, NOAA, USDA, USFWS, DOT, Census, and more into a single REST API. This repository contains:
9
-
10
- - **REST API documentation** — query federal data programmatically
11
- - **MCP Server** — connect GeoTap to Claude, Cursor, Windsurf, and other AI tools
8
+ GeoTap aggregates data from FEMA, USGS, EPA, NOAA, USDA, USFWS, DOT, Census, and more accessible through the MCP (Model Context Protocol).
12
9
 
13
10
  > **Web App**: [geotapdata.com](https://geotapdata.com) — no code required, draw on a map and explore data visually.
14
11
 
15
12
  ---
16
13
 
17
- ## Data Sources
14
+ ## Getting Started
18
15
 
19
- | Agency | Data Available |
20
- |--------|---------------|
21
- | **FEMA** | Flood zones, FIRM panels, flood insurance rate maps, floodway boundaries |
22
- | **USGS** | Elevation (3DEP at 1m/10m/30m), geology, streamgages, groundwater, land use (NLCD), StreamStats, National Streamflow Statistics (NSS) |
23
- | **EPA** | Water quality (ATTAINS), Superfund sites, brownfields, TRI toxic releases, USTs, NPDES outfalls |
24
- | **NOAA** | Rainfall (Atlas 14), IDF curves, tide stations, climate projections (CMIP6), weather stations, radar |
25
- | **USDA/NRCS** | Soils (SSURGO), curve numbers, hydrologic soil groups, TR-55 parameters |
26
- | **USFWS** | Wetlands (NWI), endangered species, critical habitat |
27
- | **DOT** | Bridges, tunnels, National Bridge Inventory |
28
- | **Census** | Demographics, boundaries, TIGER geographic data |
29
- | **USACE** | Dams, levees, navigation channels |
30
- | **NHD** | Stream flowlines, hydrography, watershed boundaries (HUC-8/10/12) |
31
- | **Other** | Power plants, mines, tribal lands, building footprints, and more |
16
+ ### Prerequisites
32
17
 
33
- Every API response includes **source attribution** the federal agency, dataset name, and reference URL so you always know where the data came from.
18
+ - **Node.js** (v18 or later)[download here](https://nodejs.org/)
19
+ - An email address to register for your API key
34
20
 
35
- ---
21
+ ### Step 1: Get Your API Key
36
22
 
37
- ## Quick Start
23
+ Go to **[geotapdata.com/developers](https://geotapdata.com/developers)** and register with your email to get a free API key.
38
24
 
39
- ### Option 1: REST API
25
+ Your API key will be sent to your email. **Save it** — you'll need it in the next step.
40
26
 
41
- ```bash
42
- # Get flood zones, wetlands, soils, and 16 more layers for a location
43
- curl "https://geotapdata.com/api/v1/spatial/near?lat=30.267&lng=-97.743&radius=0.5"
27
+ ### Step 2: Set Up the MCP Server
44
28
 
45
- # Get NOAA Atlas 14 rainfall data
46
- curl "https://geotapdata.com/api/v1/rainfall/atlas14?lat=30.267&lon=-97.743"
29
+ Choose your AI tool below and follow the instructions. The MCP server is installed automatically via `npx` — no manual download needed.
47
30
 
48
- # Geocode an address
49
- curl "https://geotapdata.com/api/v1/geocode?address=123+Main+St+Austin+TX"
50
- ```
31
+ ---
32
+
33
+ <details open>
34
+ <summary><strong>Claude Desktop</strong></summary>
51
35
 
52
- ### Option 2: MCP Server (for AI tools)
36
+ 1. Open Claude Desktop
37
+ 2. Go to **Settings** (gear icon) → **Developer** → **Edit Config**
38
+ 3. This opens your `claude_desktop_config.json` file. Add the following (replace `your-api-key-here` with your actual key):
53
39
 
54
- Add to Claude Desktop or Cursor config:
55
40
  ```json
56
41
  {
57
42
  "mcpServers": {
58
43
  "geotap": {
59
44
  "command": "npx",
60
- "args": ["-y", "geotap-mcp-server"]
45
+ "args": ["-y", "geotap-mcp-server"],
46
+ "env": {
47
+ "GEOTAP_API_KEY": "your-api-key-here"
48
+ }
61
49
  }
62
50
  }
63
51
  }
64
52
  ```
65
53
 
66
- Then ask: *"What are the flood zones at 123 Main St, Austin TX?"*
67
-
68
- ---
69
-
70
- ## REST API Reference
71
-
72
- **Base URL**: `https://geotapdata.com/api/v1`
73
-
74
- ### Authentication
75
-
76
- API keys are **optional** during the open beta. All endpoints work without authentication.
77
-
78
- | Method | Details |
79
- |--------|---------|
80
- | **Header** | `X-API-Key: your-key-here` |
81
- | **Query param** | `?api_key=your-key-here` |
82
- | **Register** | `POST https://geotapdata.com/api/keys/register` with `{"email": "you@example.com"}` |
83
-
84
- Authenticated requests get higher rate limits and usage tracking.
85
-
86
- ### Rate Limits
54
+ > **Config file location:**
55
+ > - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
56
+ > - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
87
57
 
88
- | Tier | Monthly Requests | Burst (per min) | Cost |
89
- |------|-----------------|------------------|------|
90
- | **Unauthenticated** | No limit | 100/min (IP-based) | Free |
91
- | **Free** (with key) | 50 | 5/min | Free |
92
- | **Starter** | 1,000 | 20/min | Coming soon |
93
- | **Pro** | 10,000 | 60/min | Coming soon |
94
- | **Enterprise** | 100,000 | 200/min | Coming soon |
58
+ 4. **Restart Claude Desktop** completely (quit and reopen)
59
+ 5. You should see a hammer icon (🔨) in the chat input — that means GeoTap is connected
95
60
 
96
- Rate limit headers are included in every response: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`.
97
-
98
- ### Response Format
99
-
100
- Every response includes:
101
-
102
- ```json
103
- {
104
- "success": true,
105
- "data": { ... },
106
- "_meta": {
107
- "sources": [
108
- {
109
- "agency": "FEMA",
110
- "dataset": "National Flood Hazard Layer (NFHL)",
111
- "url": "https://www.fema.gov/flood-maps/national-flood-hazard-layer"
112
- }
113
- ],
114
- "retrievedAt": "2026-03-19T12:00:00.000Z",
115
- "disclaimer": "Data sourced from US federal agencies via GeoTap..."
116
- }
117
- }
118
- ```
61
+ </details>
119
62
 
120
63
  ---
121
64
 
122
- ### Endpoints
123
-
124
- #### Geocoding
125
-
126
- | Method | Endpoint | Description |
127
- |--------|----------|-------------|
128
- | GET | `/geocode?address={address}` | Convert a US address to coordinates |
129
-
130
- ```bash
131
- curl "https://geotapdata.com/api/v1/geocode?address=456+Oak+Ave+Houston+TX"
132
- ```
133
-
134
- #### Quick Start: Query an Address (Recommended)
135
-
136
- The fastest way to get environmental data — geocode + query in one call:
137
-
138
- ```bash
139
- # One call: geocodes address + returns flood zone, soils, wetlands, contamination
140
- curl "https://geotapdata.com/api/v1/query-address?address=123+Main+St+Houston+TX"
141
-
142
- # With specific layers
143
- curl "https://geotapdata.com/api/v1/query-address?address=123+Main+St+Houston+TX&layers=flood_zones,soil_map_units"
144
- ```
145
-
146
- Response includes plain-English `_interpretation` fields:
147
- ```json
148
- {
149
- "properties": {
150
- "zone": "AE",
151
- "_interpretation": "High-risk flood zone with base flood elevations determined. Flood insurance required."
152
- }
153
- }
154
- ```
155
-
156
- #### Point Query (by coordinates)
157
-
158
- ```bash
159
- # What's at this exact point? (properties only, no geometry — always <5KB)
160
- curl "https://geotapdata.com/api/v1/spatial/point?lat=30.267&lng=-97.743&layers=flood_zones,wetlands"
161
- ```
162
-
163
- #### Spatial Queries
164
-
165
- | Method | Endpoint | Description |
166
- |--------|----------|-------------|
167
- | GET | `/query-address?address=...` | **Geocode + point query in one call (recommended)** |
168
- | GET | `/spatial/point?lat=...&lng=...` | Point-in-polygon query (properties only, with interpretations) |
169
- | GET | `/spatial/near?lat={lat}&lng={lng}&radius={km}` | Query layers near a point |
170
- | POST | `/spatial/in-polygon` | Query layers within a polygon |
171
- | POST | `/spatial/summary` | Feature counts per layer (fast) |
172
- | GET | `/spatial/bbox?bbox={w,s,e,n}` | Query layers in a bounding box |
173
-
174
- **`geometry` parameter** — available on `/near`, `/bbox`, `/in-polygon`, and `/layers/:name/features`:
175
- - `geometry=none` — strips all coordinates (smallest response, best for LLM consumers)
176
- - `geometry=simplified` — reduces coordinate density
177
- - `geometry=full` — complete geometry (default)
178
-
179
- ```bash
180
- # All environmental data within 0.5 km of a point (no geometry for smaller response)
181
- curl "https://geotapdata.com/api/v1/spatial/near?lat=34.05&lng=-118.25&radius=0.5&geometry=none"
182
-
183
- # Specific layers only
184
- curl "https://geotapdata.com/api/v1/spatial/near?lat=34.05&lng=-118.25&radius=0.5&layers=flood_zones,wetlands,soil_map_units"
185
-
186
- # Query within a polygon
187
- curl -X POST "https://geotapdata.com/api/v1/spatial/in-polygon" \
188
- -H "Content-Type: application/json" \
189
- -d '{
190
- "polygon": {
191
- "type": "Polygon",
192
- "coordinates": [[[-97.75,30.26],[-97.74,30.26],[-97.74,30.27],[-97.75,30.27],[-97.75,30.26]]]
193
- },
194
- "geometry": "none"
195
- }'
196
- ```
197
-
198
- #### Data Layers
199
-
200
- | Method | Endpoint | Description |
201
- |--------|----------|-------------|
202
- | GET | `/layers` | List all available data layers |
203
- | GET | `/layers/{name}` | Get metadata for a layer |
204
- | GET | `/layers/{name}/features?bbox={w,s,e,n}` | Get features from a layer |
205
-
206
- **Available layer names**: `flood_zones`, `wetlands`, `soil_map_units`, `dem_elevation`, `nlcd_land_cover`, `contours`, `building_footprints`, `stream_gauges`, `streams_rivers`, `weather_alerts`, `critical_habitat`, `protected_lands`, `brownfields`, `superfund`, `ust`, `npdes_outfalls`, `dams`, `levees`, `impaired_waters`, `satellite_imagery`, `sole_source_aquifers`
207
-
208
- #### Rainfall & Precipitation
209
-
210
- | Method | Endpoint | Description |
211
- |--------|----------|-------------|
212
- | GET | `/rainfall/atlas14?lat={lat}&lon={lon}` | NOAA Atlas 14 precipitation frequency |
213
- | GET | `/rainfall/atlas14/idf?lat={lat}&lon={lon}` | IDF curve data |
214
- | POST | `/rainfall/hyetograph` | Generate design storm hyetograph |
215
- | POST | `/rainfall/export` | Export hyetograph as CSV/JSON |
216
- | GET | `/rainfall/distributions` | List rainfall distribution types |
217
- | GET | `/rainfall/recommend?lat={lat}&lon={lon}` | Recommended SCS distribution |
218
- | GET | `/rainfall/climate/scenarios` | Available climate scenarios |
219
- | GET | `/rainfall/climate/factors?lat={lat}&lon={lon}&horizon={h}&scenario={s}` | Climate change multipliers |
220
- | POST | `/rainfall/climate/project` | Future rainfall projections |
221
- | GET | `/rainfall/uncertainty/bounds?lat={lat}&lon={lon}&returnPeriod={rp}&duration={d}` | Confidence intervals |
222
- | POST | `/rainfall/uncertainty/envelope` | Monte Carlo uncertainty bands |
223
- | POST | `/rainfall/uncertainty/sensitivity` | Parameter sensitivity analysis |
224
-
225
- ```bash
226
- # Atlas 14 rainfall for all durations and return periods
227
- curl "https://geotapdata.com/api/v1/rainfall/atlas14?lat=32.78&lon=-96.80"
228
-
229
- # Generate a 25-year, 24-hour design storm hyetograph
230
- curl -X POST "https://geotapdata.com/api/v1/rainfall/hyetograph" \
231
- -H "Content-Type: application/json" \
232
- -d '{
233
- "latitude": 32.78,
234
- "longitude": -96.80,
235
- "returnPeriod": "25yr",
236
- "duration": 24,
237
- "timeInterval": 15,
238
- "distribution": "SCS Type III"
239
- }'
240
-
241
- # Climate-adjusted rainfall projection
242
- curl -X POST "https://geotapdata.com/api/v1/rainfall/climate/project" \
243
- -H "Content-Type: application/json" \
244
- -d '{
245
- "latitude": 32.78,
246
- "longitude": -96.80,
247
- "returnPeriod": "100yr",
248
- "duration": 24,
249
- "horizon": "mid-century",
250
- "scenario": "SSP5-8.5"
251
- }'
252
- ```
253
-
254
- #### Watershed & Hydrology
255
-
256
- | Method | Endpoint | Description |
257
- |--------|----------|-------------|
258
- | POST | `/watershed/delineate` | Delineate watershed (USGS StreamStats) |
259
- | GET | `/watershed/characteristics?lat={lat}&lng={lng}` | Basin parameters |
260
- | GET | `/watershed/flow-statistics?lat={lat}&lng={lng}` | Peak/low flow estimates |
261
- | GET | `/watershed/flowlines?bbox={w,s,e,n}` | Stream network (NHD) |
262
- | GET | `/watershed/water-quality?bbox={w,s,e,n}` | Watershed water quality |
263
-
264
- ```bash
265
- # Delineate watershed from a pour point
266
- curl -X POST "https://geotapdata.com/api/v1/watershed/delineate" \
267
- -H "Content-Type: application/json" \
268
- -d '{"lat": 36.12, "lng": -97.06}'
269
- ```
270
-
271
- #### Hydrology Toolkit
272
-
273
- | Method | Endpoint | Description |
274
- |--------|----------|-------------|
275
- | POST | `/hydrology/analyze` | Complete hydrologic analysis (CN, Tc, peak flow) |
276
- | GET | `/hydrology/distributions` | Available rainfall distributions |
277
- | GET | `/hydrology/distribution?lat={lat}&lon={lon}` | Recommended distribution |
278
-
279
- #### Curve Number
280
-
281
- | Method | Endpoint | Description |
282
- |--------|----------|-------------|
283
- | GET | `/cn/lookup?nlcd={code}&hsg={group}` | Lookup CN for land use + soil |
284
- | GET | `/cn/tables` | Complete CN lookup tables |
285
- | POST | `/cn/analyze` | Weighted CN for catchment polygons |
286
-
287
- ```bash
288
- # Lookup curve number for developed land on B soils
289
- curl "https://geotapdata.com/api/v1/cn/lookup?nlcd=22&hsg=B"
290
-
291
- # Calculate weighted CN for a catchment
292
- curl -X POST "https://geotapdata.com/api/v1/cn/analyze" \
293
- -H "Content-Type: application/json" \
294
- -d '{"catchments": {"type": "FeatureCollection", "features": [...]}}'
295
- ```
296
-
297
- #### Water Quality
298
-
299
- | Method | Endpoint | Description |
300
- |--------|----------|-------------|
301
- | POST | `/water-quality/receiving-water` | EPA ATTAINS data with downstream trace |
302
- | GET | `/water-quality/impairments?huc12={code}` | Impairments by HUC-12 |
303
- | GET | `/water-quality/watershed?lat={lat}&lon={lon}` | Identify HUC-12 for a point |
304
-
305
- #### Waterway Permits
306
-
307
- | Method | Endpoint | Description |
308
- |--------|----------|-------------|
309
- | POST | `/waterway-permits/features` | Find streams, wetlands, waterbodies |
310
- | POST | `/waterway-permits/analyze` | Determine required permits |
311
-
312
- #### Monitoring Stations
313
-
314
- | Method | Endpoint | Description |
315
- |--------|----------|-------------|
316
- | GET | `/stations?bbox={w,s,e,n}` | Find USGS/NOAA stations |
317
- | GET | `/stations/search?q={query}` | Search by name or ID |
318
- | GET | `/stations/types` | Available station types |
319
- | GET | `/stations/watersheds?bbox={w,s,e,n}` | HUC watershed boundaries |
320
- | GET | `/stations/watersheds/{hucCode}` | Specific watershed by HUC code |
321
-
322
- #### Gage Intelligence
323
-
324
- **Gauged sites** (requires USGS station ID):
325
-
326
- | Method | Endpoint | Description |
327
- |--------|----------|-------------|
328
- | GET | `/gage-intelligence/{siteId}/flood-frequency` | Bulletin 17C flood frequency |
329
- | GET | `/gage-intelligence/{siteId}/flow-duration` | Flow duration curve |
330
- | GET | `/gage-intelligence/{siteId}/low-flow` | 7Q10, 7Q2, harmonic mean |
331
- | GET | `/gage-intelligence/{siteId}/storm-events` | Historical storm events |
332
- | GET | `/gage-intelligence/{siteId}/storm-events/{eventId}` | Storm event detail |
333
- | GET | `/gage-intelligence/{siteId}/storm-events/{eventId}/export` | Export for HEC-HMS |
334
- | GET | `/gage-intelligence/{siteId}/summary` | Gage overview |
335
- | GET | `/gage-intelligence/{siteId}/published-stats` | Official USGS GageStats |
336
- | GET | `/gage-intelligence/{siteId}/compare` | Computed vs. published QA |
337
-
338
- **Ungaged sites** (regional regression):
339
-
340
- | Method | Endpoint | Description |
341
- |--------|----------|-------------|
342
- | POST | `/gage-intelligence/ungaged/estimate` | NSS flood frequency estimate |
343
- | POST | `/gage-intelligence/ungaged/estimate-all` | All available statistics |
344
- | GET | `/gage-intelligence/ungaged/regions?state={ST}` | NSS regions by state |
345
- | GET | `/gage-intelligence/ungaged/parameters?state={ST}` | Required basin characteristics |
346
-
347
- **Watershed similarity**:
348
-
349
- | Method | Endpoint | Description |
350
- |--------|----------|-------------|
351
- | POST | `/gage-intelligence/similarity/find` | Find analog watersheds |
352
- | POST | `/gage-intelligence/similarity/find-with-stats` | Similar watersheds + stats |
353
- | POST | `/gage-intelligence/similarity/recommend-index` | Best reference gage |
354
- | POST | `/gage-intelligence/similarity/transfer` | Transfer statistics (DA ratio) |
355
-
356
- ```bash
357
- # Flood frequency at USGS gage 08158000 (Colorado River at Austin)
358
- curl "https://geotapdata.com/api/v1/gage-intelligence/08158000/flood-frequency"
359
-
360
- # 7Q10 low flow for NPDES permits
361
- curl "https://geotapdata.com/api/v1/gage-intelligence/08158000/low-flow"
362
-
363
- # Estimate flood frequency at an ungaged site
364
- curl -X POST "https://geotapdata.com/api/v1/gage-intelligence/ungaged/estimate" \
365
- -H "Content-Type: application/json" \
366
- -d '{"state": "TX", "region": "4", "parameters": {"drainageArea": 10.5}}'
367
- ```
368
-
369
- #### Elevation & Terrain
370
-
371
- | Method | Endpoint | Description |
372
- |--------|----------|-------------|
373
- | GET | `/spatial/dem-stats?bbox={w,s,e,n}` | Min/max/mean elevation |
374
- | GET | `/spatial/contours?bbox={w,s,e,n}` | Contour lines |
375
- | GET | `/spatial/contour-intervals` | Available intervals |
376
- | POST | `/spatial/dem-export` | Export DEM as GeoTIFF |
377
- | POST | `/spatial/contours-export` | Export contours |
378
- | GET | `/spatial/dem-availability?bbox={w,s,e,n}` | Check resolution availability |
379
- | GET | `/spatial/dem-resolutions` | Available DEM resolutions |
380
-
381
- #### Land Use
382
-
383
- | Method | Endpoint | Description |
384
- |--------|----------|-------------|
385
- | POST | `/spatial/nlcd-export` | Export NLCD land cover (GeoTIFF or vector) |
386
-
387
- #### Site Analysis & Reports
65
+ <details>
66
+ <summary><strong>Claude Code (CLI)</strong></summary>
388
67
 
389
- | Method | Endpoint | Description |
390
- |--------|----------|-------------|
391
- | POST | `/site-analysis/report` | Comprehensive environmental report |
392
- | GET | `/site-analysis/report/{jobId}` | Check report status |
393
- | POST | `/constraints/report` | Environmental constraints assessment |
394
- | GET | `/constraints/report/{jobId}` | Check constraints status |
395
- | GET | `/constraints/config` | Constraint configuration options |
396
- | POST | `/site-developability/report` | Developability score (0-100) |
397
- | GET | `/site-developability/config` | Scoring methodology |
68
+ Run this command to add GeoTap to your Claude Code MCP servers:
398
69
 
399
70
  ```bash
400
- # Generate a full site analysis
401
- curl -X POST "https://geotapdata.com/api/v1/site-analysis/report" \
402
- -H "Content-Type: application/json" \
403
- -d '{
404
- "geometry": {"type": "Point", "coordinates": [-97.74, 30.27]},
405
- "projectName": "Oak Hill Development"
406
- }'
407
-
408
- # Check status (reports take 30-60 seconds)
409
- curl "https://geotapdata.com/api/v1/site-analysis/report/{jobId}"
71
+ claude mcp add geotap -- npx -y geotap-mcp-server
410
72
  ```
411
73
 
412
- #### Export
413
-
414
- | Method | Endpoint | Description |
415
- |--------|----------|-------------|
416
- | GET | `/export/config/options` | Available formats and CRS |
417
- | POST | `/export` | Export data (GeoJSON, Shapefile, KML, CSV) |
418
- | GET | `/export/{jobId}` | Check export status + download URL |
419
- | GET | `/export/{jobId}/download` | Download exported file |
74
+ Then set your API key as an environment variable. Add this to your shell profile (`~/.zshrc`, `~/.bashrc`, etc.):
420
75
 
421
76
  ```bash
422
- # Export flood zones and wetlands as a shapefile
423
- curl -X POST "https://geotapdata.com/api/v1/export" \
424
- -H "Content-Type: application/json" \
425
- -d '{
426
- "layers": ["flood_zones", "wetlands"],
427
- "format": "shapefile",
428
- "geometry": {"type": "Polygon", "coordinates": [[...]]}
429
- }'
77
+ export GEOTAP_API_KEY="your-api-key-here"
430
78
  ```
431
79
 
432
- #### Satellite Imagery
80
+ Restart your terminal, then start Claude Code. GeoTap tools will be available automatically.
433
81
 
434
- | Method | Endpoint | Description |
435
- |--------|----------|-------------|
436
- | POST | `/spatial/satellite-export` | Export aerial imagery as GeoTIFF |
437
- | GET | `/spatial/satellite-resolutions` | Available resolutions |
438
-
439
- #### Health & Status
440
-
441
- | Method | Endpoint | Description |
442
- |--------|----------|-------------|
443
- | GET | `/health` | API health check |
444
- | GET | `/status` | All data source connectivity |
445
- | GET | `/status/{apiName}` | Specific API status |
446
- | GET | `/docs` | API documentation (JSON) |
82
+ </details>
447
83
 
448
84
  ---
449
85
 
450
- ## MCP Server
451
-
452
- The MCP (Model Context Protocol) server wraps the REST API into **16 consolidated tools** (or 109 legacy tools) that Claude, Cursor, Windsurf, and other AI assistants can call directly.
453
-
454
- ### Installation
455
-
456
- #### Claude Desktop
86
+ <details>
87
+ <summary><strong>Cursor</strong></summary>
457
88
 
458
- Add to your `claude_desktop_config.json`:
89
+ 1. Open Cursor
90
+ 2. Go to **Settings** (⌘ + , on Mac, Ctrl + , on Windows) → search for **"MCP"**
91
+ 3. Click **"Edit in settings.json"** or add to your `.cursor/mcp.json` file:
459
92
 
460
93
  ```json
461
94
  {
462
95
  "mcpServers": {
463
96
  "geotap": {
464
97
  "command": "npx",
465
- "args": ["-y", "geotap-mcp-server"]
98
+ "args": ["-y", "geotap-mcp-server"],
99
+ "env": {
100
+ "GEOTAP_API_KEY": "your-api-key-here"
101
+ }
466
102
  }
467
103
  }
468
104
  }
469
105
  ```
470
106
 
471
- #### Cursor
472
-
473
- Add to your Cursor MCP settings:
474
-
475
- ```json
476
- {
477
- "mcpServers": {
478
- "geotap": {
479
- "command": "npx",
480
- "args": ["-y", "geotap-mcp-server"]
481
- }
482
- }
483
- }
484
- ```
107
+ 4. Restart Cursor
108
+ 5. Open the AI chat panel — GeoTap tools will appear in the available tools list
485
109
 
486
- #### Windsurf / Other MCP Clients
110
+ </details>
487
111
 
488
- ```bash
489
- npm install -g geotap-mcp-server
490
- geotap-mcp
491
- ```
112
+ ---
492
113
 
493
- ### Configuration
114
+ <details>
115
+ <summary><strong>Windsurf</strong></summary>
494
116
 
495
- | Variable | Description | Default |
496
- |----------|-------------|---------|
497
- | `GEOTAP_API_URL` | API base URL | `https://geotapdata.com/api/v1` |
498
- | `GEOTAP_API_KEY` | Optional API key | (none — free tier) |
117
+ 1. Open Windsurf
118
+ 2. Go to **Settings** → **MCP Servers** (or edit `~/.codeium/windsurf/mcp_config.json` directly)
119
+ 3. Add:
499
120
 
500
- With API key:
501
121
  ```json
502
122
  {
503
123
  "mcpServers": {
@@ -512,201 +132,85 @@ With API key:
512
132
  }
513
133
  ```
514
134
 
515
- ### What You Can Ask
516
-
517
- - *"What are the flood zones at 123 Main St, Austin TX?"*
518
- - *"Is this property in a wetland?"*
519
- - *"What soil types are on this site?"*
520
- - *"What's the 100-year rainfall for Dallas?"*
521
- - *"Delineate the watershed at this point"*
522
- - *"Are there any EPA Superfund sites near here?"*
523
- - *"What's the curve number for this drainage area?"*
524
- - *"What are the peak flood flows for this stream?"*
525
- - *"What's the 7Q10 low flow at this gauge?"*
526
- - *"Generate a design storm hyetograph for a 25-year, 24-hour event"*
527
- - *"How will climate change affect rainfall at this location?"*
528
- - *"Run a full environmental site analysis for this parcel"*
529
- - *"What permits do I need to build near this stream?"*
530
- - *"Export this data as a shapefile"*
531
-
532
- ### Available Tools (109 legacy / 16 consolidated)
533
-
534
- **Core tools (start here):**
535
- - **query_address** — Geocode + environmental query in one call. Returns properties with plain-English interpretations. (<5KB response)
536
- - **identify_features_at_point** — Same as above but for lat/lng coordinates
537
- - **get_rainfall_data** — NOAA Atlas 14 precipitation data
538
- - **get_environmental_summary** — Quick feature counts per layer
539
- - **geocode_address** — Convert address to coordinates
135
+ 4. Restart Windsurf
540
136
 
541
- <details>
542
- <summary>All Spatial Queries (6)</summary>
543
-
544
- - **query_address** — Geocode + point query in one call (recommended starting tool)
545
- - **identify_features_at_point** — Point-in-polygon query (properties only, no geometry)
546
- - **get_environmental_data_for_area** — Query all 37 data sources within a polygon (supports geometry=none)
547
- - **get_environmental_data_near_point** — Query all data sources near a lat/lng point (supports geometry=none)
548
- - **get_environmental_summary** — Quick feature counts per layer for an area
549
- - **get_environmental_data_in_bbox** — Query data within a bounding box (supports geometry=none)
550
137
  </details>
551
138
 
552
- <details>
553
- <summary>Data Layers (3)</summary>
554
-
555
- - **list_data_layers** — List all 37 available data sources
556
- - **get_layer_details** — Get metadata about a specific layer
557
- - **get_layer_features** — Get features from a specific data layer
558
- </details>
559
-
560
- <details>
561
- <summary>Rainfall & Precipitation (14)</summary>
562
-
563
- - **get_rainfall_data** — NOAA Atlas 14 precipitation frequency estimates
564
- - **get_idf_curves** — Intensity-Duration-Frequency curve data
565
- - **generate_hyetograph** — Design storm rainfall distribution over time
566
- - **export_hyetograph** — Export hyetograph as CSV/JSON for modeling software
567
- - **list_rainfall_distributions** — All available temporal distribution types
568
- - **get_rainfall_distribution** — Recommended SCS distribution for a location
569
- - **get_climate_scenarios** — Available climate change scenarios and horizons
570
- - **get_climate_change_factors** — Climate adjustment multipliers for a location
571
- - **get_climate_change_rainfall_projection** — Future rainfall under climate scenarios
572
- - **get_rainfall_uncertainty_bounds** — Atlas 14 confidence intervals
573
- - **generate_uncertainty_envelope** — Monte Carlo uncertainty bands for design storms
574
- - **run_rainfall_sensitivity_analysis** — Parameter sensitivity analysis
575
- - **get_design_approaches** — Risk-based design confidence levels
576
- - **check_rainfall_service_status** — NOAA Atlas 14 availability check
577
- </details>
578
-
579
- <details>
580
- <summary>Watershed & Hydrology (5)</summary>
581
-
582
- - **delineate_watershed** — Trace watershed boundary from a pour point (USGS StreamStats)
583
- - **get_watershed_characteristics** — Basin physical/hydrologic parameters
584
- - **get_flow_statistics** — Peak and low flow estimates (regional regression)
585
- - **get_flowlines** — Stream network from NHD
586
- - **get_watershed_water_quality** — Water quality in the containing watershed
587
- </details>
139
+ ---
588
140
 
589
141
  <details>
590
- <summary>Hydrology Toolkit (3)</summary>
142
+ <summary><strong>Other MCP-Compatible Clients</strong></summary>
591
143
 
592
- - **analyze_hydrology** Complete hydrologic analysis (CN, Tc, SCS runoff, peak flow)
593
- - **get_hydrology_distributions** — Available rainfall distributions for analysis
594
- - **get_hydrology_distribution_for_location** — Recommended distribution for a point
595
- </details>
144
+ For any MCP client, the server can be run directly:
596
145
 
597
- <details>
598
- <summary>Curve Number / Runoff (3)</summary>
146
+ ```bash
147
+ # Install globally
148
+ npm install -g geotap-mcp-server
599
149
 
600
- - **lookup_curve_number** SCS CN for a land use + soil type combination
601
- - **get_curve_number_tables** — Complete CN lookup tables
602
- - **analyze_curve_numbers** — Weighted CN calculation for catchment areas
603
- </details>
150
+ # Run with your API key
151
+ GEOTAP_API_KEY=your-api-key-here geotap-mcp
152
+ ```
604
153
 
605
- <details>
606
- <summary>Water Quality (3)</summary>
154
+ The server communicates over **stdio** — point your MCP client to the `geotap-mcp` command with the `GEOTAP_API_KEY` environment variable set.
607
155
 
608
- - **get_water_quality** — EPA ATTAINS impairment data with downstream trace
609
- - **get_water_impairments** — Quick impairment check by HUC-12
610
- - **get_watershed_for_point** — Identify HUC-12 watershed for a location
611
156
  </details>
612
157
 
613
- <details>
614
- <summary>Waterway Permits (2)</summary>
615
-
616
- - **find_water_features** — Find streams, wetlands, waterbodies in an area
617
- - **analyze_permit_requirements** — Determine required permits (Section 404, NPDES, etc.)
618
- </details>
158
+ ---
619
159
 
620
- <details>
621
- <summary>Elevation & Terrain (7)</summary>
622
-
623
- - **get_elevation_stats** — Min/max/mean elevation (USGS 3DEP)
624
- - **get_contour_lines** — Generate topographic contour lines
625
- - **get_contour_interval_options** — Available contour intervals
626
- - **export_dem** — Export DEM as GeoTIFF (1m/10m/30m)
627
- - **export_contours** — Export contour lines as GeoJSON
628
- - **check_dem_availability** — Check which resolutions are available
629
- - **get_dem_resolution_options** — Available DEM resolutions
630
- </details>
160
+ ### Step 3: Start Asking Questions
631
161
 
632
- <details>
633
- <summary>Land Use / Land Cover (1)</summary>
162
+ Once connected, ask your AI assistant to pull data for any US site. GeoTap collects from all 80+ federal sources at once — just give it a location and then ask whatever you want:
634
163
 
635
- - **export_land_use** — NLCD land cover data (GeoTIFF or vector)
636
- </details>
164
+ ```
165
+ "Collect site data for 123 Main St, Austin TX"
166
+ ```
637
167
 
638
- <details>
639
- <summary>Monitoring Stations (3)</summary>
168
+ Once the data comes back (~60-120 seconds), you can ask follow-up questions like:
640
169
 
641
- - **find_monitoring_stations** Search for USGS/NOAA/EPA stations
642
- - **search_stations** Search stations by name or ID
643
- - **get_station_types** Available station type configurations
644
- </details>
170
+ - *"Is this site in a flood zone?"*
171
+ - *"What soil types are here and what's the curve number?"*
172
+ - *"Are there any contamination concerns nearby?"*
173
+ - *"What's the 100-year rainfall?"*
174
+ - *"What permits would I need to develop this site?"*
175
+ - *"Summarize the key environmental risks"*
645
176
 
646
- <details>
647
- <summary>Gage Intelligence — Gauged Sites (9)</summary>
648
-
649
- - **get_flood_frequency_analysis** — Bulletin 17C flood frequency at a USGS gauge
650
- - **get_flow_duration_curve** — Flow duration curve and percentiles
651
- - **get_low_flow_statistics** — 7Q10, 7Q2, harmonic mean (NPDES critical flows)
652
- - **get_storm_events** — Detect and analyze historical storm events
653
- - **get_storm_event_detail** — Detailed data for a specific storm event
654
- - **export_storm_event_for_modeling** — Export storm event for HEC-HMS
655
- - **get_gage_summary** — Quick overview of available data at a gauge
656
- - **get_published_gage_statistics** — Official USGS GageStats values
657
- - **compare_computed_vs_published_stats** — QA comparison of computed vs. published
658
- </details>
177
+ ### Troubleshooting
659
178
 
660
- <details>
661
- <summary>Gage Intelligence — Ungaged Sites (4)</summary>
179
+ | Problem | Solution |
180
+ |---------|----------|
181
+ | Server won't start / "GEOTAP_API_KEY is required" | Make sure your API key is set in the `env` block of your MCP config |
182
+ | "npx: command not found" | Install [Node.js](https://nodejs.org/) (v18+), which includes npx |
183
+ | Tools don't appear in Claude Desktop | Restart Claude Desktop completely (quit + reopen, not just close the window) |
184
+ | Rate limit errors | Wait a moment and retry — burst limits are per-minute |
662
185
 
663
- - **estimate_ungaged_flood_frequency** — NSS regional regression estimates
664
- - **estimate_all_ungaged_statistics** — All available statistics for ungaged site
665
- - **get_ungaged_nss_regions** — Available NSS regions by state
666
- - **get_ungaged_required_parameters** — Required basin characteristics for estimation
667
- </details>
186
+ ---
668
187
 
669
- <details>
670
- <summary>Gage Intelligence — Watershed Similarity (4)</summary>
188
+ ## Data Sources
671
189
 
672
- - **find_similar_watersheds** Find analog gauged watersheds
673
- - **find_similar_watersheds_with_stats** — Similar watersheds with published stats
674
- - **recommend_index_gage** Best reference gage for flow transfer
675
- - **transfer_flood_statistics** Transfer statistics via drainage area ratio
676
- </details>
190
+ | Agency | Data Available |
191
+ |--------|---------------|
192
+ | **FEMA** | Flood zones, FIRM panels, flood insurance rate maps, floodway boundaries |
193
+ | **USGS** | Elevation (3DEP at 1m/10m/30m), geology, streamgages, groundwater, land use (NLCD), StreamStats, National Streamflow Statistics (NSS) |
194
+ | **EPA** | Water quality (ATTAINS), Superfund sites, brownfields, TRI toxic releases, USTs, NPDES outfalls |
195
+ | **NOAA** | Rainfall (Atlas 14), IDF curves, tide stations, climate projections (CMIP6), weather stations, radar |
196
+ | **USDA/NRCS** | Soils (SSURGO), curve numbers, hydrologic soil groups, TR-55 parameters |
197
+ | **USFWS** | Wetlands (NWI), endangered species, critical habitat |
198
+ | **DOT** | Bridges, tunnels, National Bridge Inventory |
199
+ | **Census** | Demographics, boundaries, TIGER geographic data |
200
+ | **USACE** | Dams, levees, navigation channels |
201
+ | **NHD** | Stream flowlines, hydrography, watershed boundaries (HUC-8/10/12) |
202
+ | **Other** | Power plants, mines, tribal lands, building footprints, and more |
677
203
 
678
- <details>
679
- <summary>Site Analysis & Reports (7)</summary>
680
-
681
- - **generate_site_analysis** — Comprehensive environmental site analysis
682
- - **get_site_analysis_status** — Check analysis job status
683
- - **generate_constraints_report** — Environmental constraints assessment
684
- - **get_constraints_report_status** — Check constraints report status
685
- - **get_constraints_config** — Available constraint configuration options
686
- - **generate_developability_report** — Site development feasibility score (0-100)
687
- - **get_developability_config** — Scoring methodology and options
688
- </details>
204
+ Every response includes **source attribution** — the federal agency, dataset name, and reference URL.
689
205
 
690
- <details>
691
- <summary>Export (3)</summary>
206
+ ---
692
207
 
693
- - **get_export_options** — Available formats and CRS options
694
- - **export_data** — Export to GeoJSON, Shapefile, KML, CSV, GeoPackage
695
- - **get_export_status** — Check export job status
696
- </details>
208
+ ## Configuration
697
209
 
698
- <details>
699
- <summary>Utilities (8)</summary>
700
-
701
- - **geocode_address** Convert address to coordinates
702
- - **check_api_status** — Check all data source connectivity
703
- - **check_specific_api_status** — Check a specific API's status
704
- - **get_firm_panels** — FEMA FIRM map panel numbers
705
- - **get_huc_watersheds** — HUC watershed boundaries
706
- - **get_huc_watershed_by_code** — Specific watershed by HUC code
707
- - **export_satellite_imagery** — Aerial/satellite imagery as GeoTIFF
708
- - **get_satellite_resolution_options** — Available imagery resolutions
709
- </details>
210
+ | Variable | Description | Required |
211
+ |----------|-------------|----------|
212
+ | `GEOTAP_API_KEY` | Your API key from registration | **Yes** |
213
+ | `GEOTAP_API_URL` | Custom API endpoint (advanced) | No |
710
214
 
711
215
  ---
712
216
 
@@ -717,7 +221,6 @@ With API key:
717
221
  - Flood analysis: Bulletin 17C flood frequency, flow duration curves, regional regression estimates
718
222
  - Watershed delineation and hydrologic modeling inputs (HEC-HMS, SWMM)
719
223
  - Low-flow analysis for NPDES permits (7Q10, 7Q2, harmonic mean flow)
720
- - Ungaged site estimation using NSS regression equations and watershed similarity
721
224
  - Climate-adjusted design storms for infrastructure resilience
722
225
 
723
226
  ### Real Estate & Development
@@ -732,62 +235,6 @@ With API key:
732
235
  - Endangered species habitat screening (USFWS critical habitat)
733
236
  - Water quality impairment assessment (EPA ATTAINS 303(d) list)
734
237
 
735
- ### AI-Powered Research
736
- - Natural language queries across 37 federal databases
737
- - Automated environmental screening reports
738
- - Cross-agency data correlation and analysis
739
-
740
- ---
741
-
742
- ## Example Workflows
743
-
744
- ### Quick Site Screening
745
- ```
746
- User: "What environmental concerns are there at 456 Oak Ave, Houston TX?"
747
-
748
- 1. geocode_address → get coordinates
749
- 2. get_environmental_data_near_point → flood zones, wetlands, soils, EPA sites
750
- 3. Summarize findings in plain language
751
- ```
752
-
753
- ### Stormwater Design Package
754
- ```
755
- User: "I need a complete stormwater design package for this 50-acre site in Dallas"
756
-
757
- 1. geocode_address → coordinates
758
- 2. get_rainfall_data → Atlas 14 depths for all return periods
759
- 3. get_rainfall_distribution → SCS Type III for Dallas
760
- 4. generate_hyetograph → 25-year, 24-hour design storm
761
- 5. delineate_watershed → drainage area boundary
762
- 6. analyze_curve_numbers → weighted CN from land use + soils
763
- 7. analyze_hydrology → time of concentration + peak discharge
764
- 8. get_water_quality → receiving water impairments
765
- 9. analyze_permit_requirements → required permits
766
- ```
767
-
768
- ### Ungaged Flood Estimation
769
- ```
770
- User: "What's the 100-year flood at 30.5, -97.8? There's no gauge there."
771
-
772
- 1. get_ungaged_nss_regions → find the NSS region for Texas
773
- 2. get_watershed_characteristics → get basin parameters
774
- 3. estimate_ungaged_flood_frequency → regional regression estimate
775
- 4. find_similar_watersheds_with_stats → validate with nearby gauged data
776
- 5. recommend_index_gage → find best reference gage
777
- 6. transfer_flood_statistics → drainage area ratio transfer for comparison
778
- ```
779
-
780
- ### Environmental Due Diligence
781
- ```
782
- User: "Run full environmental due diligence on this 20-acre parcel"
783
-
784
- 1. generate_site_analysis → comprehensive environmental report
785
- 2. generate_developability_report → 0-100 feasibility score
786
- 3. find_water_features → jurisdictional waters on site
787
- 4. analyze_permit_requirements → permit pathway and costs
788
- 5. get_water_quality → downstream receiving water assessment
789
- ```
790
-
791
238
  ---
792
239
 
793
240
  ## Contributing
@@ -801,6 +248,5 @@ MIT
801
248
  ## Links
802
249
 
803
250
  - **Web App**: [geotapdata.com](https://geotapdata.com)
804
- - **API Docs (JSON)**: [geotapdata.com/api/v1/docs](https://geotapdata.com/api/v1/docs)
805
251
  - **Issues**: [GitHub Issues](https://github.com/jcholly/geotap-developer/issues)
806
252
  - **npm**: [geotap-mcp-server](https://www.npmjs.com/package/geotap-mcp-server)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geotap-mcp-server",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "MCP server for GeoTap — collect comprehensive environmental data from 80+ US federal sources for any site. One tool, all the data.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/api.js CHANGED
@@ -1,6 +1,25 @@
1
1
  const BASE_URL = process.env.GEOTAP_API_URL || 'https://geotapdata.com/api/v1';
2
2
  const API_KEY = process.env.GEOTAP_API_KEY || '';
3
3
 
4
+ /**
5
+ * Validate that an API key is configured.
6
+ * Throws a descriptive error if missing — the MCP server requires a key.
7
+ */
8
+ export function requireApiKey() {
9
+ if (!API_KEY) {
10
+ throw new Error(
11
+ 'GEOTAP_API_KEY is required.\n\n' +
12
+ '1. Register for a free API key:\n' +
13
+ ' curl -X POST https://geotapdata.com/api/keys/register \\\n' +
14
+ ' -H "Content-Type: application/json" \\\n' +
15
+ ' -d \'{"email": "you@example.com"}\'\n\n' +
16
+ '2. Add it to your MCP config:\n' +
17
+ ' "env": { "GEOTAP_API_KEY": "your-key-here" }\n\n' +
18
+ 'See https://github.com/jcholly/geotap-developer for setup instructions.'
19
+ );
20
+ }
21
+ }
22
+
4
23
  /**
5
24
  * Structured API Error with fix instructions for LLMs.
6
25
  */
@@ -105,9 +124,7 @@ export async function callApi(endpoint, method, params) {
105
124
  'User-Agent': 'geotap-mcp-server/2.2.1'
106
125
  };
107
126
 
108
- if (API_KEY) {
109
- headers['X-API-Key'] = API_KEY;
110
- }
127
+ headers['X-API-Key'] = API_KEY;
111
128
 
112
129
  // Substitute path parameters like {siteId} with values from params
113
130
  let resolvedEndpoint = endpoint;
package/src/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
5
  import { z } from 'zod';
6
- import { callApi, StructuredApiError } from './api.js';
6
+ import { callApi, StructuredApiError, requireApiKey } from './api.js';
7
7
  import { readFileSync } from 'fs';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { dirname, join } from 'path';
@@ -259,6 +259,14 @@ server.tool(
259
259
  }
260
260
  );
261
261
 
262
+ // Require API key before starting
263
+ try {
264
+ requireApiKey();
265
+ } catch (err) {
266
+ console.error(`[geotap] ERROR: ${err.message}`);
267
+ process.exit(1);
268
+ }
269
+
262
270
  console.error(`[geotap] v3.0.0 — 2 tools (collect_site_data, get_results) + 1 meta-tool (get_llms_txt)`);
263
271
 
264
272
  // Start server