geotap-mcp-server 3.0.0 → 3.0.2

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 (3) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +1 -1
  3. package/src/index.js +90 -16
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GeoTap
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geotap-mcp-server",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
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/index.js CHANGED
@@ -27,18 +27,59 @@ DATA INCLUDES:
27
27
  - Contamination: Superfund, brownfields, USTs, EPA-regulated facilities (RCRA, GHG, FRS)
28
28
  - Water: streams, watershed, water quality impairments (ATTAINS), NPDES outfalls, groundwater
29
29
  - Hazards: seismic design (ASCE 7-22), earthquakes, wildfires, landslides, coastal vulnerability, NRI
30
- - Rainfall: NOAA Atlas 14 precipitation frequency data
30
+ - Rainfall: NOAA Atlas 14 precipitation frequency data (IDF curves, design storms)
31
+ - Land cover: NLCD 2021 classification (developed, forest, wetlands, etc.)
32
+ - Elevation: USGS 3DEP (min/max/mean elevation, relief)
31
33
  - Infrastructure: hospitals, fire stations, schools, EMS, dams, levees, power plants, airports, railroads, bridges
32
34
  - Ecology: species (GBIF), fish habitat, critical habitat, cropland, national forests, BLM lands, historic places
33
35
  - Energy: solar potential, utility rates, EV charging stations
34
- - Demographics: Census ACS (population, income, housing, poverty)
36
+ - Demographics: Census ACS (population, income, housing, poverty, vacancy rates)
35
37
  - Protected lands (PAD-US), wild & scenic rivers, sole source aquifers
36
38
 
39
+ HOW TO PRESENT RESULTS:
40
+ The goal is a scannable engineering document, not a data dump. An engineer doing site due diligence needs to answer three questions fast:
41
+ 1. What kills the project? (floodway, contamination, protected species)
42
+ 2. What complicates permitting? (wetlands, impaired waters, high slopes, poor soils)
43
+ 3. What's the baseline context? (rainfall IDF, seismic params, demographics, infrastructure)
44
+
45
+ CRITICAL FLAGS — scan results and lead with these if present:
46
+ - Any FEMA zone AE/AO/VE (SFHA): "Site intersects SFHA — Zone [X]" (CRITICAL)
47
+ - Any floodway: "Regulatory floodway — no-rise certification required" (CRITICAL)
48
+ - Superfund site nearby: "NPL Superfund site within search radius" (CRITICAL)
49
+ - Wetland count > 10: "High wetland density — Section 404 permitting likely" (HIGH)
50
+ - 303(d) impaired water (Category 5): "TMDL required, stricter discharge limits" (HIGH)
51
+ - Brownfields > 3: "Phase I ESA recommended" (MODERATE)
52
+ - Soils with HSG D: "Poorly draining soils — stormwater design impact" (MODERATE)
53
+
54
+ SECTION ORDER (skip sections with no data):
55
+ 1. Site overview — address, coordinates, county, elevation (min/max/mean), land cover, area
56
+ 2. FEMA flood zones — table with zone, subtype, SFHA status, risk level
57
+ 3. Soils — one block per soil unit: HSG, drainage class, slope, flood frequency, limitations
58
+ 4. Atlas 14 rainfall — IDF table (rows: 15min, 1hr, 6hr, 12hr, **24hr bold**, 3day; cols: 2yr, 5yr, 10yr, 25yr, 50yr, 100yr). Include Atlas 14 volume/version.
59
+ 5. Natural hazard risk — NRI ratings by hazard type (overall, flooding, tornado, earthquake, etc.)
60
+ 6. Wetlands — count, type breakdown, Section 404 permitting note
61
+ 7. Water resources — streams (with distances), impaired waters (category), watershed HUC
62
+ 8. Contamination — Superfund, brownfields (with distances/status), USTs, NPDES outfalls
63
+ 9. Seismic & dams — ASCE 7-22 params (SDS, SD1, SDC, PGA), nearby dams with hazard rating
64
+ 10. Infrastructure — hospitals, fire stations, schools, EMS counts with distances
65
+ 11. Solar & energy — DNI, GHI, capacity factor, utility rates
66
+ 12. Demographics — population, median income, vacancy rate (from Census ACS)
67
+
68
+ FORMATTING RULES:
69
+ - Use markdown tables for flood zones, rainfall IDF, brownfields, soils
70
+ - Bold the 24-hr row in rainfall tables — it's the most referenced for stormwater design
71
+ - For soils, always include HSG and drainage class — these drive CN calculations
72
+ - Include distances and cardinal directions for nearby features (e.g., "0.8 mi NW")
73
+ - When a source returned no data ("_noData"), mention it where relevant ("no Superfund sites" is positive)
74
+ - Cite source agencies (FEMA, NRCS, NOAA Atlas 14, EPA), not just "GeoTap"
75
+ - End with disclaimer: "Data sourced from US federal agencies via GeoTap. Verify critical findings against authoritative sources before making engineering or regulatory decisions."
76
+
37
77
  IMPORTANT:
38
- - All data from authoritative US federal sources. Always cite the source agency.
78
+ - All data from authoritative US federal sources. Always cite the source agency, not just "GeoTap."
39
79
  - Data is for informational purposes. Remind users to verify for engineering/regulatory decisions.
40
80
  - Coordinates must be within the United States (including territories).
41
- - If a data source returns "_noData: true", it was queried but found nothing at that location.`
81
+ - If a data source returns "_noData: true", it was queried but found nothing at that location — mention this where relevant (no contamination nearby is positive).
82
+ - If a data source returns "_error", note that the source was unavailable and the user should check back.`
42
83
  });
