Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.cyanheads/epa-mcp-server

REMOTE · EPA.CASEYJHAND.COM · 2 COMPONENTS

Search EPA compliance, TRI, Superfund, drinking-water, EJScreen, and AirNow data.

+3 this week 75 Trust /100

Last scanned (55 minutes ago)

Scores higher than 64% of remote servers

Reachable. Last reached 5 Nov 2026.

Category Health and Science

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security83
Transport & Reachability100
Schema Quality & AI Usability74
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 5573 tokens (~464/item across 12 items; 11 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management0
  • Stability check failed: schema churn in the 27 days we've observed: 8 tool removals, 0 breaking changes, 0 auth/transport breaks, 11 additions. See how to fix → Fail
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 11 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 13 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 1 Nov 26 +3
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “epa_echo_search_facilities” rewrote its description, which is the text the model reads security
    • Tool “epa_echo_search_violations” rewrote its description, which is the text the model reads security
    • Tool “epa_ejscreen_get_scores” rewrote its description, which is the text the model reads security
    • Tool “epa_tri_get_facility_releases” rewrote its description, which is the text the model reads security
    • Tool “epa_tri_search_releases” rewrote its description, which is the text the model reads security
    • Tool “epa_water_search_systems” rewrote its description, which is the text the model reads security
    • Tool “epa_echo_get_facility” rewrote its description, which is the text the model reads security
    • Tool “epa_superfund_search_sites” rewrote its description, which is the text the model reads security
    • Schema quality: 355 → 464 ▼ functional
    • Schema quality: 355 → 310 ▲ functional
    • Schema quality: unverified → 100 ▲ functional
    • New resource “epa-guide” functional
    • Server version: 0.7.0 → 0.8.0 functional
    • Server version: 0.6.0 → 0.7.0 functional
    • New tool “epa_echo_get_case” functional
    • New tool “epa_superfund_get_site” functional
    • “epa_echo_get_facility” added an optional parameter “drinking_water_violations_offset” cosmetic
    • “epa_echo_get_facility” added an optional parameter “inspections_limit” cosmetic
    • “epa_echo_get_facility” added an optional parameter “inspections_offset” cosmetic
    • “epa_echo_search_facilities” added an optional parameter “county” cosmetic
    • “epa_echo_search_facilities” added an optional parameter “county_fips” cosmetic
    • “epa_echo_search_facilities” added an optional parameter “facility_name” cosmetic
    • “epa_echo_search_facilities” added an optional parameter “naics” cosmetic
    • “epa_echo_search_facilities” added an optional parameter “offset” cosmetic
    • “epa_echo_search_violations” added an optional parameter “offset” cosmetic
    • “epa_superfund_search_sites” added an optional parameter “offset” cosmetic
    • “epa_tri_get_facility_releases” added an optional parameter “limit” cosmetic
    • “epa_tri_get_facility_releases” added an optional parameter “offset” cosmetic
    • “epa_tri_search_releases” added an optional parameter “offset” cosmetic
    • “epa_water_search_systems” added an optional parameter “active_only” cosmetic
    • “epa_water_search_systems” added an optional parameter “county” cosmetic
    • “epa_water_search_systems” added an optional parameter “offset” cosmetic
    • “epa_echo_get_facility” added an optional parameter “drinking_water_violations_limit” cosmetic
    • “epa_superfund_search_sites” added an optional parameter “exclude_archived” cosmetic
    • “epa_echo_search_facilities” reworded the description of “limit” cosmetic
    • “epa_echo_search_facilities” reworded the description of “state” cosmetic
    • “epa_echo_search_facilities” reworded the description of “zip_code” cosmetic
    • “epa_echo_search_violations” reworded the description of “limit” cosmetic
    • “epa_echo_search_violations” reworded the description of “program” cosmetic
    • “epa_echo_search_violations” reworded the description of “state” cosmetic
    • “epa_echo_search_violations” reworded the description of “zip_code” cosmetic
    • “epa_superfund_search_sites” reworded the description of “limit” cosmetic
    • “epa_superfund_search_sites” reworded the description of “state” cosmetic
    • “epa_superfund_search_sites” reworded the description of “zip_code” cosmetic
    • “epa_tri_get_facility_releases” reworded the description of “year” cosmetic
    • “epa_tri_search_releases” reworded the description of “county” cosmetic
    • “epa_tri_search_releases” reworded the description of “include_release_breakdown” cosmetic
    • “epa_tri_search_releases” reworded the description of “limit” cosmetic
    • “epa_tri_search_releases” reworded the description of “state” cosmetic
    • “epa_tri_search_releases” reworded the description of “year” cosmetic
    • “epa_water_search_systems” reworded the description of “limit” cosmetic
    • “epa_water_search_systems” reworded the description of “has_violation” cosmetic
    • “epa_water_search_systems” reworded the description of “state” cosmetic
    • “epa_water_search_systems” reworded the description of “zip_code” cosmetic
    • “epa_echo_get_facility” reworded the description of “registry_id” cosmetic
    • “epa_airnow_get_conditions” reworded the description of “zip_code” cosmetic
    • “epa_superfund_search_sites” reworded the description of “npl_status” cosmetic
  • 24 Oct 26 −7
    • Stability: 0.47 → fail ▼ security
    • Tool “epa_search_water_systems” was removed ▼ security
    • Tool “epa_search_violations” was removed ▼ security
    • Tool “epa_search_tri_releases” was removed ▼ security
    • Tool “epa_search_facilities” was removed ▼ security
    • Tool “epa_get_tri_releases” was removed ▼ security
    • Tool “epa_get_facility” was removed ▼ security
    • Tool “epa_get_ejscreen” was removed ▼ security
    • Tool “epa_get_air_quality” was removed ▼ security
    • Tool “epa_search_superfund” was removed ▼ security
    • The server rewrote its instructions, which are the text every model session reads security
    • Server version: 0.5.0 → 0.6.0 functional
    • New tool “epa_airnow_get_conditions” functional
    • New tool “epa_water_search_systems” functional
    • New tool “epa_tri_search_releases” functional
    • New tool “epa_tri_get_facility_releases” functional
    • New tool “epa_superfund_search_sites” functional
    • New tool “epa_ejscreen_get_scores” functional
    • New tool “epa_echo_search_violations” functional
    • New tool “epa_echo_search_facilities” functional
    • New tool “epa_echo_get_facility” functional
  • 23 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

  • 20 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

  • 19 Oct 26 0
    • Server version: 0.4.1 → 0.5.0 functional
    • “epa_get_tri_releases” reworded the description of “year” cosmetic
  • 18 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

  • 17 Oct 26 +52
    • Injection markers: unverified → pass ▲ security
    • Authorization: unverified → partial ▲ security
    • HSTS header: fail → pass ▲ security
    • Transport: fail → pass ▲ security
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “epa_search_tri_releases” rewrote its description, which is the text the model reads security
    • Tool “epa_search_violations” rewrote its description, which is the text the model reads security
    • Tool “epa_get_facility” rewrote its description, which is the text the model reads security
    • Tool “epa_get_tri_releases” rewrote its description, which is the text the model reads security
    • Tool “epa_search_facilities” rewrote its description, which is the text the model reads security
    • Schema quality: 306 → 343 ▼ functional
    • Endpoint reachability: not serving MCP → reachable ▲ functional
    • Stability: unverified → 0.27 ▲ functional
    • Tool coverage: unverified → 100 ▲ functional
    • MCP protocol: unverified → pass ▲ functional
    • Server version: 0.4.0 → 0.4.1 functional
    • “epa_search_facilities” reworded the description of “active_only” cosmetic
    • “epa_search_facilities” reworded the description of “city” cosmetic
    • “epa_search_facilities” reworded the description of “has_violation” cosmetic
    • “epa_search_facilities” reworded the description of “programs” cosmetic
    • “epa_search_superfund” reworded the description of “city” cosmetic
    • “epa_search_tri_releases” reworded the description of “chemical_name” cosmetic
    • “epa_search_tri_releases” reworded the description of “county” cosmetic
    • “epa_search_tri_releases” reworded the description of “year” cosmetic
    • “epa_search_violations” reworded the description of “case_type” cosmetic
    • “epa_search_violations” reworded the description of “date_filed_end” cosmetic
    • “epa_search_violations” reworded the description of “date_filed_start” cosmetic
    • “epa_search_violations” reworded the description of “program” cosmetic
    • “epa_search_violations” reworded the description of “zip_code” cosmetic
    • “epa_get_tri_releases” reworded the description of “chemical_name” cosmetic
    • “epa_get_tri_releases” reworded the description of “facility_id” cosmetic
  • 16 Oct 26 −51
    • Endpoint reachability: reachable → not serving MCP ▼ security
    • Authorization: partial → unverified ▼ security
    • Tool safety: pass → unverified ▼ security
    • Stability: 0.20 → unverified ▼ security
    • Transport: pass → fail ▼ security
    • HSTS header: pass → fail ▼ security
    • Capabilities: pass → unverified ▼ functional
    • Tool coverage: 100 → unverified ▼ functional
    • First check of Schema quality: unverified functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Probed https://epa.caseyjhand.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=caseyjhand.com CN=WE1,O=Google Trust Services,C=US 2 Nov 2026 31 Jan 2027 ECDSA 256 ECDSA-SHA256 995a30681ab772540e934241ca1d576c
SANs: caseyjhand.com, *.caseyjhand.com
CN=WE1,O=Google Trust Services,C=US (CA) CN=GTS Root R4,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 ECDSA 256 ECDSA-SHA384 7ff31977972c224a76155d13b6d685e3
CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 15 Nov 2023 28 Jan 2028 ECDSA 384 SHA256-RSA 7fe530bf331343bedd821610493d8a1b

Background: What to check on a remote MCP endpoint →

DNSSEC secure

Validation of epa.caseyjhand.com. — Secure

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
com. present 19718 13 Verified
caseyjhand.com. present 2371 13 Verified
epa.caseyjhand.com. Verified address RRset verified with the apex keys
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
strict-transport-security max-age=63072000; includeSubDomains; preload
x-content-type-options nosniff

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://epa.caseyjhand.com/mcp Verified 200
http (plaintext) http://epa.caseyjhand.com/mcp HTTPS enforced 301 https://epa.caseyjhand.com/mcp
MCP tools · 11 exposed · ~5,262 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
epa_airnow_get_conditions ~371

AirNow: Get current AQI observations or the issued AQI forecast for a US location from the AirNow API. Provide either zip_code or both latitude and longitude. Current mode returns the latest hourly NowCast AQI for each pollutant (PM2.5, ozone, PM10) from the closest monitor within 50 miles, with the monitor site name, site ID, and reporting agency; pollutants in one reporting area can come from different monitors. Forecast mode returns every day the reporting area's agency has issued (typically one to five), each with the AQI category, an action-day flag, and the issue date, plus the agency's forecast discussion when one exists; some agencies forecast a category without an AQI number. In forecast mode, set forecast_date to keep only the forecast valid on that date; current mode rejects it. Data are preliminary — suitable for awareness, not regulatory, trend, or enforcement decisions. Responses are cached for ~1 hour.

NameTypeReqDescription
forecast_datestring–Forecast mode only (rejected in current mode): keep just the forecast valid on this date (YYYY-MM-DD). Omit to get every issued forecast day. When no issued day matches, the result is empty and its m…
latitudenumber–Latitude in decimal degrees (use with longitude instead of zip_code)
longitudenumber–Longitude in decimal degrees (use with latitude instead of zip_code)
modestring–Data mode: "current" for the latest hourly observations, "forecast" for every forecast day the reporting area has issued
zip_codestring–US ZIP code for the location: 5 digits, or a ZIP+4 such as 98108-1234, which searches its first five digits
NameTypeReqDescription
attributionstring–Credit to the reporting or forecasting agencies and the U.S. EPA AirNow program, with the preliminary-data notice. Reproduce it when passing this data on.
errorobject–Present when the call failed. Absent on success.
messagestring–Why the result is empty: AirNow's own explanation, the issued forecast dates when forecast_date matched none, or a coverage hint. Absent when data is returned.
modestring–Data mode used: "current" or "forecast"
observationsarray–AQI observation or forecast records grouped by reporting area

No examples provided.

epa_echo_get_case ~294

ECHO: Retrieve one civil enforcement case by case number, with the facilities, defendants, and settlements behind it. Returns the case's category, enforcement type, status, lead agency, relief sought, outcome, court and DOJ docket numbers, summary, and penalty, cost-recovery, compliance-action, and SEP totals; the laws and sections cited; the facilities the case names, one per EPA Registry ID, with address, NAICS and SIC codes, and the program IDs the case links (pass a registryId to epa_echo_get_facility for its compliance profile); defendants; pollutants; milestones; and every enforcement conclusion (order, consent decree, or other settlement) with its facilities, dates, penalties and costs, complying actions, pollutant reductions, and Supplemental Environmental Projects. Take the case number from epa_echo_search_violations or from a formal action's caseId in epa_echo_get_facility. Civil cases only: a criminal CR_ case number fails before any request.

NameTypeReqDescription
case_idstringyesCivil enforcement case number: a caseId from epa_echo_search_violations (e.g. "03-2014-7010", "WA-100446") or a formal action's caseId from epa_echo_get_facility (e.g. "WAPSCAF000000000000000416"). C…
NameTypeReqDescription
caseCategoryCodestring–Case category code: "JDC" civil judicial, "AFR" administrative formal
caseIdstring–Case number, as ECHO records it
caseNamestring–Case name; absent when ECHO records none
caseStatusstring–Case status, e.g. "Final Order Entered", "Resolved", "Closed"
caseStatusDatestring–Date caseStatus took effect (MM/DD/YYYY)
complianceActionCostInDollarsnumber–Estimated cost of the injunctive relief and other actions required to return to compliance, in dollars
costRecoveryInDollarsnumber–Response costs the parties agreed or were ordered to repay, in dollars — the outcome of a CERCLA cost-recovery case
courtDocketNumberstring–The court's or region's docket number, e.g. "18-195"
defendantsarray–Defendants the case names; empty when ECHO records none, as on many state cases
dojDocketNumberstring–Department of Justice docket number, e.g. "90-11-3-06663/2"
enforcementConclusionsarray–Enforcement conclusions in ECHO's order; fields ECHO leaves empty are absent
enforcementOutcomestring–How the case was resolved, e.g. "Final Order No Penalty"
enforcementTypestring–Kind of enforcement action, e.g. "Administrative Order", "Bankruptcy", "CERCLA 120E Federal Facility Agreement (FFA)"
errorobject–Present when the call failed. Absent on success.
facilitiesarray–Facilities the case names, one per Registry ID in ECHO's order; a case can span several states
lawsAndSectionsarray–Statutes and sections the case cites
leadAgencystring–Agency leading the case: "EPA" or "State"
milestonesarray–Case milestones in ECHO's order
penaltyAssessedInDollarsnumber–Federal penalty assessed across the case, in dollars
penaltyCollectedInDollarsnumber–Penalty ECHO records as collected, in dollars
pollutantsarray–Pollutants the case concerns
reliefSoughtstring–Relief the case seeks, e.g. "Cost Recovery"; absent when ECHO records none
stateLocalPenaltyInDollarsnumber–State or local penalty assessed across the case, in dollars
summarystring–Case summary as EPA wrote it
supplementalProjectCostInDollarsnumber–Cost of the Supplemental Environmental Projects agreed, in dollars
violationsstring–Violation description ECHO records, e.g. "Oil Spill Violation Under CWA/OPA"

No examples provided.

epa_echo_get_facility ~503

ECHO: Retrieve a full compliance profile for a single EPA-regulated facility by EPA Registry ID or EPA program ID. Returns facility metadata, the NAICS industry codes its programs record, ECHO's facility-level compliance status, a per-statute (CAA, CWA, RCRA, SDWA, and others ECHO tracks) compliance summary, inspections and other compliance monitoring records from the last five years (newest first, paged), five years of formal enforcement actions with penalties, five years of drinking-water violations with contaminant, measure, MCL, status, and enforcement actions (paged), the latest TRI release total, and the facility's TRI facility IDs for epa_tri_get_facility_releases. Use epa_echo_search_facilities to discover Registry IDs; pass a public water system's PWSID from epa_water_search_systems to get its drinking-water violations. For area-level enforcement discovery use epa_echo_search_violations instead.

NameTypeReqDescription
drinking_water_violations_limitinteger–Maximum number of drinking-water violations to return in one call (1–200, default 50). A larger value, up to 5,000, returns 200 with a notice. Page past it with drinking_water_violations_offset and d…
drinking_water_violations_offsetinteger–Number of drinking-water violations to skip before this page (default 0). Pass the previous call's drinkingWaterViolationsNextOffset to continue; a value past the end returns an empty page.
inspections_limitinteger–Maximum number of inspections to return in one call (1–100, default 100). A larger value, up to 5,000, returns 100 with a notice. Page past it with inspections_offset and inspectionsNextOffset.
inspections_offsetinteger–Number of inspections to skip before this page (default 0). Pass the previous call's inspectionsNextOffset to continue; a value past the end returns an empty page.
registry_idstringyesEPA FRS Registry ID for the facility (from epa_echo_search_facilities), or an EPA program ID ECHO resolves to one: a public water system PWSID (from epa_water_search_systems, e.g. WA5300484), a TRI f…
NameTypeReqDescription
airComplianceobject–Clean Air Act status. Present only when programs.air is true and ECHO reports a CAA status.
citystring–City
complianceobject–Facility-level noncompliance count from ECHO's facility search record. Absent when ECHO reports none or the facility search request fails.
complianceStatusstring–ECHO's facility-level compliance status, the same value epa_echo_search_facilities returns (e.g. "Significant Violation"). Absent when ECHO assigns none, as for TRI-only facilities, or when ECHO's fa…
countystring–County name
drinkingWaterViolationsarray–Drinking-water (SDWIS) violations in ECHO's 5-year report for a public water system, newest compliance period first: one page of drinking_water_violations_limit entries from drinking_water_violations…
drinkingWaterViolationsNextOffsetnumber–Offset of the next page of drinkingWaterViolations: present exactly when more follow, absent on the last page. Pass it as drinking_water_violations_offset.
drinkingWaterViolationsTotalnumber–Drinking-water violations in ECHO's report for this facility, across every page; 0 when it has no SDWIS record
errorobject–Present when the call failed. Absent on success.
fipsCodestring–5-digit county FIPS code
formalActionsarray–Formal enforcement actions over the 5-year window, newest first
inspectionsarray–Inspections, evaluations, investigations, and other compliance monitoring records over the 5-year window, newest first: one page of inspections_limit entries from inspections_offset.
inspectionsNextOffsetnumber–Offset of the next page of inspections: present exactly when more follow, absent on the last page. Pass it as inspections_offset.
inspectionsTotalnumber–Compliance monitoring records in ECHO's 5-year history for this facility, across every page
latitudenumber–Latitude in decimal degrees
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
longitudenumber–Longitude in decimal degrees
naicsarray–NAICS industry codes the facility's program records carry, each code once, ascending by code. Programs can record different codes for one site. Empty when no program records one.
namestring–Facility name
noticestring–Present when ECHO's facility search request failed, so complianceStatus and compliance are missing; every other field comes from the facility's detailed report.
programCompliancearray–ECHO's per-statute enforcement and compliance summary. Empty when the facility is in no compliance-tracked program, as for TRI-only facilities.
programsobject–Program registration flags, from the ECHO systems in the facility's detailed report
registryIdstring–EPA FRS Registry ID
statestring–2-letter state abbreviation
streetstring–Street address
triFacilityIdsarray–15-character TRI facility IDs recorded for this facility, most recently reported first — pass one as facility_id to epa_tri_get_facility_releases for per-chemical releases. A site can carry several f…
triReleasesTransfersInLbsnumber–Total TRI on- and off-site releases and transfers in pounds for triReleasesTransfersYear, ECHO's latest TRI year for this facility. Absent when ECHO holds no TRI history for it.
triReleasesTransfersYearnumber–TRI reporting year triReleasesTransfersInLbs covers
truncatedboolean–True when a list was cut at its limit: more drinking-water violations or inspections follow this page, and drinkingWaterViolationsNextOffset or inspectionsNextOffset continues it. Absent when neither…
waterComplianceobject–Clean Water Act status. Present only when programs.water is true and ECHO reports a CWA status.
zipstring–ZIP code

No examples provided.

epa_echo_search_facilities ~872

ECHO: Search EPA-regulated facilities by location, county, facility name, NAICS industry code, environmental program, or compliance status across CAA, CWA, RCRA, TRI, and SDWA. Returns facility name, EPA Registry ID, coordinates, county FIPS code, per-program registration flags, TRI facility IDs, five-year inspection and penalty totals, and TRI release totals. Registry IDs returned here feed epa_echo_get_facility; TRI facility IDs feed epa_tri_get_facility_releases. Supports proximity search via latitude + longitude + radius_miles. At least one geographic filter (zip_code, state, city, county_fips, or a complete latitude+longitude+radius_miles triple) is required — unscoped searches time out. Page past limit with offset and nextOffset.

NameTypeReqDescription
active_onlyboolean–When true, return only facilities with an active permit
citystring–City name, case-insensitive; matches cities that begin with it ("TACOMA", or "SEAT" for SEATTLE and SEATAC). Pair with state.
countystring–County name, case-insensitive. A trailing County, Parish, Borough, City and Borough, Census Area, or Municipality is dropped ("King County" searches KING), then it matches recorded county names that…
county_fipsstring–5-digit county FIPS code, state + county (e.g. "53033" for King County, WA); matches it exactly and scopes a search on its own. Leaves out registrations with no program record, which county includes.
facility_namestring–Facility name words, case-insensitive: every word must appear as a whole word, in any order, in a name ECHO records for the facility, so "BOEING" matches BOEING PLANT 2 and "OEING" matches nothing. A…
has_violationboolean–When true, return only facilities with at least one program in significant noncompliance (complianceStatus "Significant Violation")
latitudenumber–Latitude in decimal degrees. Pair with longitude and radius_miles for proximity search.
limitinteger–Maximum number of facilities to return in one call (1–100, default 50). A larger value, up to 5,000, returns 100 with a notice. Page past it with offset and nextOffset.
longitudenumber–Longitude in decimal degrees. Pair with latitude and radius_miles for proximity search.
naicsstring–NAICS industry code, 2–6 digits; fewer than six match every code that begins with them ("3364" for aerospace product and parts manufacturing). Pair with a geographic filter.
offsetinteger–Number of facilities to skip before this page (default 0). Pass the previous call's nextOffset to continue; a value past the end returns an empty page.
programsarray–Restrict results to facilities registered in one environmental program — ECHO filters on a single program per search, so pass one value. CAA=air, CWA=water, RCRA=hazardous waste, TRI=toxic releases,…
radius_milesnumber–Search radius in miles around the given latitude/longitude (max 100). Requires latitude and longitude.
statestring–2-letter state or territory code (e.g. "WA", "PR"), case-insensitive. Required with county. ECHO also files facilities under codes outside the USPS set, such as DM for offshore Gulf of Mexico platfor…
zip_codestring–5-digit ZIP code to search within; a ZIP+4 such as "98108-1234" searches its first five digits
NameTypeReqDescription
effectiveQuerystring–The search as the server sent it upstream, in this tool's input names: normalized values, how each text filter matched ("=" exact, "contains", "begins with", "has words"), and defaults that change wh…
errorobject–Present when the call failed. Absent on success.
facilitiesarray–One page of matching EPA facilities, in ECHO's order: limit facilities from offset
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
messagestring–Recovery hint when the page is empty: no facility matched, or offset is past the last match. Absent when facilities are returned.
nextOffsetnumber–Offset of the next page: present exactly when more records follow, absent on the last page. Pass it as offset to continue.
noticestring–Present when more facilities follow: names the offset that continues the list.
totalCountnumber–Facilities matched before limit and offset were applied

No examples provided.

epa_echo_search_violations ~566

ECHO: Search EPA civil and criminal enforcement cases by state, ZIP code, regulatory program, case type, or filing-date range. Returns case identifier, case type and status, lead agency (EPA or state), primary law and section, enforcement outcome, federal and state penalties, cost recovery, compliance action and SEP costs, and filing, settlement, and closing dates. Case rows name no facility: pass a civil caseId to epa_echo_get_case for the facilities, defendants, and settlements behind it. Designed for area-level violation discovery — for a single known facility's enforcement history use epa_echo_get_facility instead. At least one of state or zip_code is required. Page past limit with offset and nextOffset.

NameTypeReqDescription
case_typestring–Filter by case type: civil (regulatory violations), criminal (willful violations), or all. A filing-date range covers civil cases only: with a date, all returns civil cases and criminal is rejected.
date_filed_end––Latest filing date, inclusive (YYYY-MM-DD). Civil cases only. Omit, or pass "", for no upper bound.
date_filed_start––Earliest filing date, inclusive (YYYY-MM-DD). Civil cases only. Omit, or pass "", for no lower bound.
limitinteger–Maximum number of cases to return in one call (1–100, default 50). A larger value, up to 5,000, returns 100 with a notice. Page past it with offset and nextOffset.
offsetinteger–Number of cases to skip before this page (default 0). Pass the previous call's nextOffset to continue; a value past the end returns an empty page.
programstring–Filter by regulatory program: CAA=Clean Air Act, CWA=Clean Water Act, RCRA=hazardous waste, SDWA=drinking water, CERCLA=Superfund, EPCRA=emergency planning and community right-to-know (the statute be…
statestring–2-letter state or territory code where the case is located (e.g. "TX", "PR"), case-insensitive. A case spanning several states matches each of them. ECHO also files some cases under codes outside the…
zip_codestring–5-digit ZIP code of the case's facility location; a ZIP+4 such as "98108-1234" searches its first five digits
NameTypeReqDescription
casesarray–One page of matching enforcement cases, in ECHO's order: limit cases from offset
effectiveQuerystring–The search as the server sent it upstream, in this tool's input names: normalized values, how each text filter matched ("=" exact, "contains", "begins with", "has words"), and defaults that change wh…
errorobject–Present when the call failed. Absent on success.
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
messagestring–Recovery hint when the page is empty: no case matched, or offset is past the last match. Absent when cases are returned.
nextOffsetnumber–Offset of the next page: present exactly when more records follow, absent on the last page. Pass it as offset to continue.
noticestring–Present when a filing-date range with case_type "all" left criminal cases out of the results, or when more cases follow (names the offset that continues the list).
totalCountnumber–Cases matched before limit and offset were applied

No examples provided.

epa_ejscreen_get_scores ~364

EJScreen: Get EJScreen environmental-justice indicators for a point and surrounding buffer. Returns 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, and RSEI toxic air releases) and 6 demographic indicators (people of color, low income, limited English, less than high school, under 5, over 64), each with national and state percentiles plus EJ Index values, along with the Demographic Index and Supplemental Demographic Index and their national averages. Data is EJAM's ACS 2018–2022 release of EJScreen (EJScreen 2.3 method), served via the community-maintained EJAM API (api.ejanalysis.com, Public Environmental Data Partners), which rehosts EJScreen after EPA discontinued public access in 2025 — not a live EPA endpoint. Provide latitude, longitude, and a buffer distance (default 1 mile, max 15 miles). When EJScreen has no indicators — the point is outside its US bounds, the buffer holds no Census block, or its blocks have no residents — coverage.valid is false and coverage.note says which, and whether a larger distance may help.

NameTypeReqDescription
distancenumber–Buffer radius around the point, in the given unit (default 1). The miles-equivalent must be 15 or less.
latitudenumberyesLatitude in decimal degrees.
longitudenumberyesLongitude in decimal degrees.
unitstring–Unit for distance. Kilometers are converted to miles (× 0.621371) before the request.
NameTypeReqDescription
coverageobject–Whether EJScreen data was available for the buffer.
dataSourcestring–Provenance and vintage of the data.
demographicarray–EJScreen demographic indicators present for the area. Empty when coverage.valid is false.
demographicIndexobject–EJScreen Demographic Index. Absent when coverage.valid is false.
environmentalarray–EJScreen environmental indicators present for the area. Empty when coverage.valid is false.
errorobject–Present when the call failed. Absent on success.
locationobject–The queried location and buffer context.
noticestring–The coverage note, repeated as guidance, when no indicators were returned.
reportUrlstring–Link (absolute URL) to the full EJScreen report for this point and buffer.
supplementalDemographicIndexobject–EJScreen Supplemental Demographic Index. Absent when coverage.valid is false.

No examples provided.

epa_superfund_get_site ~123

Superfund: Retrieve a site by exact SEMS site ID from epa_superfund_search_sites, with all recorded contaminant associations and their media, operable units, and EPA actions. Repeated chemicals in different contexts and duplicate source rows are retained. An existing site without contaminant records returns an empty array. Associations do not establish current exposure, concentrations, or current risk. Site and contaminant requests share a 50-second deadline.

NameTypeReqDescription
site_idstringyesSEMS siteId from epa_superfund_search_sites; preserve leading zeros
NameTypeReqDescription
contaminantsarray–Every SEMS contaminant association for the site; empty when none are recorded
errorobject–Present when the call failed. Absent on success.
siteobject–Superfund site record with source status and assessment metadata

No examples provided.

epa_superfund_search_sites ~479

Superfund: Search Superfund (CERCLA/SEMS) sites by location or NPL listing status. Returns site identifiers, source NPL status labels, non-NPL assessment and archive metadata when available, coordinates, and county FIPS code. Accepts either state/city/ZIP, returned in SEMS site ID order, or latitude+longitude+radius for proximity searches, ordered nearest first; page through a large match with offset and nextOffset. Proximity searches match only sites with usable coordinates and share a 50-second deadline; narrow the radius or add filters if the search times out. Use epa_superfund_get_site with a returned siteId for contaminant associations.

NameTypeReqDescription
citystring–City name (partial match within state, case-insensitive). Punctuation is matched as written ("St. Louis", "Coeur d'Alene").
exclude_archivedboolean–Exclude archived sites by requiring SEMS archived_ind=N; false retains all archive statuses
latitudenumber–Latitude for proximity search (use with longitude and radius_miles)
limitinteger–Maximum number of sites to return in one call (1–200, default 50). A larger value, up to 5,000, returns 200 with a notice. Page past it with offset and nextOffset.
longitudenumber–Longitude for proximity search (use with latitude and radius_miles)
npl_statusstring–Filter by NPL status: listed=final or part of an NPL site (F,A), not-listed=N, proposed=P, deleted=D, removed=R, withdrawn=W, all=include all
offsetinteger–Number of sites to skip before this page (default 0). Pass the previous call's nextOffset to continue; a value past the end returns an empty page.
radius_milesnumber–Search radius in miles from the given coordinates. Required when using latitude+longitude.
statestring–2-letter US state or territory code to filter sites, e.g. "WA"
zip_codestring–5-digit ZIP code to filter sites; a ZIP+4 searches its 5-digit ZIP. Matches sites recorded under the ZIP or any ZIP+4 within it.
NameTypeReqDescription
effectiveQuerystring–The search as the server sent it upstream, in this tool's input names: normalized values, how each text filter matched ("=" exact, "contains", "begins with", "has words"), and defaults that change wh…
errorobject–Present when the call failed. Absent on success.
guidancestring–Present when more sites follow: the offset that continues the search.
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
messagestring–Recovery hint when no sites are found. Absent when sites are returned.
nextOffsetnumber–Offset of the next page: present exactly when more records follow, absent on the last page. Pass it as offset to continue.
noticestring–Proximity coordinate-coverage limitation, with the page's place in the nearest-first match when the page does not hold every match; also present when a non-proximity punctuated city filter reaches it…
sitesarray–Matching Superfund sites
totalCountnumber–Superfund sites matched before limit and offset. Present for a proximity search, which ranks every match; absent for a state, city, or ZIP search, whose match count EPA's DMAP service does not report…

No examples provided.

epa_tri_get_facility_releases ~458

TRI: Query Toxic Release Inventory annual chemical release data for a specific facility. Returns per-chemical release records with chemical name, reporting year, on-site releases by medium (air, water, land, underground injection) and their total, and the Form R one-time release quantity, newest reporting year first; page past 500 filings with offset and nextOffset. Quantities are in pounds; dioxin and dioxin-like compounds, which TRI has facilities report in grams, are converted and marked with reportedUnit. TRI data lags ~18 months — the most recent available year is typically 2 years prior to the current calendar year. facility_id is the 15-character TRI facility ID: take it from the facilityId field of epa_tri_search_releases, or from the triFacilityIds of epa_echo_get_facility for a facility you already hold a Registry ID for. A 12-digit EPA Registry ID is a different identifier and matches no TRI records.

NameTypeReqDescription
chemical_namestring–Optional filter to restrict results to a specific chemical (partial match, case-insensitive). Commas, apostrophes, brackets, and Greek letters are matched as written, e.g. "4,4'-Methylenedianiline".
facility_idstringyes15-character TRI facility ID (e.g. "9867WSNRWD1981S") — the facilityId field returned by epa_tri_search_releases, or an entry of epa_echo_get_facility triFacilityIds. A 12-digit EPA Registry ID match…
limitinteger–Maximum number of filings to return in one call (1–500, default 500). A larger value, up to 5,000, returns 500 with a notice. Page past it with offset and nextOffset.
offsetinteger–Number of filings to skip before this page (default 0). Pass the previous call's nextOffset to continue; a value past the end returns an empty page.
yearinteger–Reporting year to retrieve. Omit for all available years, newest first. TRI data is typically available through ~2 years prior to the current year.
NameTypeReqDescription
capnumber–The limit that was applied. Present only when truncated.
errorobject–Present when the call failed. Absent on success.
facilityIdstring–TRI facility ID queried
guidancestring–Present when truncated: the offset that continues the lookup.
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
messagestring–Recovery hint when no releases are found — suggests alternative years or checking the facility ID. Absent when releases are returned.
nextOffsetnumber–Offset of the next page: present exactly when more records follow, absent on the last page. Pass it as offset to continue.
noticestring–Present when a punctuated chemical_name filter read its page limit before finding every filing spelled as given, so more matching records may exist.
releasesarray–Per-chemical annual TRI release records for the queried facility
shownnumber–Number of filings returned. Present only when truncated.
truncatedboolean–True when more filings may follow this page; nextOffset continues it. Absent on the last page.

No examples provided.

epa_tri_search_releases ~589

TRI: Search Toxic Release Inventory data across facilities in a state or county, for one reporting year or, without year, every available year newest first. Returns facility name and county, TRI facility ID, EPA Registry ID (the registry_id epa_echo_get_facility takes), parent company, chemical name, and the Form R one-time release quantity; set include_release_breakdown to add on-site releases by medium (air, water, land, and underground-injection) and their total, at the cost of a slower call. Quantities are in pounds; dioxin and dioxin-like compounds, which TRI has facilities report in grams, are converted and marked with reportedUnit. Records come in reporting-year order, not ranked by quantity; page through a large match with offset and nextOffset. Use to build an environmental exposure profile for an area. Use epa_tri_get_facility_releases for detailed release records for a single facility. TRI data lags ~18 months from the current calendar year.

NameTypeReqDescription
chemical_namestring–Optional filter to restrict results to a specific chemical (partial match, case-insensitive). Commas, apostrophes, brackets, and Greek letters are matched as written, e.g. "4,4'-Methylenedianiline".
countystring–County name to narrow results within the state, e.g. "King". Case-insensitive partial match on the bare name, so a short name can also match a longer one (LAKE matches LAKE OF THE WOODS; check county…
include_release_breakdownboolean–Add on-site releases by medium (air, water, land, underground injection) and their total to each record. Costs one extra upstream request, which can add about 20 seconds when EPA has not cached it.
limitinteger–Maximum number of release records to return in one call (1–200, default 50). A larger value, up to 5,000, returns 200 with a notice. Page past it with offset and nextOffset.
offsetinteger–Number of release records to skip before this page (default 0). Pass the previous call's nextOffset to continue; a value past the end returns an empty page.
statestringyes2-letter US state or territory code (required, e.g. "WA", "TX", "PR")
yearinteger–Reporting year. Omit to search every available year in the state, newest reporting year first, so the first page holds the most recent filings. TRI data lags ~18 months.
NameTypeReqDescription
capnumber–The limit that was applied. Present only when truncated.
effectiveQuerystring–The search as the server sent it upstream, in this tool's input names: normalized values, how each text filter matched ("=" exact, "contains", "begins with", "has words"), and defaults that change wh…
errorobject–Present when the call failed. Absent on success.
guidancestring–Present when truncated: the offset that continues the search.
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
messagestring–Recovery hint when no releases are found. Absent when releases are returned.
nextOffsetnumber–Offset of the next page: present exactly when more records follow, absent on the last page. Pass it as offset to continue.
noticestring–Present when a punctuated county or chemical_name filter read its page limit before finding limit matches spelled as given, so more matching records may exist.
releasesarray–TRI release records for facilities in the queried state and filters
shownnumber–Number of release records returned. Present only when truncated.
statestring–State queried, as the search sent it (uppercase code)
truncatedboolean–True when more release records may follow this page; nextOffset continues it. Absent on the last page.

No examples provided.

epa_water_search_systems ~643

Drinking water (SDWIS): Search public water systems by state, ZIP code, or county served. Returns system name, PWSID, population served, primary water source, and activity status, in PWSID order; page through a large match with offset and nextOffset. zip_code matches a system's address of record, often an owner's or operator's office far from the area it serves; county (with state) finds the systems serving an area. With has_violation, returns only systems with a current SDWA violation in EPA's ECHO, which applies EPA's Enforcement Response Policy, so it flags fewer systems than SDWIS's unresolved violation records. At least one of state or zip_code is required. Pass a returned pwsid as registry_id to epa_echo_get_facility for the system's drinking-water violations: contaminant, measured level, MCL, status, and enforcement actions.

NameTypeReqDescription
active_onlyboolean–When true, return only systems SDWIS lists as active (activity code A). The default false also returns inactive systems and ones changed to non-public.
countystring–County the system serves, e.g. "King"; requires state. Case-insensitive, and a trailing "County", "Parish", "Borough", "City and Borough", "Census Area", or "Municipality" is dropped, so "Anchorage"…
has_violationboolean–When true, return only systems with a current SDWA violation in EPA's ECHO, its compliance status for the system, which clears violations SDWIS still lists as unresolved. Works with state, zip_code,…
limitinteger–Maximum number of systems to return in one call (1–200, default 50). A larger value, up to 5,000, returns 200 with a notice. Page past it with offset and nextOffset.
offsetinteger–Number of systems to skip before this page (default 0). Pass the previous call's nextOffset to continue; a value past the end returns an empty page.
pws_typestring–Filter by public water system type: community=permanent residences, non-transient=regular non-residents (schools, businesses), transient=occasional users (campgrounds)
statestring–2-letter US state or territory code (e.g. "WA", "CA"), or an EPA region code 01–10 for tribal systems, whose primacy agency is the EPA region
zip_codestring–5-digit ZIP code of the water system's address of record — often its owner's or operator's office, which can be far from the area the system serves. Matches stored ZIP+4s within it; a ZIP+4 searches…
NameTypeReqDescription
effectiveQuerystring–The search as the server sent it upstream, in this tool's input names: normalized values, how each text filter matched ("=" exact, "contains", "begins with", "has words"), and defaults that change wh…
errorobject–Present when the call failed. Absent on success.
guidancestring–Present when more systems may follow: the offset that continues the search.
limitNoticestring–Present when limit was above the cap and the call returned the cap instead.
messagestring–Recovery hint when no systems are found. Absent when systems are returned.
nextOffsetnumber–Offset of the next page: present exactly when more records follow, absent on the last page. Pass it as offset to continue.
noticestring–Present when a check ended before the page filled: a ZIP or county has_violation check read its 1,000-system limit, or the county check reached its read limit with few whole-name matches. nextOffset…
systemsarray–Matching public water systems, in PWSID order
totalCountnumber–Systems matched before limit and offset. Present when the call saw the whole match: a search from offset 0 with no nextOffset, or a state has_violation search that checked ECHO's whole violator list.…

No examples provided.

Install

How do I install the io.github.cyanheads/epa-mcp-server server?

io.github.cyanheads/epa-mcp-server is a hosted endpoint at https://epa.caseyjhand.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · epa.caseyjhand.com

# add to Claude Code
claude mcp add --transport http cyanheads-epa-mcp-server 'https://epa.caseyjhand.com/mcp'
Common questions

What is the io.github.cyanheads/epa-mcp-server server?

io.github.cyanheads/epa-mcp-server is listed in the public MCP registry as io.github.cyanheads/epa-mcp-server. Search EPA compliance, TRI, Superfund, drinking-water, EJScreen, and AirNow data. This page covers its hosted endpoint (https://epa.caseyjhand.com/mcp).

Is the io.github.cyanheads/epa-mcp-server server safe to use?

io.github.cyanheads/epa-mcp-server scores 75 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the io.github.cyanheads/epa-mcp-server server expose?

io.github.cyanheads/epa-mcp-server exposes 11 tools: epa_echo_search_facilities, epa_echo_get_facility, epa_echo_search_violations, epa_echo_get_case, epa_tri_get_facility_releases, and 6 more. Their descriptions and schemas cost roughly 5,262 tokens of context every time the server is loaded.

Does the io.github.cyanheads/epa-mcp-server server require authentication?

No. We connected to io.github.cyanheads/epa-mcp-server without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the io.github.cyanheads/epa-mcp-server server still maintained?

io.github.cyanheads/epa-mcp-server is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.