EPA MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@EPA MCP ServerFind facilities in Houston, TX"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Tools
9 tools spanning EPA facility compliance, toxic chemical releases, Superfund cleanup sites, drinking water safety, environmental justice screening, and real-time air quality:
Tool | Description |
| Search EPA-regulated facilities by location (ZIP, state, city, or latitude/longitude + radius proximity), industry, or compliance status across all environmental programs (CAA, CWA, RCRA, TRI, SDWA). Returns facility name, EPA Registry ID, coordinates, county FIPS, per-program compliance flags, inspection counts, penalty totals, and TRI release totals. |
| Retrieve a full compliance profile for a single EPA-regulated facility: compliance status per program, inspection dates, formal enforcement actions, penalty amounts, and TRI annual release totals. Aggregates multiple ECHO DFR endpoints in parallel. |
| Search EPA civil and criminal enforcement cases by state, regulatory program, or date range. Returns case identifier, facility name and Registry ID, programs involved, penalty assessed, settlement date, and case type. |
| Get AQI observations or forecasts for a location. Returns per-pollutant AQI values (PM2.5, ozone, CO, SO2, NO2), AQI category (Good through Hazardous), reporting area name, and observation timestamp. |
| Query Toxic Release Inventory annual chemical release data for a specific facility by medium (air, water, land, underground injection) and reporting year. |
| Search Toxic Release Inventory data across facilities in a state or county for a given year. Returns facility name, TRI ID, chemical name, total releases by medium, and facility coordinates. |
| Search Superfund (CERCLA/SEMS) sites by location or NPL listing status. Accepts state/city/ZIP or lat/lng + radius for proximity searches. Returns site name, EPA ID, NPL status, cleanup status, and coordinates. |
| Search drinking water systems (SDWIS) by state or ZIP code. Returns system name, PWSID, population served, primary water source, and active violation status. |
| Get EJScreen environmental-justice indicators for a point + buffer: 13 environmental and 6 demographic indicators with national/state percentiles, EJ Index values, and the demographic indices. Serves EJScreen v2.2 (2022) via the community-maintained EJAM API (Public Environmental Data Partners), which rehosts EJScreen after EPA discontinued public access in 2025. |
epa_search_facilities
Search for EPA-regulated facilities with cross-program compliance data.
Geographic filters: ZIP code, state, city (city requires state), or latitude + longitude + radius_miles for proximity search
Program filter: narrow to CAA, CWA, RCRA, TRI, or SDWA registrants
Compliance filter:
has_violationflag to surface only non-compliant facilitiesReturns
RegistryID(key forepa_get_facility),FacFIPSCode(county FIPS for Census chaining), and coordinatesResults cap enforced — unscoped searches are prohibited at the input validation layer
epa_get_facility
Retrieve a comprehensive compliance profile by EPA Registry ID.
Aggregates 3–5 ECHO DFR endpoints in parallel: program flags and TRI totals, compliance summary, inspection/enforcement history, CAA details (if registered), CWA/NPDES permit details (if registered)
Uses
Promise.allSettled— partial data returned even if one upstream endpoint failsIncludes formal enforcement actions, penalty amounts, and inspection dates across all programs
epa_search_violations
Search area-level EPA enforcement cases — distinct from per-facility history in epa_get_facility.
Program filter: CAA, CWA, RCRA, SDWA, CERCLA, FIFRA, or TSCA
Case type: civil, criminal, or all
Date range filtering by filing date (ISO 8601)
Returns case identifier, affected facility name and Registry ID for downstream
epa_get_facilitylookup
epa_get_air_quality
Get current AQI observations or daily forecasts from AirNow.
Accepts ZIP code or latitude/longitude coordinates
mode: currentreturns the latest observed AQI per pollutant;mode: forecastreturns daily AQI forecasts (requiresforecast_date)AQI categories: Good (1) through Hazardous (6) with numeric and text category
Data is preliminary — suitable for awareness, not regulatory or enforcement decisions
AirNow responses cached at ~1 hour TTL to respect rate limits
epa_get_tri_releases
Query per-chemical release breakdown for a single TRI facility.
Accepts TRI facility ID from
epa_search_facilitiesresultsReturns release quantities by medium: air, water, land, underground injection
Optional year filter (defaults to most recent available); optional chemical name filter
TRI data lags ~18 months — most recent available year is typically 2 years prior to current
epa_search_tri_releases
Identify top polluters in a region via TRI data.
State and optional county scope; required year parameter
Optional chemical name filter to focus on a specific substance
Returns facility coordinates for downstream map or proximity analysis
Complement to
epa_get_tri_releases— use this for area discovery, then drill into a specific facility
epa_search_superfund
Search Superfund (CERCLA/SEMS) sites by location or proximity.
Two input shapes: state/city/ZIP for administrative filters, or lat/lng + radius for proximity
NPL status filter: listed, not-listed, proposed, or all
Returns site cleanup status and coordinates for downstream spatial analysis
epa_search_water_systems
Identify drinking water systems with active or recent violations.
State and optional ZIP code scope
has_violationflag surfaces only systems with current violationsPWS type filter: community (
CWS), non-transient non-community (NTNCWS), or transient non-community (TNCWS)
epa_get_ejscreen
Screen a point and its surrounding buffer for environmental-justice indicators.
Input:
latitude,longitude,distance(default 1), andunit(milesorkilometers); kilometers are converted to miles before the request, and the buffer is capped at 15 milesReturns the 13 EJScreen environmental indicators (PM2.5, ozone, diesel particulate, NO2, lead paint, traffic proximity, Superfund/RMP/hazardous-waste/wastewater proximity, underground storage tanks, drinking-water non-compliance, RSEI toxic air releases) and 6 demographic indicators (people of color, low income, limited English, less than high school, under 5, over 64)
Each indicator carries national and state percentiles plus EJ Index values; the Demographic Index and Supplemental Demographic Index are included
Points outside US coverage return a coverage note instead of fabricated indicators
Data source: EJScreen v2.2 (2022) served via the community-maintained EJAM API (Public Environmental Data Partners), which rehosts EJScreen after EPA discontinued public access in 2025 — not a live EPA endpoint
Related MCP server: mcp-epa-envirofacts
Resources and prompts
Type | Name | Description |
Resource |
| Full compliance profile for a facility by EPA Registry ID (same data as |
Resource |
| Superfund site record by SEMS site ID |
All resource data is also reachable via tools. Use epa_get_facility and epa_search_superfund for programmatic access in tool-only MCP clients.
Features
Built on @cyanheads/mcp-ts-core:
Declarative tool and resource definitions — single file per primitive, framework handles registration and validation
Unified error handling — handlers throw, framework catches, classifies, and formats
Pluggable auth:
none,jwt,oauthSwappable storage backends:
in-memory,filesystem,Supabase,Cloudflare KV/R2/D1Structured logging with optional OpenTelemetry tracing
STDIO and Streamable HTTP transports
EPA-specific:
Multiple environmental data sources unified behind a single
epa_tool surface: ECHO (facility compliance), Envirofacts DMAP (TRI, Superfund, SDWIS), AirNow (real-time air quality), and the community-maintained EJAM API rehosting EJScreen environmental-justice data (v2.2, 2022)Parallel ECHO DFR aggregation in
epa_get_facility— 3–5 upstream calls resolved concurrently withPromise.allSettledAirNow response caching (~1 hour TTL) to stay within per-key rate limits
DMAP coordinate normalization —
tri.tri_facilityDDMMSS integers converted to decimal degrees
Agent-friendly output:
Cross-tool join keys surfaced on every response —
RegistryIDandFacFIPSCodefrom facility search feed directly into compliance, TRI, and Census API workflowsTyped enforcement and compliance status fields — agents branch on data values, not string parsing
Structured partial failure —
epa_get_facilityreturns available program data even when one DFR endpoint is unavailable, with per-section status
Getting started
Add the following to your MCP client configuration file. An AirNow API key is optional — set AIRNOW_API_KEY to enable epa_get_air_quality (register free at docs.airnowapi.org); without it the server starts with the other 8 tools. ECHO, DMAP, and EJScreen tools work without authentication.
{
"mcpServers": {
"epa-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/epa-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"AIRNOW_API_KEY": "your-airnow-key"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"epa-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/epa-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"AIRNOW_API_KEY": "your-airnow-key"
}
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 AIRNOW_API_KEY=... bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.3.0 or higher (or Node.js v24+).
(Optional) An AirNow API key to enable
epa_get_air_quality— register free at docs.airnowapi.org/account/request. Without it the server runs the other 8 tools. ECHO, DMAP, and EJScreen tools require no API key.
Installation
Clone the repository:
git clone https://github.com/cyanheads/epa-mcp-server.gitNavigate into the directory:
cd epa-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# optionally set AIRNOW_API_KEY to enable the air quality toolConfiguration
All configuration is validated at startup via Zod schemas in src/config/. Key environment variables:
Variable | Description | Default |
| Optional. Enables | — |
| ECHO API base URL |
|
| Envirofacts DMAP API base URL |
|
| AirNow API base URL |
|
| Optional. EJScreen (EJAM) API base URL used by |
|
| Transport: |
|
| HTTP server port |
|
| HTTP endpoint path |
|
| Auth mode: |
|
| Log level (RFC 5424) |
|
| Directory for log files (Node.js only) |
|
| Storage backend: |
|
| Enable OpenTelemetry tracing and metrics |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t epa-mcp-server .
docker run --rm -e AIRNOW_API_KEY=your-key -p 3010:3010 epa-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/epa-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| ECHO REST API service layer — facility search, facility detail, enforcement cases. |
| Envirofacts DMAP service layer — TRI releases, Superfund sites, drinking water systems. |
| AirNow service layer — current and forecast AQI observations. |
| EJScreen (EJAM) service layer — environmental-justice indicators for a point + buffer. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools and resources via the barrels in
src/mcp-server/*/definitions/index.tsWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
ECHO searches must enforce at least one geographic parameter — unscoped queries time out against the live API
Contributing
Issues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityAmaintenanceExposes EPA Computational Toxicology (CompTox) evidence federation through MCP, enabling chemical identity, hazard, exposure, and bioactivity data retrieval for AI agents.Last updated6Apache 2.0
- Alicense-qualityCmaintenanceEnables querying US EPA Envirofacts data using natural language, providing access to environmental information through the Pipeworx MCP gateway.Last updated8MIT
- AlicenseAqualityBmaintenanceAn MCP server that exposes EPA ECHO water quality data as tools, enabling facility search, permit limits, discharge measurements, violations, and enforcement actions.Last updated6MIT
- Alicense-qualityCmaintenanceWraps EPA ECHO Web Services (free, no auth) to enable querying environmental data via natural language.Last updated16MIT
Related MCP Connectors
EPA ECHO MCP — wraps EPA ECHO Web Services (free, no auth)
EPA Emissions MCP — wraps EPA Envirofacts REST API (free, no auth)
US EPA Envirofacts MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyanheads/epa-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server