earthquake-mcp-server
Public Hosted Server: https://earthquake.caseyjhand.com/mcp
Tools
4 tools for querying global earthquake data from USGS and EMSC:
Tool | Description |
| Fetch a USGS pre-computed real-time earthquake feed by magnitude tier and time window |
| Search earthquakes by time range, magnitude, depth, location radius, PAGER alert level, or felt reports |
| Count earthquakes matching filters without fetching full records |
| Fetch complete detail for a specific earthquake by USGS event ID |
earthquake_get_feed
Fetch a USGS pre-computed real-time earthquake feed by magnitude tier and time window.
CDN-cached by USGS — faster and more available than the FDSN query API
Five magnitude tiers:
all(microseisms),1.0,2.5,4.5, andsignificant(USGS-curated by magnitude, felt reports, and PAGER impact)Four time windows:
hour,day,week,monthReturns event list with counts and the source feed URL
Paged with an opaque
cursor:limitbounds a page (default 100, max 1000),totalCountreports the whole feed, andnextCursorretrieves the rest — the broad tiers run past 10,000 events formonthThe cursor is opaque because these feeds have no upstream paging parameter and USGS regenerates them about once a minute; a numeric offset across two calls would skip or repeat events
Best for real-time "what's happening now" queries; use
earthquake_searchfor historical or filtered queries
earthquake_search
Search earthquakes by time range, magnitude, depth, location radius, PAGER alert level, or felt reports.
Dual-source: USGS (global, richer metadata) or EMSC (an independent global catalog from the European-Mediterranean Seismological Centre, for cross-verification anywhere)
Full FDSN ComCat query API parameters: time range, magnitude, depth, location radius
USGS-specific filters: PAGER alert level (
green/yellow/orange/red), DYFI felt reports count, significance score, event typeEvery event carries an
event_typein one vocabulary whichever source served it — the QuakeML names USGS publishes (earthquake,quarry blast,explosion,ice quake); EMSC's two-character code is decoded to the same names, with how sure EMSC was kept beside it inevent_certainty— and theevent_typefilter narrows to one of them on USGSLocation-based queries: provide
latitude,longitude, andradius_kmtogetherRectangular study areas:
min_latitude,max_latitude,min_longitude,max_longitude, each independently optional and forwarded to both sources; combining a box with the radius circle intersects the two. Longitude accepts up to ±360 so a box can cross the antimeridianSort by time (newest first) or magnitude (largest first), ascending or descending
One call returns at most 20,000 events; page beyond that with
offset, forwarded straight to the upstream FDSNoffsetparameter on both sourcesoffsetcounts from 1, matching both upstream APIs — a capped result carriestotalCountand thenextOffsetto pass on the following call, and says so withcountUnavailablewhen the follow-up count query failed rather than leaving the total silently absentUse
earthquake_countfirst to gauge result sizeUSGS-specific filters are not supported by EMSC — when
source=emscthey are dropped and named inignoredFilters, so an unconstrained result set is never mistaken for a filtered one
earthquake_count
Count earthquakes matching filters without fetching full records.
Lightweight alternative to
earthquake_searchfor statistical queries ("how many M5+ events in 2025?")Same filter surface as
earthquake_search: time, magnitude, depth, location radius, bounding box, PAGER, DYFI, significance, event typeA radius over a mining region counts quarry blasts alongside earthquakes — pass
event_type="earthquake"on USGS to exclude themReturns
exceeds_limitflag when count exceeds 20,000 — signals a full search needs pagingEchoes the effective query back as
queryEcho, including the resolved time window — omittingstart_timecounts only the last 30 daysUSGS returns the
max_allowedcap (20,000); EMSC count endpoint does not expose this field (max_allowedwill be null)USGS-specific filters are dropped and named in
ignoredFilterswhensource=emsc, the same as onearthquake_search
earthquake_get_event
Fetch complete detail for a specific earthquake by USGS event ID.
Returns the normalized event a search result already carries, plus
detail— a projection of the analysis products only the single-event response holdsdetailgroups: PAGER alert and report link, ShakeMap peak MMI/PGA/PGV and intensity map, DYFI response count and max CDI, moment-tensor scalar moment and nodal planes, landslide and liquefaction alerts, origin quality (azimuthal gap, station count, location and depth uncertainty), finite-fault rupture length and widthA group is omitted when USGS produced no such product — a small automatic event usually has none, a large reviewed one has most of them
Event IDs appear in the
idfield ofearthquake_get_feedandearthquake_searchresults (e.g.us6000sznj,hv74966427)USGS-only — EMSC events have no per-event detail endpoint
Resources
Type | URI pattern | Description |
Resource |
| USGS real-time earthquake feed as injectable context — returns the whole feed, so use the |
Resource |
| Full USGS earthquake event detail by ID as injectable context, including the same |
Features
Built on @cyanheads/mcp-ts-core:
Declarative tool definitions — single file per tool, framework handles registration and validation
Unified error handling across all tools
Pluggable auth (
none,jwt,oauth)Swappable storage backends:
in-memory,filesystem,Supabase,Cloudflare KV/R2/D1Structured logging with optional OpenTelemetry tracing
Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
Earthquake-specific:
Two independent global data sources: USGS ComCat (full metadata) and EMSC SeismicPortal (an independent catalog from the European-Mediterranean Seismological Centre, with no PAGER/DYFI/ShakeMap metadata and station coverage densest around Europe and the Mediterranean)
USGS real-time GeoJSON feeds (CDN-cached, fast availability) plus FDSN event query API
EMSC FDSN-WS event and count endpoints
No API key required — both USGS and EMSC are fully public
Agent-friendly output:
Source attribution on every response (
usgs/emsc) so agents can reason about data provenanceexceeds_limitflag on count responses surfaces truncation risk before a full searchFields a source does not publish come back
null, never as a fabricated zero —tsunamiandstatusare null on EMSC events, and the rendered text says "not published by source" rather than "no tsunami" or "reviewed"source_catalogandauthcarry provenance (which catalog and which authoritative agency produced a solution) so agents can weigh two sources against each otherUSGS-only filters dropped for an EMSC query are named in
ignoredFilterson bothearthquake_searchandearthquake_countAn upstream rejection surfaces the service's own explanation (the offending parameter and its accepted format) in the error message, not just a status code; when the service explains nothing, the error says so under its own reason rather than passing the raw upstream body through
event_typetravels with every event, so a quarry blast or explosion is never silently read as an earthquake, andevent_certaintykeeps a suspected one from reading as confirmed
Getting started
Public Hosted Instance
A public instance is available at https://earthquake.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"earthquake-mcp-server": {
"type": "streamable-http",
"url": "https://earthquake.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"earthquake-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/earthquake-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"earthquake-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/earthquake-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"earthquake-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/earthquake-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.3.0 or higher.
No API keys required — USGS and EMSC data is fully public.
Installation
Clone the repository:
git clone https://github.com/cyanheads/earthquake-mcp-server.gitNavigate into the directory:
cd earthquake-mcp-serverInstall dependencies:
bun installConfiguration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
Variable | Description | Default |
| Transport: |
|
| HTTP server port |
|
| HTTP endpoint path where the MCP server is mounted |
|
| Public origin override for TLS-terminating reverse-proxy deployments | none |
| HTTP session handling: |
|
| Authentication: |
|
| Log level ( |
|
| Opt-in Bun-only forced-GC pressure loop (ms). Try |
|
| Directory for log files (Node.js only) |
|
| Storage backend: |
|
| USGS API base URL. Override for testing or mirroring. |
|
| EMSC API base URL. Override for testing or mirroring. |
|
| Default result limit for |
|
| HTTP timeout in milliseconds for upstream API calls |
|
| Enable OpenTelemetry |
|
Running the server
Local development
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Project structure
Directory | Purpose |
| Tool definitions ( |
| Resource definitions. Feed and event resources. |
| USGS ComCat service — GeoJSON feed fetcher and FDSN query API client. |
| EMSC SeismicPortal service — FDSN event search and count endpoints. |
| Server-specific environment variable parsing and validation with Zod. |
| Unit and integration tests, mirroring the |
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 logging,ctx.statefor storageRegister new tools and resources in the
createApp()arrays
Contributing
Issues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
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/earthquake-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server