npm @cyanheads/earthquake-mcp-serverstreamable-httpupdated 14d ago
@cyanheads/earthquake-mcp-server Search USGS and EMSC seismic data — real-time feeds, event queries, and earthquake counts via MCP. STDIO or Streamable HTTP. 4 Tools • 2 Resources
What can you do with 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 |
|---|---|
earthquake_get_feed |
Fetch a USGS pre-computed real-time earthquake feed by magnitude tier and time window |
earthquake_search |
Search earthquakes by time range, magnitude, depth, location radius, PAGER alert level, or felt reports |
earthquake_count |
Count earthquakes matching filters without fetching full records |
earthquake_get_event |
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,month - Returns 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 formonth - The 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 type - Every 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 USGS - Location-based queries: provide
latitude,longitude, andradius_kmtogether - Rectangular 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 antimeridian - Sort 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 sources offsetcounts 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 absent- Use
earthquake_countfirst to gauge result size - USGS-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 type - A radius over a mining region counts quarry blasts alongside earthquakes — pass
event_type="earthquake"on USGS to exclude them - Returns
exceeds_limitflag when count exceeds 20,000 — signals a full search needs paging - Echoes the effective query back as
queryEcho, including the resolved time window — omittingstart_timecounts only the last 30 days - USGS 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 holds detailgroups: 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 width- A 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 | earthquake://feed/{magnitude_tier}/{time_window} |
USGS real-time earthquake feed as injectable context — returns the whole feed, so use the earthquake_get_feed tool for the broad tiers |
| Resource | earthquake://event/{event_id} |
Full USGS earthquake event detail by ID as injectable context, including the same detail product projection as earthquake_get_event |
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/D1 - Structured 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 provenance exceeds_limitflag on count responses surfaces truncation risk before a full search- Fields 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 other- USGS-only filters dropped for an EMSC query are named in
ignoredFilterson bothearthquake_searchandearthquake_count - An 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/mcp
Prerequisites
- 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.git
- Navigate into the directory:
cd earthquake-mcp-server
- Install dependencies:
bun install
Configuration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE |
Transport: stdio or http |
stdio |
MCP_HTTP_PORT |
HTTP server port | 3010 |
MCP_HTTP_ENDPOINT_PATH |
HTTP endpoint path where the MCP server is mounted | /mcp |
MCP_PUBLIC_URL |
Public origin override for TLS-terminating reverse-proxy deployments | none |
MCP_SESSION_MODE |
HTTP session handling: stateful, stateless, or auto. The Docker image and .env.example ship stateless. |
auto (resolves to stateful) |
MCP_AUTH_MODE |
Authentication: none, jwt, or oauth |
none |
MCP_LOG_LEVEL |
Log level (debug, info, warning, error, etc.) |
info |
MCP_GC_PRESSURE_INTERVAL_MS |
Opt-in Bun-only forced-GC pressure loop (ms). Try 60000 if heap growth is observed under sustained HTTP load. |
0 (disabled) |
LOGS_DIR |
Directory for log files (Node.js only) | <project-root>/logs |
STORAGE_PROVIDER_TYPE |
Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 |
in-memory |
USGS_BASE_URL |
USGS API base URL. Override for testing or mirroring. | https://earthquake.usgs.gov |
EMSC_BASE_URL |
EMSC API base URL. Override for testing or mirroring. | https://www.seismicportal.eu |
DEFAULT_LIMIT |
Default result limit for earthquake_search |
100 |
REQUEST_TIMEOUT_MS |
HTTP timeout in milliseconds for upstream API calls | 10000 |
OTEL_ENABLED |
Enable OpenTelemetry | false |
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:stdio -
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Project structure
| Directory | Purpose |
|---|---|
src/mcp-server/tools |
Tool definitions (*.tool.ts). Four tools across USGS and EMSC. |
src/mcp-server/resources |
Resource definitions. Feed and event resources. |
src/services/usgs |
USGS ComCat service — GeoJSON feed fetcher and FDSN query API client. |
src/services/emsc |
EMSC SeismicPortal service — FDSN event search and count endpoints. |
src/config |
Server-specific environment variable parsing and validation with Zod. |
tests/ |
Unit and integration tests, mirroring the src/ structure. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor logging,ctx.statefor storage - Register 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 test
License
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
Install
Add earthquake mcp server to your client. Pick the one you use.
{
"servers": {
"earthquake-mcp-server": {
"type": "http",
"url": "https://earthquake.caseyjhand.com/mcp"
}
}
}Add to `.vscode/mcp.json` in your workspace.
claude mcp add earthquake-mcp-server -- npx -y @cyanheads/earthquake-mcp-servercodex mcp add earthquake-mcp-server -- npx -y @cyanheads/earthquake-mcp-serveramp mcp add earthquake-mcp-server -- npx -y @cyanheads/earthquake-mcp-server{
"mcpServers": {
"earthquake-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"earthquake-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
{
"mcpServers": {
"earthquake-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"earthquake-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"earthquake-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"earthquake-mcp-server": {
"type": "local",
"command": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"earthquake-mcp-server": {
"command": {
"path": "npx",
"args": [
"-y",
"@cyanheads/earthquake-mcp-server"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y @cyanheads/earthquake-mcp-serverRun `goose configure`, choose **Add Extension → Command-line Extension**, and paste this command.
4 tools
earthquake mcp server exposes 4 tools to a connected agent.
- earthquake_get_feed
- Fetch a USGS pre-computed real-time earthquake feed by magnitude tier and time window
- earthquake_search
- Search earthquakes by time range, magnitude, depth, location radius, PAGER alert level, or felt reports
- earthquake_count
- Count earthquakes matching filters without fetching full records
- earthquake_get_event
- Fetch complete detail for a specific earthquake by USGS event ID
Score
80 / 100
Excellent
- Documentation25/25
- Maintenance25/25
- Trust6/20
- Capability9/15
- Install experience15/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 7 days ago
- Has a release history
- Repository is not archived
- No licence detected
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 4 tool(s) documented
- Provides prompt templates
- Provides resources
- 18 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint — no local install
Version history
| Versions | Published |
|---|---|
| 0.3.4Latest | Aug 25, 2026 |
| 0.3.3 | Aug 18, 2026 |
| 0.3.2 | Aug 18, 2026 |
| 0.3.1 | Jul 26, 2026 |
| 0.3.0 | Jul 26, 2026 |
| 0.2.0 | Jul 26, 2026 |
| 0.1.16 | Jul 2, 2026 |
| 0.1.15 | Jun 20, 2026 |
| 0.1.14 | Jun 16, 2026 |
| 0.1.13 | Jun 12, 2026 |
| 0.1.12 | Jun 4, 2026 |
| 0.1.11 | Jun 2, 2026 |
| 0.1.10 | May 30, 2026 |
| 0.1.9 | May 29, 2026 |
| 0.1.8 | May 24, 2026 |
| 0.1.7 | May 24, 2026 |
| 0.1.6 | May 24, 2026 |
| 0.1.5 | May 24, 2026 |
| 0.1.4 | May 24, 2026 |
| 0.1.3 | May 24, 2026 |