@cyanheads/epa-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/CLAUDE.md +405 -0
- package/Dockerfile +98 -0
- package/README.md +322 -0
- package/changelog/0.1.x/0.1.0.md +22 -0
- package/changelog/0.1.x/0.1.1.md +18 -0
- package/changelog/template.md +119 -0
- package/dist/config/server-config.d.ts +15 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +38 -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 +28 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/facility.resource.d.ts +9 -0
- package/dist/mcp-server/resources/definitions/facility.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/facility.resource.js +24 -0
- package/dist/mcp-server/resources/definitions/facility.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +12 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +10 -0
- package/dist/mcp-server/resources/definitions/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/superfund-site.resource.d.ts +9 -0
- package/dist/mcp-server/resources/definitions/superfund-site.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/superfund-site.resource.js +26 -0
- package/dist/mcp-server/resources/definitions/superfund-site.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-air-quality.tool.d.ts +46 -0
- package/dist/mcp-server/tools/definitions/get-air-quality.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-air-quality.tool.js +193 -0
- package/dist/mcp-server/tools/definitions/get-air-quality.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-facility.tool.d.ts +61 -0
- package/dist/mcp-server/tools/definitions/get-facility.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-facility.tool.js +193 -0
- package/dist/mcp-server/tools/definitions/get-facility.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-tri-releases.tool.d.ts +26 -0
- package/dist/mcp-server/tools/definitions/get-tri-releases.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-tri-releases.tool.js +92 -0
- package/dist/mcp-server/tools/definitions/get-tri-releases.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +305 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +31 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-facilities.tool.d.ts +58 -0
- package/dist/mcp-server/tools/definitions/search-facilities.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-facilities.tool.js +182 -0
- package/dist/mcp-server/tools/definitions/search-facilities.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-superfund.tool.d.ts +49 -0
- package/dist/mcp-server/tools/definitions/search-superfund.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-superfund.tool.js +155 -0
- package/dist/mcp-server/tools/definitions/search-superfund.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-tri-releases.tool.d.ts +29 -0
- package/dist/mcp-server/tools/definitions/search-tri-releases.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-tri-releases.tool.js +113 -0
- package/dist/mcp-server/tools/definitions/search-tri-releases.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-violations.tool.d.ts +48 -0
- package/dist/mcp-server/tools/definitions/search-violations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-violations.tool.js +156 -0
- package/dist/mcp-server/tools/definitions/search-violations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-water-systems.tool.d.ts +38 -0
- package/dist/mcp-server/tools/definitions/search-water-systems.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-water-systems.tool.js +147 -0
- package/dist/mcp-server/tools/definitions/search-water-systems.tool.js.map +1 -0
- package/dist/services/airnow/airnow-service.d.ts +45 -0
- package/dist/services/airnow/airnow-service.d.ts.map +1 -0
- package/dist/services/airnow/airnow-service.js +160 -0
- package/dist/services/airnow/airnow-service.js.map +1 -0
- package/dist/services/airnow/types.d.ts +39 -0
- package/dist/services/airnow/types.d.ts.map +1 -0
- package/dist/services/airnow/types.js +6 -0
- package/dist/services/airnow/types.js.map +1 -0
- package/dist/services/dmap/dmap-service.d.ts +60 -0
- package/dist/services/dmap/dmap-service.d.ts.map +1 -0
- package/dist/services/dmap/dmap-service.js +320 -0
- package/dist/services/dmap/dmap-service.js.map +1 -0
- package/dist/services/dmap/types.d.ts +108 -0
- package/dist/services/dmap/types.d.ts.map +1 -0
- package/dist/services/dmap/types.js +6 -0
- package/dist/services/dmap/types.js.map +1 -0
- package/dist/services/echo/echo-service.d.ts +57 -0
- package/dist/services/echo/echo-service.d.ts.map +1 -0
- package/dist/services/echo/echo-service.js +295 -0
- package/dist/services/echo/echo-service.js.map +1 -0
- package/dist/services/echo/types.d.ts +198 -0
- package/dist/services/echo/types.d.ts.map +1 -0
- package/dist/services/echo/types.js +6 -0
- package/dist/services/echo/types.js.map +1 -0
- package/package.json +80 -0
- package/server.json +111 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching EPA-regulated facilities by location, industry, or compliance status.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-facilities.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getEchoService } from '../../../services/echo/echo-service.js';
|
|
8
|
+
export const searchFacilitiesTool = tool('epa_search_facilities', {
|
|
9
|
+
title: 'Search EPA Facilities',
|
|
10
|
+
description: 'Search EPA-regulated facilities by location, industry program, or compliance status across all environmental programs (CAA, CWA, RCRA, TRI, SDWA). Returns facility name, EPA Registry ID, coordinates, county FIPS code, per-program registration flags, inspection counts, penalty totals, and TRI release totals. Registry IDs returned here feed epa_get_facility and epa_get_tri_releases. At least one geographic filter (zip_code, state, or city+state) is required — unscoped searches time out.',
|
|
11
|
+
annotations: { readOnlyHint: true, openWorldHint: true, idempotentHint: true },
|
|
12
|
+
input: z.object({
|
|
13
|
+
zip_code: z.string().optional().describe('5-digit ZIP code to search within'),
|
|
14
|
+
state: z.string().optional().describe('2-letter US state abbreviation (e.g. "WA", "CA")'),
|
|
15
|
+
city: z.string().optional().describe('City name. Pair with state for best results.'),
|
|
16
|
+
active_only: z.boolean().optional().describe('When true, return only active facilities'),
|
|
17
|
+
programs: z
|
|
18
|
+
.array(z.enum(['CAA', 'CWA', 'RCRA', 'TRI', 'SDWA']))
|
|
19
|
+
.optional()
|
|
20
|
+
.describe('Restrict results to facilities registered in these environmental programs. CAA=air, CWA=water, RCRA=waste, TRI=toxic releases, SDWA=drinking water.'),
|
|
21
|
+
has_violation: z
|
|
22
|
+
.boolean()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('When true, return only facilities with recent significant violations'),
|
|
25
|
+
limit: z
|
|
26
|
+
.number()
|
|
27
|
+
.int()
|
|
28
|
+
.min(1)
|
|
29
|
+
.max(100)
|
|
30
|
+
.default(50)
|
|
31
|
+
.describe('Maximum number of facilities to return (1–100)'),
|
|
32
|
+
}),
|
|
33
|
+
output: z.object({
|
|
34
|
+
facilities: z
|
|
35
|
+
.array(z
|
|
36
|
+
.object({
|
|
37
|
+
registryId: z
|
|
38
|
+
.string()
|
|
39
|
+
.describe('EPA FRS Registry ID — use as input to epa_get_facility and epa_get_tri_releases'),
|
|
40
|
+
name: z.string().describe('Facility name'),
|
|
41
|
+
street: z.string().optional().describe('Street address'),
|
|
42
|
+
city: z.string().optional().describe('City'),
|
|
43
|
+
state: z.string().optional().describe('2-letter state abbreviation'),
|
|
44
|
+
zip: z.string().optional().describe('ZIP code'),
|
|
45
|
+
county: z.string().optional().describe('County name'),
|
|
46
|
+
fipsCode: z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('5-digit county FIPS code — use with Census API for demographics'),
|
|
50
|
+
latitude: z.number().optional().describe('Latitude in decimal degrees'),
|
|
51
|
+
longitude: z.number().optional().describe('Longitude in decimal degrees'),
|
|
52
|
+
complianceStatus: z
|
|
53
|
+
.string()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe('Overall compliance status text from ECHO'),
|
|
56
|
+
programs: z
|
|
57
|
+
.object({
|
|
58
|
+
air: z.boolean().describe('Registered under Clean Air Act (CAA)'),
|
|
59
|
+
water: z.boolean().describe('Registered under Clean Water Act (CWA)'),
|
|
60
|
+
rcra: z
|
|
61
|
+
.boolean()
|
|
62
|
+
.describe('Registered under Resource Conservation and Recovery Act (RCRA)'),
|
|
63
|
+
tri: z.boolean().describe('Participates in Toxic Release Inventory (TRI)'),
|
|
64
|
+
sdwa: z.boolean().describe('Regulated under Safe Drinking Water Act (SDWA)'),
|
|
65
|
+
})
|
|
66
|
+
.describe('Program registration flags'),
|
|
67
|
+
triReleasesTransfersInLbs: z
|
|
68
|
+
.number()
|
|
69
|
+
.optional()
|
|
70
|
+
.describe('Total TRI on/off-site releases and transfers in pounds (summary). Use epa_get_tri_releases for per-chemical breakdown.'),
|
|
71
|
+
inspectionCount: z.number().optional().describe('Number of EPA inspections on record'),
|
|
72
|
+
totalPenaltiesInDollars: z
|
|
73
|
+
.number()
|
|
74
|
+
.optional()
|
|
75
|
+
.describe('Total assessed penalties in dollars across all programs'),
|
|
76
|
+
})
|
|
77
|
+
.describe('EPA facility record with Registry ID, location, program flags, and compliance summary'))
|
|
78
|
+
.describe('Matching EPA facilities'),
|
|
79
|
+
totalCount: z.number().describe('Total facilities matched before the limit was applied'),
|
|
80
|
+
message: z
|
|
81
|
+
.string()
|
|
82
|
+
.optional()
|
|
83
|
+
.describe('Recovery hint when no results are found — echoes applied filters and suggests how to broaden the search. Absent when results are returned.'),
|
|
84
|
+
}),
|
|
85
|
+
errors: [
|
|
86
|
+
{
|
|
87
|
+
reason: 'no_geographic_filter',
|
|
88
|
+
code: JsonRpcErrorCode.InvalidParams,
|
|
89
|
+
when: 'No geographic filter (zip_code, state, or city) was provided.',
|
|
90
|
+
recovery: 'Provide at least one of zip_code, state, or city to scope the search.',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
reason: 'no_match',
|
|
94
|
+
code: JsonRpcErrorCode.NotFound,
|
|
95
|
+
when: 'No facilities matched the search criteria.',
|
|
96
|
+
recovery: 'Broaden the search by removing filters or expanding the geographic area.',
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
async handler(input, ctx) {
|
|
100
|
+
// Enforce geographic scoping requirement
|
|
101
|
+
if (!input.zip_code?.trim() && !input.state?.trim() && !input.city?.trim()) {
|
|
102
|
+
throw ctx.fail('no_geographic_filter', 'At least one geographic filter (zip_code, state, or city) is required.', {
|
|
103
|
+
...ctx.recoveryFor('no_geographic_filter'),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
ctx.log.info('epa_search_facilities', {
|
|
107
|
+
zip: input.zip_code,
|
|
108
|
+
state: input.state,
|
|
109
|
+
city: input.city,
|
|
110
|
+
programs: input.programs,
|
|
111
|
+
});
|
|
112
|
+
const zipCode = input.zip_code?.trim();
|
|
113
|
+
const state = input.state?.trim();
|
|
114
|
+
const city = input.city?.trim();
|
|
115
|
+
const { facilities, totalCount } = await getEchoService().searchFacilities({
|
|
116
|
+
...(zipCode && { zipCode }),
|
|
117
|
+
...(state && { state }),
|
|
118
|
+
...(city && { city }),
|
|
119
|
+
...(input.active_only && { activeOnly: input.active_only }),
|
|
120
|
+
...(input.programs?.length && { programs: input.programs }),
|
|
121
|
+
...(input.has_violation && { hasViolation: input.has_violation }),
|
|
122
|
+
limit: input.limit,
|
|
123
|
+
}, ctx);
|
|
124
|
+
ctx.log.info('epa_search_facilities completed', { count: facilities.length, totalCount });
|
|
125
|
+
if (facilities.length === 0) {
|
|
126
|
+
const parts = [];
|
|
127
|
+
if (input.zip_code)
|
|
128
|
+
parts.push(`zip_code="${input.zip_code}"`);
|
|
129
|
+
if (input.state)
|
|
130
|
+
parts.push(`state="${input.state}"`);
|
|
131
|
+
if (input.city)
|
|
132
|
+
parts.push(`city="${input.city}"`);
|
|
133
|
+
if (input.programs?.length)
|
|
134
|
+
parts.push(`programs=[${input.programs.join(', ')}]`);
|
|
135
|
+
if (input.has_violation)
|
|
136
|
+
parts.push('has_violation=true');
|
|
137
|
+
return {
|
|
138
|
+
facilities: [],
|
|
139
|
+
totalCount: 0,
|
|
140
|
+
message: `No facilities matched: ${parts.join(', ')}. Try broadening the geographic area or removing program/violation filters.`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return { facilities, totalCount };
|
|
144
|
+
},
|
|
145
|
+
format: (result) => {
|
|
146
|
+
const lines = [];
|
|
147
|
+
lines.push(`## EPA Facility Search Results`);
|
|
148
|
+
lines.push(`**Total Found:** ${result.totalCount} | **Returned:** ${result.facilities.length}`);
|
|
149
|
+
if (result.message)
|
|
150
|
+
lines.push(`\n> ${result.message}`);
|
|
151
|
+
for (const f of result.facilities) {
|
|
152
|
+
lines.push(`\n### ${f.name}`);
|
|
153
|
+
lines.push(`**Registry ID:** ${f.registryId}`);
|
|
154
|
+
const location = [f.street, f.city, f.state, f.zip].filter(Boolean).join(', ');
|
|
155
|
+
if (location)
|
|
156
|
+
lines.push(`**Location:** ${location}`);
|
|
157
|
+
if (f.county)
|
|
158
|
+
lines.push(`**County:** ${f.county}${f.fipsCode ? ` (FIPS: ${f.fipsCode})` : ''}`);
|
|
159
|
+
if (f.latitude !== undefined && f.longitude !== undefined) {
|
|
160
|
+
lines.push(`**Coordinates:** ${f.latitude}, ${f.longitude}`);
|
|
161
|
+
}
|
|
162
|
+
if (f.complianceStatus)
|
|
163
|
+
lines.push(`**Compliance Status:** ${f.complianceStatus}`);
|
|
164
|
+
const activePrograms = Object.entries(f.programs)
|
|
165
|
+
.filter(([, v]) => v)
|
|
166
|
+
.map(([k]) => k.toUpperCase())
|
|
167
|
+
.join(', ');
|
|
168
|
+
if (activePrograms)
|
|
169
|
+
lines.push(`**Programs:** ${activePrograms}`);
|
|
170
|
+
if (f.triReleasesTransfersInLbs !== undefined) {
|
|
171
|
+
lines.push(`**TRI Releases+Transfers:** ${f.triReleasesTransfersInLbs.toLocaleString()} lbs`);
|
|
172
|
+
}
|
|
173
|
+
if (f.inspectionCount !== undefined)
|
|
174
|
+
lines.push(`**Inspections:** ${f.inspectionCount}`);
|
|
175
|
+
if (f.totalPenaltiesInDollars !== undefined) {
|
|
176
|
+
lines.push(`**Total Penalties:** $${f.totalPenaltiesInDollars.toLocaleString()}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=search-facilities.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-facilities.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-facilities.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching Superfund (CERCLA/SEMS) sites by location or NPL status.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-superfund.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const searchSuperfundTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
state: z.ZodOptional<z.ZodString>;
|
|
9
|
+
city: z.ZodOptional<z.ZodString>;
|
|
10
|
+
zip_code: z.ZodOptional<z.ZodString>;
|
|
11
|
+
latitude: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
longitude: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
radius_miles: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
npl_status: z.ZodDefault<z.ZodEnum<{
|
|
15
|
+
all: "all";
|
|
16
|
+
listed: "listed";
|
|
17
|
+
"not-listed": "not-listed";
|
|
18
|
+
proposed: "proposed";
|
|
19
|
+
}>>;
|
|
20
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
21
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
22
|
+
sites: z.ZodArray<z.ZodObject<{
|
|
23
|
+
siteId: z.ZodString;
|
|
24
|
+
name: z.ZodString;
|
|
25
|
+
street: z.ZodOptional<z.ZodString>;
|
|
26
|
+
city: z.ZodOptional<z.ZodString>;
|
|
27
|
+
state: z.ZodOptional<z.ZodString>;
|
|
28
|
+
zip: z.ZodOptional<z.ZodString>;
|
|
29
|
+
county: z.ZodOptional<z.ZodString>;
|
|
30
|
+
fipsCode: z.ZodOptional<z.ZodString>;
|
|
31
|
+
nplStatus: z.ZodOptional<z.ZodString>;
|
|
32
|
+
cleanupStatus: z.ZodOptional<z.ZodString>;
|
|
33
|
+
latitude: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
longitude: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
totalCount: z.ZodNumber;
|
|
37
|
+
message: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strip>, readonly [{
|
|
39
|
+
readonly reason: "no_location_filter";
|
|
40
|
+
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
41
|
+
readonly when: "No location filter (state, city, zip_code, or latitude+longitude) was provided.";
|
|
42
|
+
readonly recovery: "Provide at least one location filter: state, city, zip_code, or latitude+longitude+radius_miles.";
|
|
43
|
+
}, {
|
|
44
|
+
readonly reason: "radius_required";
|
|
45
|
+
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
46
|
+
readonly when: "Latitude and longitude were provided without radius_miles.";
|
|
47
|
+
readonly recovery: "Provide radius_miles together with latitude and longitude for a proximity search.";
|
|
48
|
+
}]>;
|
|
49
|
+
//# sourceMappingURL=search-superfund.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-superfund.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-superfund.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+K9B,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching Superfund (CERCLA/SEMS) sites by location or NPL status.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-superfund.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getDmapService } from '../../../services/dmap/dmap-service.js';
|
|
8
|
+
export const searchSuperfundTool = tool('epa_search_superfund', {
|
|
9
|
+
title: 'Search Superfund Sites',
|
|
10
|
+
description: 'Search Superfund (CERCLA/SEMS) sites by location or NPL listing status. Returns site name, EPA site ID, NPL status (listed/not listed/proposed), cleanup status, coordinates, and county FIPS code. Accepts either state/city/ZIP or latitude+longitude+radius for proximity searches. Use for "are there Superfund sites near X" questions.',
|
|
11
|
+
annotations: { readOnlyHint: true, openWorldHint: true, idempotentHint: true },
|
|
12
|
+
input: z.object({
|
|
13
|
+
state: z.string().optional().describe('2-letter US state abbreviation to filter sites'),
|
|
14
|
+
city: z.string().optional().describe('City name (partial match within state)'),
|
|
15
|
+
zip_code: z.string().optional().describe('5-digit ZIP code to filter sites'),
|
|
16
|
+
latitude: z
|
|
17
|
+
.number()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Latitude for proximity search (use with longitude and radius_miles)'),
|
|
20
|
+
longitude: z
|
|
21
|
+
.number()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('Longitude for proximity search (use with latitude and radius_miles)'),
|
|
24
|
+
radius_miles: z
|
|
25
|
+
.number()
|
|
26
|
+
.min(0.1)
|
|
27
|
+
.max(500)
|
|
28
|
+
.optional()
|
|
29
|
+
.describe('Search radius in miles from the given coordinates. Required when using latitude+longitude.'),
|
|
30
|
+
npl_status: z
|
|
31
|
+
.enum(['listed', 'not-listed', 'proposed', 'all'])
|
|
32
|
+
.default('all')
|
|
33
|
+
.describe('Filter by NPL (National Priorities List) status: listed=final NPL, not-listed=not on NPL, proposed=proposed for listing, all=include all'),
|
|
34
|
+
limit: z
|
|
35
|
+
.number()
|
|
36
|
+
.int()
|
|
37
|
+
.min(1)
|
|
38
|
+
.max(200)
|
|
39
|
+
.default(50)
|
|
40
|
+
.describe('Maximum number of sites to return (1–200)'),
|
|
41
|
+
}),
|
|
42
|
+
output: z.object({
|
|
43
|
+
sites: z
|
|
44
|
+
.array(z
|
|
45
|
+
.object({
|
|
46
|
+
siteId: z.string().describe('EPA SEMS site identifier'),
|
|
47
|
+
name: z.string().describe('Superfund site name'),
|
|
48
|
+
street: z.string().optional().describe('Street address'),
|
|
49
|
+
city: z.string().optional().describe('City'),
|
|
50
|
+
state: z.string().optional().describe('2-letter state abbreviation'),
|
|
51
|
+
zip: z.string().optional().describe('ZIP code'),
|
|
52
|
+
county: z.string().optional().describe('County name'),
|
|
53
|
+
fipsCode: z.string().optional().describe('5-digit county FIPS code'),
|
|
54
|
+
nplStatus: z
|
|
55
|
+
.string()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe('NPL status code: NPL=listed, N=not listed, P=proposed'),
|
|
58
|
+
cleanupStatus: z.string().optional().describe('Current cleanup stage or status'),
|
|
59
|
+
latitude: z.number().optional().describe('Latitude in decimal degrees'),
|
|
60
|
+
longitude: z.number().optional().describe('Longitude in decimal degrees'),
|
|
61
|
+
})
|
|
62
|
+
.describe('Superfund site record with location, NPL status, and cleanup status'))
|
|
63
|
+
.describe('Matching Superfund sites'),
|
|
64
|
+
totalCount: z
|
|
65
|
+
.number()
|
|
66
|
+
.describe('Number of sites returned (may be less than available if limit applied)'),
|
|
67
|
+
message: z
|
|
68
|
+
.string()
|
|
69
|
+
.optional()
|
|
70
|
+
.describe('Recovery hint when no sites are found. Absent when sites are returned.'),
|
|
71
|
+
}),
|
|
72
|
+
errors: [
|
|
73
|
+
{
|
|
74
|
+
reason: 'no_location_filter',
|
|
75
|
+
code: JsonRpcErrorCode.InvalidParams,
|
|
76
|
+
when: 'No location filter (state, city, zip_code, or latitude+longitude) was provided.',
|
|
77
|
+
recovery: 'Provide at least one location filter: state, city, zip_code, or latitude+longitude+radius_miles.',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
reason: 'radius_required',
|
|
81
|
+
code: JsonRpcErrorCode.InvalidParams,
|
|
82
|
+
when: 'Latitude and longitude were provided without radius_miles.',
|
|
83
|
+
recovery: 'Provide radius_miles together with latitude and longitude for a proximity search.',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
async handler(input, ctx) {
|
|
87
|
+
const hasGeo = !!input.state?.trim() || !!input.city?.trim() || !!input.zip_code?.trim();
|
|
88
|
+
const hasLatLng = input.latitude !== undefined && input.longitude !== undefined;
|
|
89
|
+
if (!hasGeo && !hasLatLng) {
|
|
90
|
+
throw ctx.fail('no_location_filter', 'At least one location filter is required to search Superfund sites.', {
|
|
91
|
+
...ctx.recoveryFor('no_location_filter'),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (hasLatLng && !input.radius_miles) {
|
|
95
|
+
throw ctx.fail('radius_required', 'Provide radius_miles when using latitude+longitude for proximity search.', {
|
|
96
|
+
...ctx.recoveryFor('radius_required'),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
ctx.log.info('epa_search_superfund', {
|
|
100
|
+
state: input.state,
|
|
101
|
+
lat: input.latitude,
|
|
102
|
+
nplStatus: input.npl_status,
|
|
103
|
+
});
|
|
104
|
+
const state = input.state?.trim();
|
|
105
|
+
const city = input.city?.trim();
|
|
106
|
+
const zipCode = input.zip_code?.trim();
|
|
107
|
+
const sites = await getDmapService().searchSuperfund({
|
|
108
|
+
...(state && { state }),
|
|
109
|
+
...(city && { city }),
|
|
110
|
+
...(zipCode && { zipCode }),
|
|
111
|
+
...(input.latitude !== undefined && { latitude: input.latitude }),
|
|
112
|
+
...(input.longitude !== undefined && { longitude: input.longitude }),
|
|
113
|
+
...(input.radius_miles !== undefined && { radiusMiles: input.radius_miles }),
|
|
114
|
+
...(input.npl_status !== 'all' && { nplStatus: input.npl_status }),
|
|
115
|
+
limit: input.limit,
|
|
116
|
+
}, ctx);
|
|
117
|
+
ctx.log.info('epa_search_superfund completed', { count: sites.length });
|
|
118
|
+
if (sites.length === 0) {
|
|
119
|
+
const location = hasLatLng
|
|
120
|
+
? `lat=${input.latitude}, lng=${input.longitude}, radius=${input.radius_miles} miles`
|
|
121
|
+
: [input.state, input.city, input.zip_code].filter(Boolean).join(', ');
|
|
122
|
+
return {
|
|
123
|
+
sites: [],
|
|
124
|
+
totalCount: 0,
|
|
125
|
+
message: `No Superfund sites found near ${location} with npl_status="${input.npl_status}". Try expanding the area, removing NPL status filter, or using a different location.`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return { sites, totalCount: sites.length };
|
|
129
|
+
},
|
|
130
|
+
format: (result) => {
|
|
131
|
+
const lines = [];
|
|
132
|
+
lines.push(`## Superfund Sites`);
|
|
133
|
+
lines.push(`**Found:** ${result.totalCount}`);
|
|
134
|
+
if (result.message)
|
|
135
|
+
lines.push(`\n> ${result.message}`);
|
|
136
|
+
for (const s of result.sites) {
|
|
137
|
+
lines.push(`\n### ${s.name}`);
|
|
138
|
+
lines.push(`**Site ID:** ${s.siteId}`);
|
|
139
|
+
const location = [s.street, s.city, s.state, s.zip].filter(Boolean).join(', ');
|
|
140
|
+
if (location)
|
|
141
|
+
lines.push(`**Location:** ${location}`);
|
|
142
|
+
if (s.county)
|
|
143
|
+
lines.push(`**County:** ${s.county}${s.fipsCode ? ` (FIPS: ${s.fipsCode})` : ''}`);
|
|
144
|
+
if (s.latitude !== undefined && s.longitude !== undefined) {
|
|
145
|
+
lines.push(`**Coordinates:** ${s.latitude}, ${s.longitude}`);
|
|
146
|
+
}
|
|
147
|
+
if (s.nplStatus)
|
|
148
|
+
lines.push(`**NPL Status:** ${s.nplStatus}`);
|
|
149
|
+
if (s.cleanupStatus)
|
|
150
|
+
lines.push(`**Cleanup Status:** ${s.cleanupStatus}`);
|
|
151
|
+
}
|
|
152
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=search-superfund.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-superfund.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-superfund.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching TRI release data across facilities in a state or county.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-tri-releases.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const searchTriReleasesTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
state: z.ZodString;
|
|
9
|
+
county: z.ZodOptional<z.ZodString>;
|
|
10
|
+
year: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
chemical_name: z.ZodOptional<z.ZodString>;
|
|
12
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
releases: z.ZodArray<z.ZodObject<{
|
|
15
|
+
facilityId: z.ZodString;
|
|
16
|
+
facilityName: z.ZodOptional<z.ZodString>;
|
|
17
|
+
chemicalName: z.ZodString;
|
|
18
|
+
reportingYear: z.ZodNumber;
|
|
19
|
+
totalReleasesInLbs: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
}, z.core.$strip>>;
|
|
21
|
+
state: z.ZodString;
|
|
22
|
+
message: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>, readonly [{
|
|
24
|
+
readonly reason: "no_releases_found";
|
|
25
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
26
|
+
readonly when: "No TRI records found for the given state and filters.";
|
|
27
|
+
readonly recovery: "Verify the state abbreviation is valid. TRI data lags 18 months — try removing the year filter or using an earlier year.";
|
|
28
|
+
}]>;
|
|
29
|
+
//# sourceMappingURL=search-tri-releases.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-tri-releases.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-tri-releases.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;GA6HhC,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching TRI release data across facilities in a state or county.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-tri-releases.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getDmapService } from '../../../services/dmap/dmap-service.js';
|
|
8
|
+
export const searchTriReleasesTool = tool('epa_search_tri_releases', {
|
|
9
|
+
title: 'Search TRI Releases by Region',
|
|
10
|
+
description: 'Search Toxic Release Inventory data across facilities in a state or county for a given reporting year. Returns facility name, TRI ID, chemical name, and release quantity. Use to identify top polluters in an area or build an environmental exposure profile. Use epa_get_tri_releases for detailed release records for a single facility. TRI data lags ~18 months from the current calendar year.',
|
|
11
|
+
annotations: { readOnlyHint: true, openWorldHint: true, idempotentHint: true },
|
|
12
|
+
input: z.object({
|
|
13
|
+
state: z
|
|
14
|
+
.string()
|
|
15
|
+
.min(2)
|
|
16
|
+
.max(2)
|
|
17
|
+
.describe('2-letter US state abbreviation (required, e.g. "WA", "TX")'),
|
|
18
|
+
county: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('County name to narrow results within the state (partial match)'),
|
|
22
|
+
year: z
|
|
23
|
+
.number()
|
|
24
|
+
.int()
|
|
25
|
+
.min(1987)
|
|
26
|
+
.max(2030)
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('Reporting year. Defaults to all available years in the state. TRI data lags ~18 months.'),
|
|
29
|
+
chemical_name: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe('Optional filter to restrict results to a specific chemical (partial match, case-insensitive)'),
|
|
33
|
+
limit: z
|
|
34
|
+
.number()
|
|
35
|
+
.int()
|
|
36
|
+
.min(1)
|
|
37
|
+
.max(200)
|
|
38
|
+
.default(50)
|
|
39
|
+
.describe('Maximum number of release records to return (1–200)'),
|
|
40
|
+
}),
|
|
41
|
+
output: z.object({
|
|
42
|
+
releases: z
|
|
43
|
+
.array(z
|
|
44
|
+
.object({
|
|
45
|
+
facilityId: z.string().describe('TRI facility identifier'),
|
|
46
|
+
facilityName: z.string().optional().describe('Facility name'),
|
|
47
|
+
chemicalName: z.string().describe('Chemical name as reported to TRI'),
|
|
48
|
+
reportingYear: z.number().describe('Year of the TRI submission'),
|
|
49
|
+
totalReleasesInLbs: z
|
|
50
|
+
.number()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe('One-time release quantity in pounds (from tri_reporting_form)'),
|
|
53
|
+
})
|
|
54
|
+
.describe('TRI release record for a facility-chemical-year combination'))
|
|
55
|
+
.describe('TRI release records for facilities in the queried state and filters'),
|
|
56
|
+
state: z.string().describe('State queried'),
|
|
57
|
+
message: z
|
|
58
|
+
.string()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Recovery hint when no releases are found. Absent when releases are returned.'),
|
|
61
|
+
}),
|
|
62
|
+
errors: [
|
|
63
|
+
{
|
|
64
|
+
reason: 'no_releases_found',
|
|
65
|
+
code: JsonRpcErrorCode.NotFound,
|
|
66
|
+
when: 'No TRI records found for the given state and filters.',
|
|
67
|
+
recovery: 'Verify the state abbreviation is valid. TRI data lags 18 months — try removing the year filter or using an earlier year.',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
async handler(input, ctx) {
|
|
71
|
+
ctx.log.info('epa_search_tri_releases', {
|
|
72
|
+
state: input.state,
|
|
73
|
+
year: input.year,
|
|
74
|
+
county: input.county,
|
|
75
|
+
});
|
|
76
|
+
const county = input.county?.trim();
|
|
77
|
+
const chemicalName = input.chemical_name?.trim();
|
|
78
|
+
const releases = await getDmapService().searchTriReleases({
|
|
79
|
+
state: input.state.trim().toUpperCase(),
|
|
80
|
+
...(county && { county }),
|
|
81
|
+
...(input.year !== undefined && { year: input.year }),
|
|
82
|
+
...(chemicalName && { chemicalName }),
|
|
83
|
+
limit: input.limit,
|
|
84
|
+
}, ctx);
|
|
85
|
+
ctx.log.info('epa_search_tri_releases completed', { count: releases.length });
|
|
86
|
+
if (releases.length === 0) {
|
|
87
|
+
const yearNote = input.year ? ` for year ${input.year}` : '';
|
|
88
|
+
const countyNote = input.county ? ` in ${input.county} county` : '';
|
|
89
|
+
const chemNote = input.chemical_name ? ` for chemical "${input.chemical_name}"` : '';
|
|
90
|
+
return {
|
|
91
|
+
releases: [],
|
|
92
|
+
state: input.state,
|
|
93
|
+
message: `No TRI releases found in ${input.state}${countyNote}${yearNote}${chemNote}. TRI data lags ~18 months — try year ${new Date().getFullYear() - 2} or removing filters.`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return { releases, state: input.state };
|
|
97
|
+
},
|
|
98
|
+
format: (result) => {
|
|
99
|
+
const lines = [];
|
|
100
|
+
lines.push(`## TRI Releases — ${result.state}`);
|
|
101
|
+
lines.push(`**Records:** ${result.releases.length}`);
|
|
102
|
+
if (result.message)
|
|
103
|
+
lines.push(`\n> ${result.message}`);
|
|
104
|
+
for (const r of result.releases) {
|
|
105
|
+
const facilityLabel = r.facilityName ? `${r.facilityName} (${r.facilityId})` : r.facilityId;
|
|
106
|
+
lines.push(`\n### ${r.chemicalName} — ${facilityLabel} (${r.reportingYear})`);
|
|
107
|
+
if (r.totalReleasesInLbs !== undefined)
|
|
108
|
+
lines.push(`**Release Quantity:** ${r.totalReleasesInLbs.toLocaleString()} lbs`);
|
|
109
|
+
}
|
|
110
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=search-tri-releases.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-tri-releases.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-tri-releases.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching EPA enforcement cases by location, program, or date range.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-violations.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const searchViolationsTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
state: z.ZodOptional<z.ZodString>;
|
|
9
|
+
zip_code: z.ZodOptional<z.ZodString>;
|
|
10
|
+
program: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
CAA: "CAA";
|
|
12
|
+
CWA: "CWA";
|
|
13
|
+
RCRA: "RCRA";
|
|
14
|
+
SDWA: "SDWA";
|
|
15
|
+
CERCLA: "CERCLA";
|
|
16
|
+
FIFRA: "FIFRA";
|
|
17
|
+
TSCA: "TSCA";
|
|
18
|
+
}>>;
|
|
19
|
+
case_type: z.ZodDefault<z.ZodEnum<{
|
|
20
|
+
all: "all";
|
|
21
|
+
criminal: "criminal";
|
|
22
|
+
civil: "civil";
|
|
23
|
+
}>>;
|
|
24
|
+
date_filed_start: z.ZodOptional<z.ZodString>;
|
|
25
|
+
date_filed_end: z.ZodOptional<z.ZodString>;
|
|
26
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
27
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
28
|
+
cases: z.ZodArray<z.ZodObject<{
|
|
29
|
+
caseId: z.ZodOptional<z.ZodString>;
|
|
30
|
+
caseName: z.ZodOptional<z.ZodString>;
|
|
31
|
+
facilityName: z.ZodOptional<z.ZodString>;
|
|
32
|
+
registryId: z.ZodOptional<z.ZodString>;
|
|
33
|
+
programsViolated: z.ZodOptional<z.ZodString>;
|
|
34
|
+
caseType: z.ZodOptional<z.ZodString>;
|
|
35
|
+
penaltyAssessedInDollars: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
settlementDate: z.ZodOptional<z.ZodString>;
|
|
37
|
+
filedDate: z.ZodOptional<z.ZodString>;
|
|
38
|
+
state: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
totalCount: z.ZodNumber;
|
|
41
|
+
message: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, z.core.$strip>, readonly [{
|
|
43
|
+
readonly reason: "no_geographic_filter";
|
|
44
|
+
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
45
|
+
readonly when: "Neither state nor zip_code was provided.";
|
|
46
|
+
readonly recovery: "Provide at least one of state or zip_code to scope the enforcement case search.";
|
|
47
|
+
}]>;
|
|
48
|
+
//# sourceMappingURL=search-violations.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-violations.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-violations.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmK/B,CAAC"}
|