43
84
 
44
85
  // ── Tool: collect_site_data ──────────────────────────────────────────
@@ -66,18 +107,21 @@ Data returned covers: flood zones, wetlands, soils, geology, contamination sites
66
107
  if (address && !siteGeometry) {
67
108
  // Geocode the address first
68
109
  const geocodeResult = await callApi('/geocode', 'GET', { address });
69
- if (!geocodeResult?.lat || !geocodeResult?.lng) {
110
+ // API returns { success, results: [{ lat, lon, displayName, source }] }
111
+ const match = geocodeResult?.results?.[0];
112
+ if (!match?.lat || !match?.lon) {
70
113
  return {
71
114
  content: [{ type: 'text', text: JSON.stringify({
72
115
  error: true,
73
- message: `Could not geocode address: "${address}". Try a more specific address or use lat/lng coordinates.`,
116
+ message: `Could not geocode address: "${address}". Try a more specific address with city/state, or use lat/lng coordinates directly.`,
117
+ suggestion: 'Example: { lat: 34.8779, lng: -82.3313 }',
74
118
  }, null, 2) }],
75
119
  isError: true
76
120
  };
77
121
  }
78
122
  siteGeometry = {
79
123
  type: 'Point',
80
- coordinates: [geocodeResult.lng, geocodeResult.lat]
124
+ coordinates: [match.lon, match.lat]
81
125
  };
82
126
  } else if (lat != null && lng != null && !siteGeometry) {
83
127
  siteGeometry = {
@@ -133,7 +177,7 @@ Data returned covers: flood zones, wetlands, soils, geology, contamination sites
133
177
 
134
178
  server.tool(
135
179
  'get_results',
136
- `Check the status of a data collection job and retrieve results. Poll every 10 seconds until status is "completed". When complete, returns the full data summary from all 80+ federal sources.`,
180
+ `Check the status of a data collection job and retrieve results. Poll every 10 seconds until status is "completed". When complete, returns the full data summary from all 80+ federal sources. Present the results to the user following the formatting instructions in the server description.`,
137
181
  {
138
182
  jobId: z.string().describe('Job ID returned from collect_site_data'),
139
183
  },
@@ -141,15 +185,45 @@ server.tool(
141
185
  try {
142
186
  const result = await callApi(`/site-analysis/data-collect/${encodeURIComponent(params.jobId)}`, 'GET', {});
143
187
 
188
+ const response = { ...result };
189
+
190
+ // Add presentation guidance when results are complete
191
+ if (result.status === 'completed') {
192
+ response._meta = {
193
+ sources: '80+ US federal agencies (FEMA, USGS, NOAA, EPA, NRCS, USFWS, USACE, DOE, DOT, CDC, Census, and more)',
194
+ retrievedAt: new Date().toISOString(),
195
+ disclaimer: 'Data sourced from US federal agencies via GeoTap. Always verify critical data against authoritative sources before making engineering or regulatory decisions.',
196
+ };
197
+ response._presentationGuide = {
198
+ instructions: 'Present as a scannable engineering document. Lead with critical flags, then structured sections. Follow the HOW TO PRESENT RESULTS instructions.',
199
+ priorityOrder: [
200
+ '1. Critical flags (floodway, SFHA, Superfund, high wetland density)',
201
+ '2. FEMA flood zones (table: zone, subtype, SFHA, risk)',
202
+ '3. Soils (HSG, drainage class, slope, limitations)',
203
+ '4. Atlas 14 rainfall (IDF table — bold 24hr row)',
204
+ '5. NRI hazard risk (badge grid by hazard type)',
205
+ '6. Wetlands (count, types, Section 404 note)',
206
+ '7. Water resources (streams, impaired waters with distances)',
207
+ '8. Contamination (Superfund, brownfields, USTs with distances)',
208
+ '9. Seismic & dams (ASCE 7-22 params, nearby dams)',
209
+ '10. Infrastructure (hospitals, fire, schools, EMS counts)',
210
+ '11. Solar/energy & demographics (collapsed/secondary)',
211
+ ],
212
+ tips: [
213
+ 'Lead with what kills or complicates the project — not context',
214
+ 'Use tables for flood zones, rainfall IDF, brownfields, soils',
215
+ 'Bold the 24-hr rainfall row — most referenced for stormwater design',
216
+ 'For soils, always show HSG and drainage class (drives CN calculation)',
217
+ 'Cite source agencies (FEMA, NRCS, NOAA Atlas 14, EPA)',
218
+ '"No Superfund sites nearby" is positive — mention it',
219
+ ]
220
+ };
221
+ } else {
222
+ response._instructions = `Job status: ${result.status}. Poll again in 10 seconds until status is "completed".`;
223
+ }
224
+
144
225
  return {
145
- content: [{ type: 'text', text: JSON.stringify({
146
- ...result,
147
- _meta: {
148
- sources: '80+ US federal agencies (FEMA, USGS, NOAA, EPA, NRCS, USFWS, USACE, DOE, DOT, CDC, Census, and more)',
149
- retrievedAt: new Date().toISOString(),
150
- disclaimer: 'Data sourced from US federal agencies via GeoTap. Always verify critical data against authoritative sources before making engineering or regulatory decisions.',
151
- }
152
- }, null, 2) }]
226
+ content: [{ type: 'text', text: JSON.stringify(response, null, 2) }]
153
227
  };
154
228
  } catch (error) {
155
229
  if (error instanceof StructuredApiError) {