@cyanheads/fema-mcp-server 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +360 -0
- package/CLAUDE.md +360 -0
- package/Dockerfile +100 -0
- package/LICENSE +201 -0
- package/README.md +340 -0
- package/changelog/0.1.x/0.1.1.md +41 -0
- package/changelog/template.md +127 -0
- package/dist/config/server-config.d.ts +9 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +22 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/fema-disaster.resource.d.ts +9 -0
- package/dist/mcp-server/resources/definitions/fema-disaster.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/fema-disaster.resource.js +59 -0
- package/dist/mcp-server/resources/definitions/fema-disaster.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-describe.tool.d.ts +27 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-describe.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-describe.tool.js +99 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-describe.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-query.tool.d.ts +25 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-query.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-query.tool.js +87 -0
- package/dist/mcp-server/tools/definitions/fema-dataframe-query.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-get-disaster.tool.d.ts +33 -0
- package/dist/mcp-server/tools/definitions/fema-get-disaster.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-get-disaster.tool.js +142 -0
- package/dist/mcp-server/tools/definitions/fema-get-disaster.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-get-housing-assistance.tool.d.ts +53 -0
- package/dist/mcp-server/tools/definitions/fema-get-housing-assistance.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-get-housing-assistance.tool.js +246 -0
- package/dist/mcp-server/tools/definitions/fema-get-housing-assistance.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-get-public-assistance.tool.d.ts +45 -0
- package/dist/mcp-server/tools/definitions/fema-get-public-assistance.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-get-public-assistance.tool.js +210 -0
- package/dist/mcp-server/tools/definitions/fema-get-public-assistance.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-query-dataset.tool.d.ts +32 -0
- package/dist/mcp-server/tools/definitions/fema-query-dataset.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-query-dataset.tool.js +128 -0
- package/dist/mcp-server/tools/definitions/fema-query-dataset.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-search-disasters.tool.d.ts +50 -0
- package/dist/mcp-server/tools/definitions/fema-search-disasters.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-search-disasters.tool.js +281 -0
- package/dist/mcp-server/tools/definitions/fema-search-disasters.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-search-nfip.tool.d.ts +38 -0
- package/dist/mcp-server/tools/definitions/fema-search-nfip.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fema-search-nfip.tool.js +307 -0
- package/dist/mcp-server/tools/definitions/fema-search-nfip.tool.js.map +1 -0
- package/dist/services/canvas/canvas-accessor.d.ts +9 -0
- package/dist/services/canvas/canvas-accessor.d.ts.map +1 -0
- package/dist/services/canvas/canvas-accessor.js +11 -0
- package/dist/services/canvas/canvas-accessor.js.map +1 -0
- package/dist/services/openfema/openfema-service.d.ts +52 -0
- package/dist/services/openfema/openfema-service.d.ts.map +1 -0
- package/dist/services/openfema/openfema-service.js +157 -0
- package/dist/services/openfema/openfema-service.js.map +1 -0
- package/dist/services/openfema/types.d.ts +139 -0
- package/dist/services/openfema/types.d.ts.map +1 -0
- package/dist/services/openfema/types.js +6 -0
- package/dist/services/openfema/types.js.map +1 -0
- package/package.json +105 -0
- package/server.json +99 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool: fema_search_nfip — NFIP flood insurance claims with DataCanvas spillover.
|
|
3
|
+
* @module mcp-server/tools/definitions/fema-search-nfip
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
7
|
+
import { getCanvas } from '../../../services/canvas/canvas-accessor.js';
|
|
8
|
+
import { escapeODataString, getOpenFemaService } from '../../../services/openfema/openfema-service.js';
|
|
9
|
+
/** Inline preview budget — ~25k tokens of JSON. */
|
|
10
|
+
const PREVIEW_CHARS = 100_000;
|
|
11
|
+
/** Cap on rows registered to canvas. */
|
|
12
|
+
const MAX_CANVAS_ROWS = 50_000;
|
|
13
|
+
/**
|
|
14
|
+
* Explicit DuckDB schema for NFIP canvas tables. All fields are nullable to
|
|
15
|
+
* prevent NOT NULL constraint failures during append: the sniff-based schema
|
|
16
|
+
* inference marks a column NOT NULL when every row in the sniff window has a
|
|
17
|
+
* non-null value — but NFIP data is sparse and later rows may omit fields
|
|
18
|
+
* that happened to be present in the first N rows.
|
|
19
|
+
*/
|
|
20
|
+
const NFIP_CANVAS_SCHEMA = [
|
|
21
|
+
{ name: 'state', type: 'VARCHAR', nullable: true },
|
|
22
|
+
{ name: 'county_code', type: 'VARCHAR', nullable: true },
|
|
23
|
+
{ name: 'zip_code', type: 'VARCHAR', nullable: true },
|
|
24
|
+
{ name: 'date_of_loss', type: 'VARCHAR', nullable: true },
|
|
25
|
+
{ name: 'year_of_loss', type: 'INTEGER', nullable: true },
|
|
26
|
+
{ name: 'amount_paid_building', type: 'DOUBLE', nullable: true },
|
|
27
|
+
{ name: 'amount_paid_contents', type: 'DOUBLE', nullable: true },
|
|
28
|
+
{ name: 'building_damage_amount', type: 'DOUBLE', nullable: true },
|
|
29
|
+
{ name: 'contents_damage_amount', type: 'DOUBLE', nullable: true },
|
|
30
|
+
{ name: 'rated_flood_zone', type: 'VARCHAR', nullable: true },
|
|
31
|
+
{ name: 'cause_of_damage', type: 'VARCHAR', nullable: true },
|
|
32
|
+
{ name: 'occupancy_type', type: 'INTEGER', nullable: true },
|
|
33
|
+
];
|
|
34
|
+
export const femaSearchNfip = tool('fema_search_nfip', {
|
|
35
|
+
title: 'Search NFIP Flood Insurance Claims',
|
|
36
|
+
description: 'Search National Flood Insurance Program (NFIP) claims data by state, county, ZIP code, and year range. ' +
|
|
37
|
+
'Returns claim counts, amounts paid on building and contents, flood zones, and loss years. ' +
|
|
38
|
+
'state is required — the full NFIP dataset is 2.7 million rows; unfiltered access is prohibited. ' +
|
|
39
|
+
'When DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) and results exceed the inline preview, ' +
|
|
40
|
+
'the full result set is staged on a canvas for SQL aggregation via fema_dataframe_query. ' +
|
|
41
|
+
'Use fema_dataframe_describe to inspect the staged table schema before writing SQL. ' +
|
|
42
|
+
'Without canvas, results are returned inline up to the limit.',
|
|
43
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
44
|
+
input: z.object({
|
|
45
|
+
state: z
|
|
46
|
+
.string()
|
|
47
|
+
.length(2)
|
|
48
|
+
.toUpperCase()
|
|
49
|
+
.describe('Two-letter US state code (required). NFIP dataset is 2.7M rows — state filter is mandatory.'),
|
|
50
|
+
county_code: z
|
|
51
|
+
.string()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('County code to narrow results within the state (e.g., 201 for Harris County TX). Use with state.'),
|
|
54
|
+
zip_code: z.string().optional().describe('ZIP code to narrow results to a specific area.'),
|
|
55
|
+
year_from: z
|
|
56
|
+
.number()
|
|
57
|
+
.int()
|
|
58
|
+
.min(1970)
|
|
59
|
+
.max(2100)
|
|
60
|
+
.optional()
|
|
61
|
+
.describe('Start year of loss, inclusive (e.g., 2020).'),
|
|
62
|
+
year_to: z
|
|
63
|
+
.number()
|
|
64
|
+
.int()
|
|
65
|
+
.min(1970)
|
|
66
|
+
.max(2100)
|
|
67
|
+
.optional()
|
|
68
|
+
.describe('End year of loss, inclusive (e.g., 2023).'),
|
|
69
|
+
limit: z
|
|
70
|
+
.number()
|
|
71
|
+
.int()
|
|
72
|
+
.min(1)
|
|
73
|
+
.max(10000)
|
|
74
|
+
.default(1000)
|
|
75
|
+
.describe('Maximum rows to fetch (1–10000, default 1000).'),
|
|
76
|
+
canvas_id: z
|
|
77
|
+
.string()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe('Optional canvas ID from a prior call. Omit to create a fresh canvas. The response returns the canvas_id to pass to fema_dataframe_query.'),
|
|
80
|
+
}),
|
|
81
|
+
output: z.object({
|
|
82
|
+
claims: z
|
|
83
|
+
.array(z
|
|
84
|
+
.object({
|
|
85
|
+
state: z
|
|
86
|
+
.string()
|
|
87
|
+
.optional()
|
|
88
|
+
.describe('Two-letter state code. Absent when not in the record.'),
|
|
89
|
+
county_code: z
|
|
90
|
+
.string()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe('County code (e.g., 201 for Harris County TX). Absent when not recorded.'),
|
|
93
|
+
zip_code: z
|
|
94
|
+
.string()
|
|
95
|
+
.optional()
|
|
96
|
+
.describe('5-digit ZIP code of the insured property. Absent when not recorded.'),
|
|
97
|
+
date_of_loss: z
|
|
98
|
+
.string()
|
|
99
|
+
.optional()
|
|
100
|
+
.describe('ISO 8601 date the flood loss occurred. Absent when not recorded.'),
|
|
101
|
+
year_of_loss: z
|
|
102
|
+
.number()
|
|
103
|
+
.optional()
|
|
104
|
+
.describe('Calendar year the flood loss occurred. Absent when not recorded.'),
|
|
105
|
+
amount_paid_building: z
|
|
106
|
+
.number()
|
|
107
|
+
.optional()
|
|
108
|
+
.describe('NFIP claim payment for the building structure in USD. Absent when zero or not recorded.'),
|
|
109
|
+
amount_paid_contents: z
|
|
110
|
+
.number()
|
|
111
|
+
.optional()
|
|
112
|
+
.describe('NFIP claim payment for contents (personal property) in USD. Absent when zero or not recorded.'),
|
|
113
|
+
building_damage_amount: z
|
|
114
|
+
.number()
|
|
115
|
+
.optional()
|
|
116
|
+
.describe('Estimated total building damage in USD (may exceed paid amount). Absent when not assessed.'),
|
|
117
|
+
contents_damage_amount: z
|
|
118
|
+
.number()
|
|
119
|
+
.optional()
|
|
120
|
+
.describe('Estimated total contents damage in USD (may exceed paid amount). Absent when not assessed.'),
|
|
121
|
+
rated_flood_zone: z
|
|
122
|
+
.string()
|
|
123
|
+
.optional()
|
|
124
|
+
.describe('FEMA flood zone designation at the property (e.g., AE, X, VE). Absent when not recorded.'),
|
|
125
|
+
cause_of_damage: z
|
|
126
|
+
.string()
|
|
127
|
+
.optional()
|
|
128
|
+
.describe('Primary cause of the flood damage (e.g., "Flooding", "Tidal Overflow"). Absent when not recorded.'),
|
|
129
|
+
occupancy_type: z
|
|
130
|
+
.number()
|
|
131
|
+
.optional()
|
|
132
|
+
.describe('NFIP occupancy type code (e.g., 1=Single Family, 2=2-4 Family, 6=Non-Residential). Absent when not recorded.'),
|
|
133
|
+
})
|
|
134
|
+
.describe('A single NFIP flood insurance claim record.'))
|
|
135
|
+
.describe('Inline preview of claim records (first N rows). Full dataset available via canvas_id when spilled=true.'),
|
|
136
|
+
total_count: z
|
|
137
|
+
.number()
|
|
138
|
+
.describe('Total matching claims in the filtered dataset before the limit.'),
|
|
139
|
+
returned_count: z.number().describe('Number of claim records in the inline preview.'),
|
|
140
|
+
canvas_id: z
|
|
141
|
+
.string()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe('Canvas ID for the staged full result set. Pass to fema_dataframe_query and fema_dataframe_describe. Present when canvas is enabled.'),
|
|
144
|
+
canvas_table: z
|
|
145
|
+
.string()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe('DuckDB table name on the canvas holding all fetched rows. Reference in SQL FROM clauses. Present when spilled=true.'),
|
|
148
|
+
spilled: z
|
|
149
|
+
.boolean()
|
|
150
|
+
.describe('True when the full result set was staged on DataCanvas; use canvas_id + fema_dataframe_query for SQL analysis. False when all results fit inline.'),
|
|
151
|
+
truncated: z
|
|
152
|
+
.boolean()
|
|
153
|
+
.optional()
|
|
154
|
+
.describe('True when the canvas row cap (50,000) was reached before all matching rows were staged. Apply tighter filters (county_code, zip_code, year range) for a complete set.'),
|
|
155
|
+
}),
|
|
156
|
+
enrichment: {
|
|
157
|
+
notice: z.string().optional().describe('Guidance on canvas usage or result scope.'),
|
|
158
|
+
},
|
|
159
|
+
async handler(input, ctx) {
|
|
160
|
+
const filterParts = [`state eq '${escapeODataString(input.state)}'`];
|
|
161
|
+
if (input.county_code?.trim()) {
|
|
162
|
+
filterParts.push(`countyCode eq '${escapeODataString(input.county_code)}'`);
|
|
163
|
+
}
|
|
164
|
+
if (input.zip_code?.trim()) {
|
|
165
|
+
filterParts.push(`reportedZipCode eq '${escapeODataString(input.zip_code)}'`);
|
|
166
|
+
}
|
|
167
|
+
if (input.year_from != null) {
|
|
168
|
+
filterParts.push(`yearOfLoss ge ${input.year_from}`);
|
|
169
|
+
}
|
|
170
|
+
if (input.year_to != null) {
|
|
171
|
+
filterParts.push(`yearOfLoss le ${input.year_to}`);
|
|
172
|
+
}
|
|
173
|
+
const svc = getOpenFemaService();
|
|
174
|
+
const { rows: rawRows, count } = await svc.fetchNfipClaims({
|
|
175
|
+
filter: filterParts.join(' and '),
|
|
176
|
+
orderby: 'dateOfLoss desc',
|
|
177
|
+
top: input.limit,
|
|
178
|
+
}, ctx);
|
|
179
|
+
const rows = rawRows.map((r) => ({
|
|
180
|
+
state: r.state ?? null,
|
|
181
|
+
county_code: r.countyCode ?? null,
|
|
182
|
+
zip_code: r.reportedZipCode ?? null,
|
|
183
|
+
date_of_loss: r.dateOfLoss ?? null,
|
|
184
|
+
year_of_loss: r.yearOfLoss ?? null,
|
|
185
|
+
amount_paid_building: r.amountPaidOnBuildingClaim ?? null,
|
|
186
|
+
amount_paid_contents: r.amountPaidOnContentsClaim ?? null,
|
|
187
|
+
building_damage_amount: r.buildingDamageAmount ?? null,
|
|
188
|
+
contents_damage_amount: r.contentsDamageAmount ?? null,
|
|
189
|
+
rated_flood_zone: r.ratedFloodZone ?? null,
|
|
190
|
+
cause_of_damage: r.causeOfDamage ?? null,
|
|
191
|
+
occupancy_type: r.occupancyType ?? null,
|
|
192
|
+
}));
|
|
193
|
+
/** Convert canvas rows (null fields) to the output schema shape (absent fields). */
|
|
194
|
+
function toOutputRows(canvasRows) {
|
|
195
|
+
return canvasRows.map((r) => ({
|
|
196
|
+
...(r.state != null ? { state: r.state } : {}),
|
|
197
|
+
...(r.county_code != null ? { county_code: r.county_code } : {}),
|
|
198
|
+
...(r.zip_code != null ? { zip_code: r.zip_code } : {}),
|
|
199
|
+
...(r.date_of_loss != null ? { date_of_loss: r.date_of_loss } : {}),
|
|
200
|
+
...(r.year_of_loss != null ? { year_of_loss: r.year_of_loss } : {}),
|
|
201
|
+
...(r.amount_paid_building != null ? { amount_paid_building: r.amount_paid_building } : {}),
|
|
202
|
+
...(r.amount_paid_contents != null ? { amount_paid_contents: r.amount_paid_contents } : {}),
|
|
203
|
+
...(r.building_damage_amount != null
|
|
204
|
+
? { building_damage_amount: r.building_damage_amount }
|
|
205
|
+
: {}),
|
|
206
|
+
...(r.contents_damage_amount != null
|
|
207
|
+
? { contents_damage_amount: r.contents_damage_amount }
|
|
208
|
+
: {}),
|
|
209
|
+
...(r.rated_flood_zone != null ? { rated_flood_zone: r.rated_flood_zone } : {}),
|
|
210
|
+
...(r.cause_of_damage != null ? { cause_of_damage: r.cause_of_damage } : {}),
|
|
211
|
+
...(r.occupancy_type != null ? { occupancy_type: r.occupancy_type } : {}),
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
214
|
+
// Try canvas spillover if available
|
|
215
|
+
const canvas = getCanvas();
|
|
216
|
+
if (canvas) {
|
|
217
|
+
const instance = await canvas.acquire(input.canvas_id, ctx);
|
|
218
|
+
const result = await spillover({
|
|
219
|
+
canvas: instance,
|
|
220
|
+
source: rows,
|
|
221
|
+
schema: NFIP_CANVAS_SCHEMA,
|
|
222
|
+
previewChars: PREVIEW_CHARS,
|
|
223
|
+
caps: { maxRows: MAX_CANVAS_ROWS },
|
|
224
|
+
signal: ctx.signal,
|
|
225
|
+
});
|
|
226
|
+
if (result.spilled) {
|
|
227
|
+
ctx.enrich.notice(`Results staged on canvas table "${result.handle.tableName}". Use fema_dataframe_query with canvas_id "${instance.canvasId}" to run SQL aggregations.`);
|
|
228
|
+
ctx.log.info('NFIP claims spilled to canvas', {
|
|
229
|
+
canvasId: instance.canvasId,
|
|
230
|
+
tableName: result.handle.tableName,
|
|
231
|
+
rowCount: result.handle.rowCount,
|
|
232
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
claims: toOutputRows(result.previewRows),
|
|
235
|
+
total_count: count,
|
|
236
|
+
returned_count: result.previewRows.length,
|
|
237
|
+
canvas_id: instance.canvasId,
|
|
238
|
+
canvas_table: result.handle.tableName,
|
|
239
|
+
spilled: true,
|
|
240
|
+
...(result.truncated ? { truncated: true } : {}),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
// Fits in preview — still surface canvas_id for potential follow-up queries
|
|
244
|
+
ctx.log.info('NFIP claims fit inline', { rowCount: result.previewRows.length, count });
|
|
245
|
+
return {
|
|
246
|
+
claims: toOutputRows(result.previewRows),
|
|
247
|
+
total_count: count,
|
|
248
|
+
returned_count: result.previewRows.length,
|
|
249
|
+
canvas_id: instance.canvasId,
|
|
250
|
+
canvas_table: '',
|
|
251
|
+
spilled: false,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// Canvas disabled — inline only
|
|
255
|
+
ctx.log.info('NFIP claims inline (canvas disabled)', { returned: rows.length, count });
|
|
256
|
+
if (count > rows.length) {
|
|
257
|
+
ctx.enrich.notice(`Showing ${rows.length} of ${count} matching claims. Enable CANVAS_PROVIDER_TYPE=duckdb for full analytical access, or increase limit and use offset for pagination.`);
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
claims: toOutputRows(rows),
|
|
261
|
+
total_count: count,
|
|
262
|
+
returned_count: rows.length,
|
|
263
|
+
spilled: false,
|
|
264
|
+
};
|
|
265
|
+
},
|
|
266
|
+
format: (result) => {
|
|
267
|
+
const lines = [];
|
|
268
|
+
lines.push(`**${result.returned_count} of ${result.total_count} NFIP claims** | Spilled: ${result.spilled}`);
|
|
269
|
+
if (result.spilled && result.canvas_id) {
|
|
270
|
+
lines.push(`**Canvas ID:** ${result.canvas_id} | **Table:** ${result.canvas_table ?? 'unknown'}`);
|
|
271
|
+
lines.push(`Use fema_dataframe_query with this canvas_id for SQL aggregations.\n`);
|
|
272
|
+
}
|
|
273
|
+
if (result.truncated) {
|
|
274
|
+
lines.push(`_Note: canvas row cap hit — result set truncated._\n`);
|
|
275
|
+
}
|
|
276
|
+
for (const c of result.claims) {
|
|
277
|
+
const parts = [];
|
|
278
|
+
if (c.state)
|
|
279
|
+
parts.push(`State: ${c.state}`);
|
|
280
|
+
if (c.county_code)
|
|
281
|
+
parts.push(`County: ${c.county_code}`);
|
|
282
|
+
if (c.zip_code)
|
|
283
|
+
parts.push(`ZIP: ${c.zip_code}`);
|
|
284
|
+
if (c.date_of_loss)
|
|
285
|
+
parts.push(`Loss: ${c.date_of_loss}`);
|
|
286
|
+
if (c.year_of_loss != null)
|
|
287
|
+
parts.push(`Year: ${c.year_of_loss}`);
|
|
288
|
+
if (c.rated_flood_zone)
|
|
289
|
+
parts.push(`Zone: ${c.rated_flood_zone}`);
|
|
290
|
+
if (c.cause_of_damage)
|
|
291
|
+
parts.push(`Cause: ${c.cause_of_damage}`);
|
|
292
|
+
if (c.occupancy_type)
|
|
293
|
+
parts.push(`Occupancy: ${c.occupancy_type}`);
|
|
294
|
+
if (c.amount_paid_building != null)
|
|
295
|
+
parts.push(`Bldg Paid: $${c.amount_paid_building.toLocaleString()}`);
|
|
296
|
+
if (c.amount_paid_contents != null)
|
|
297
|
+
parts.push(`Contents Paid: $${c.amount_paid_contents.toLocaleString()}`);
|
|
298
|
+
if (c.building_damage_amount != null)
|
|
299
|
+
parts.push(`Bldg Damage: $${c.building_damage_amount.toLocaleString()}`);
|
|
300
|
+
if (c.contents_damage_amount != null)
|
|
301
|
+
parts.push(`Contents Damage: $${c.contents_damage_amount.toLocaleString()}`);
|
|
302
|
+
lines.push(parts.join(' | '));
|
|
303
|
+
}
|
|
304
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
//# sourceMappingURL=fema-search-nfip.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fema-search-nfip.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fema-search-nfip.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Canvas accessor module — holds the optional DataCanvas instance
|
|
3
|
+
* initialized from CoreServices in createApp's setup() callback.
|
|
4
|
+
* @module services/canvas/canvas-accessor
|
|
5
|
+
*/
|
|
6
|
+
import type { DataCanvas } from '@cyanheads/mcp-ts-core/canvas';
|
|
7
|
+
export declare const setCanvas: (c: DataCanvas | undefined) => void;
|
|
8
|
+
export declare const getCanvas: () => DataCanvas | undefined;
|
|
9
|
+
//# sourceMappingURL=canvas-accessor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-accessor.d.ts","sourceRoot":"","sources":["../../../src/services/canvas/canvas-accessor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAIhE,eAAO,MAAM,SAAS,GAAI,GAAG,UAAU,GAAG,SAAS,KAAG,IAErD,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,UAAU,GAAG,SAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Canvas accessor module — holds the optional DataCanvas instance
|
|
3
|
+
* initialized from CoreServices in createApp's setup() callback.
|
|
4
|
+
* @module services/canvas/canvas-accessor
|
|
5
|
+
*/
|
|
6
|
+
let _canvas;
|
|
7
|
+
export const setCanvas = (c) => {
|
|
8
|
+
_canvas = c;
|
|
9
|
+
};
|
|
10
|
+
export const getCanvas = () => _canvas;
|
|
11
|
+
//# sourceMappingURL=canvas-accessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-accessor.js","sourceRoot":"","sources":["../../../src/services/canvas/canvas-accessor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,IAAI,OAA+B,CAAC;AAEpC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAyB,EAAQ,EAAE;IAC3D,OAAO,GAAG,CAAC,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,GAA2B,EAAE,CAAC,OAAO,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview OpenFEMA API service — wraps the public OpenFEMA v2 REST API
|
|
3
|
+
* with OData parameter encoding, response parsing, error classification, and retry logic.
|
|
4
|
+
* @module services/openfema/openfema-service
|
|
5
|
+
*/
|
|
6
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import type { AppConfig } from '@cyanheads/mcp-ts-core/config';
|
|
8
|
+
import type { StorageService } from '@cyanheads/mcp-ts-core/storage';
|
|
9
|
+
import type { OpenFemaQueryOptions, RawDisasterDeclaration, RawHousingAssistance, RawNfipClaim, RawPaProject } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Escape a string value for embedding in an OData string literal (single-quoted).
|
|
12
|
+
* OData 3 escapes a literal single quote as two consecutive single quotes ('').
|
|
13
|
+
* Without this, user-supplied strings containing ' can break out of the literal
|
|
14
|
+
* and alter the filter structure.
|
|
15
|
+
*/
|
|
16
|
+
export declare function escapeODataString(value: string): string;
|
|
17
|
+
export declare class OpenFemaService {
|
|
18
|
+
private readonly baseUrl;
|
|
19
|
+
private readonly timeoutMs;
|
|
20
|
+
constructor(_config: AppConfig, _storage: StorageService);
|
|
21
|
+
/**
|
|
22
|
+
* Fetch a page from any OpenFEMA dataset.
|
|
23
|
+
* Returns the data array and total count from the response envelope.
|
|
24
|
+
*/
|
|
25
|
+
fetchDataset<T>(dataset: string, opts: OpenFemaQueryOptions, ctx: Context): Promise<{
|
|
26
|
+
rows: T[];
|
|
27
|
+
count: number;
|
|
28
|
+
}>;
|
|
29
|
+
/** Fetch disaster declaration summaries. */
|
|
30
|
+
fetchDisasters(opts: OpenFemaQueryOptions, ctx: Context): Promise<{
|
|
31
|
+
rows: RawDisasterDeclaration[];
|
|
32
|
+
count: number;
|
|
33
|
+
}>;
|
|
34
|
+
/** Fetch public assistance funded project details. */
|
|
35
|
+
fetchPaProjects(opts: OpenFemaQueryOptions, ctx: Context): Promise<{
|
|
36
|
+
rows: RawPaProject[];
|
|
37
|
+
count: number;
|
|
38
|
+
}>;
|
|
39
|
+
/** Fetch housing assistance — owners or renters. */
|
|
40
|
+
fetchHousingAssistance(dataset: 'HousingAssistanceOwners' | 'HousingAssistanceRenters', opts: OpenFemaQueryOptions, ctx: Context): Promise<{
|
|
41
|
+
rows: RawHousingAssistance[];
|
|
42
|
+
count: number;
|
|
43
|
+
}>;
|
|
44
|
+
/** Fetch NFIP claims. */
|
|
45
|
+
fetchNfipClaims(opts: OpenFemaQueryOptions, ctx: Context): Promise<{
|
|
46
|
+
rows: RawNfipClaim[];
|
|
47
|
+
count: number;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
export declare function initOpenFemaService(config: AppConfig, storage: StorageService): void;
|
|
51
|
+
export declare function getOpenFemaService(): OpenFemaService;
|
|
52
|
+
//# sourceMappingURL=openfema-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openfema-service.d.ts","sourceRoot":"","sources":["../../../src/services/openfema/openfema-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,KAAK,EAGV,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAoBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc;IAMxD;;;OAGG;IACH,YAAY,CAAC,CAAC,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAqGxC,4CAA4C;IAC5C,cAAc,CACZ,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7D,sDAAsD;IACtD,eAAe,CACb,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAInD,oDAAoD;IACpD,sBAAsB,CACpB,OAAO,EAAE,yBAAyB,GAAG,0BAA0B,EAC/D,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAI3D,yBAAyB;IACzB,eAAe,CACb,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAGpD;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAEpF;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview OpenFEMA API service — wraps the public OpenFEMA v2 REST API
|
|
3
|
+
* with OData parameter encoding, response parsing, error classification, and retry logic.
|
|
4
|
+
* @module services/openfema/openfema-service
|
|
5
|
+
*/
|
|
6
|
+
import { invalidParams, notFound, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { withRetry } from '@cyanheads/mcp-ts-core/utils';
|
|
8
|
+
import { getServerConfig } from '../../config/server-config.js';
|
|
9
|
+
/**
|
|
10
|
+
* Escape a string value for embedding in an OData string literal (single-quoted).
|
|
11
|
+
* OData 3 escapes a literal single quote as two consecutive single quotes ('').
|
|
12
|
+
* Without this, user-supplied strings containing ' can break out of the literal
|
|
13
|
+
* and alter the filter structure.
|
|
14
|
+
*/
|
|
15
|
+
export function escapeODataString(value) {
|
|
16
|
+
return value.replace(/'/g, "''");
|
|
17
|
+
}
|
|
18
|
+
/** Build encoded OData query string — uses %24 prefix for $ params (Akamai requirement). */
|
|
19
|
+
function buildODataQuery(opts) {
|
|
20
|
+
const parts = [];
|
|
21
|
+
// Always request inline count so we get real totals
|
|
22
|
+
parts.push('%24inlinecount=allpages');
|
|
23
|
+
if (opts.filter)
|
|
24
|
+
parts.push(`%24filter=${encodeURIComponent(opts.filter)}`);
|
|
25
|
+
if (opts.select)
|
|
26
|
+
parts.push(`%24select=${encodeURIComponent(opts.select)}`);
|
|
27
|
+
if (opts.orderby)
|
|
28
|
+
parts.push(`%24orderby=${encodeURIComponent(opts.orderby)}`);
|
|
29
|
+
if (opts.top !== undefined)
|
|
30
|
+
parts.push(`%24top=${opts.top}`);
|
|
31
|
+
if (opts.skip !== undefined)
|
|
32
|
+
parts.push(`%24skip=${opts.skip}`);
|
|
33
|
+
return parts.join('&');
|
|
34
|
+
}
|
|
35
|
+
/** Detect HTML response (Drupal 404 pages). */
|
|
36
|
+
function isHtmlResponse(text) {
|
|
37
|
+
return /^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text);
|
|
38
|
+
}
|
|
39
|
+
export class OpenFemaService {
|
|
40
|
+
baseUrl;
|
|
41
|
+
timeoutMs;
|
|
42
|
+
constructor(_config, _storage) {
|
|
43
|
+
const srv = getServerConfig();
|
|
44
|
+
this.baseUrl = srv.baseUrl;
|
|
45
|
+
this.timeoutMs = srv.requestTimeoutMs;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Fetch a page from any OpenFEMA dataset.
|
|
49
|
+
* Returns the data array and total count from the response envelope.
|
|
50
|
+
*/
|
|
51
|
+
fetchDataset(dataset, opts, ctx) {
|
|
52
|
+
const qs = buildODataQuery(opts);
|
|
53
|
+
const url = `${this.baseUrl}/${dataset}?${qs}`;
|
|
54
|
+
return withRetry(async () => {
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
57
|
+
// Combine the request abort signal with the timeout signal
|
|
58
|
+
const signal = ctx.signal &&
|
|
59
|
+
typeof AbortSignal.any ===
|
|
60
|
+
'function'
|
|
61
|
+
? AbortSignal.any([
|
|
62
|
+
ctx.signal,
|
|
63
|
+
controller.signal,
|
|
64
|
+
])
|
|
65
|
+
: controller.signal;
|
|
66
|
+
let response;
|
|
67
|
+
try {
|
|
68
|
+
response = await fetch(url, { signal });
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
clearTimeout(timeoutId);
|
|
72
|
+
}
|
|
73
|
+
// HTML content-type = unknown dataset (Drupal 404)
|
|
74
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
75
|
+
if (contentType.includes('text/html') || (!response.ok && contentType.includes('html'))) {
|
|
76
|
+
throw notFound(`Dataset "${dataset}" not found — API returned HTML instead of JSON. Check the dataset name.`, { reason: 'unknown_dataset', dataset });
|
|
77
|
+
}
|
|
78
|
+
const text = await response.text();
|
|
79
|
+
// Body HTML check as fallback (some error pages send application/json content-type)
|
|
80
|
+
if (isHtmlResponse(text)) {
|
|
81
|
+
throw notFound(`Dataset "${dataset}" not found — API returned HTML instead of JSON. Check the dataset name.`, { reason: 'unknown_dataset', dataset });
|
|
82
|
+
}
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
// Parse structured FEMA error response
|
|
85
|
+
try {
|
|
86
|
+
const errBody = JSON.parse(text);
|
|
87
|
+
if (errBody.error?.[0]) {
|
|
88
|
+
const e = errBody.error[0];
|
|
89
|
+
if (response.status === 400) {
|
|
90
|
+
throw invalidParams(`OpenFEMA query error [${e.code}]: ${e.message}`, {
|
|
91
|
+
reason: 'invalid_filter',
|
|
92
|
+
code: e.code,
|
|
93
|
+
name: e.name,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
throw serviceUnavailable(`OpenFEMA API error [${e.code}]: ${e.message}`, {
|
|
97
|
+
status: response.status,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (parseErr) {
|
|
102
|
+
// Re-throw if it's already a classified McpError
|
|
103
|
+
if (parseErr instanceof Error && 'code' in parseErr)
|
|
104
|
+
throw parseErr;
|
|
105
|
+
}
|
|
106
|
+
throw serviceUnavailable(`OpenFEMA API returned HTTP ${response.status} for dataset "${dataset}".`, { status: response.status, url });
|
|
107
|
+
}
|
|
108
|
+
let envelope;
|
|
109
|
+
try {
|
|
110
|
+
envelope = JSON.parse(text);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
throw serviceUnavailable('OpenFEMA returned non-JSON response — possible upstream error.', { url });
|
|
114
|
+
}
|
|
115
|
+
// Data array is keyed by entityName (e.g. "DisasterDeclarationsSummaries")
|
|
116
|
+
const rows = envelope[dataset] ?? [];
|
|
117
|
+
// count is in envelope.metadata.count when $inlinecount=allpages is sent
|
|
118
|
+
const count = typeof envelope.metadata?.count === 'number' ? envelope.metadata.count : rows.length;
|
|
119
|
+
ctx.log.debug('OpenFEMA fetch complete', { dataset, count, rows: rows.length });
|
|
120
|
+
return { rows, count };
|
|
121
|
+
}, {
|
|
122
|
+
operation: `OpenFemaService.fetchDataset(${dataset})`,
|
|
123
|
+
// Context is safe to pass — the retry helper strips non-serializable fields before logging.
|
|
124
|
+
context: ctx,
|
|
125
|
+
baseDelayMs: 1000,
|
|
126
|
+
signal: ctx.signal,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/** Fetch disaster declaration summaries. */
|
|
130
|
+
fetchDisasters(opts, ctx) {
|
|
131
|
+
return this.fetchDataset('DisasterDeclarationsSummaries', opts, ctx);
|
|
132
|
+
}
|
|
133
|
+
/** Fetch public assistance funded project details. */
|
|
134
|
+
fetchPaProjects(opts, ctx) {
|
|
135
|
+
return this.fetchDataset('PublicAssistanceFundedProjectsDetails', opts, ctx);
|
|
136
|
+
}
|
|
137
|
+
/** Fetch housing assistance — owners or renters. */
|
|
138
|
+
fetchHousingAssistance(dataset, opts, ctx) {
|
|
139
|
+
return this.fetchDataset(dataset, opts, ctx);
|
|
140
|
+
}
|
|
141
|
+
/** Fetch NFIP claims. */
|
|
142
|
+
fetchNfipClaims(opts, ctx) {
|
|
143
|
+
return this.fetchDataset('FimaNfipClaims', opts, ctx);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// --- Init/accessor pattern ---
|
|
147
|
+
let _service;
|
|
148
|
+
export function initOpenFemaService(config, storage) {
|
|
149
|
+
_service = new OpenFemaService(config, storage);
|
|
150
|
+
}
|
|
151
|
+
export function getOpenFemaService() {
|
|
152
|
+
if (!_service) {
|
|
153
|
+
throw new Error('OpenFemaService not initialized — call initOpenFemaService() in setup()');
|
|
154
|
+
}
|
|
155
|
+
return _service;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=openfema-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openfema-service.js","sourceRoot":"","sources":["../../../src/services/openfema/openfema-service.ts"],"names":[],"mappings":"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"}
|