Skip to main content
Glama
cyanheads

earthquake-mcp-server

by cyanheads

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Public Hosted Server: https://earthquake.caseyjhand.com/mcp


Overview

Seismic data from USGS ComCat and the EMSC SeismicPortal. Fetch real-time earthquake feeds, search and count seismic events by time, magnitude, depth, and location, and pull full analysis detail for a single event. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.

Tools

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

Resources

Resource

Description

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

earthquake://event/{event_id}

Full USGS earthquake event detail by ID as injectable context, including the same detail product projection as earthquake_get_event

Related MCP server: usgs-earthquakes

Capability reference

earthquake_get_feed tool

  • Choose a magnitude tier (all, 1.0, 2.5, 4.5, significant) and a window (hour, day, week, month). USGS caches these feeds; use earthquake_search for historical or filtered queries.

  • Returns events, page count, generation time, and source feed URL. all includes microseisms; significant is USGS-curated using magnitude, felt reports, and PAGER impact.

  • limit defaults to 100, max 1000. totalCount reports the whole feed and nextCursor retrieves another page; pass the opaque cursor back unchanged.


  • Search usgs or emsc by time, magnitude, depth, radius, or bounding box. A radius requires latitude, longitude, and radius_km together; box edges are independently optional, support antimeridian bounds up to ±360°, and intersect a supplied circle.

  • Returns normalized events with event_type and EMSC's event_certainty. ignoredFilters names unsupported filters; queryEcho reports the effective query.

  • Sort by time or magnitude in either direction. limit defaults to 100, max 20,000; paging uses a 1-based offset. Capped results carry nextOffset and totalCount, or countUnavailable if the count lookup failed. Use earthquake_count first to size the match set.


earthquake_count tool

  • Count matches using the same filters as earthquake_search, without fetching events. Omit start_time for the last 30 days; queryEcho reports the resolved window and applied filters.

  • exceeds_limit flags counts above 20,000. max_allowed is 20,000 for USGS and null for EMSC; ignoredFilters names filters the source cannot apply.


earthquake_get_event tool

  • Pass a USGS event_id from the id field of a feed or search result (e.g. us6000sznj). EMSC has no per-event detail endpoint.

  • Returns the normalized event plus optional detail: PAGER, ShakeMap, DYFI, moment tensor, ground-failure alerts, origin quality, and finite-fault dimensions. Groups are omitted when USGS produced no corresponding product.


earthquake://feed/{magnitude_tier}/{time_window} resource

  • Choose the same magnitude tiers and time windows as earthquake_get_feed; all 20 combinations are listed as browsable resources.

  • Returns the whole feed as application/json, with a public 60-second cache hint. Broad week/month feeds can contain thousands of events; use earthquake_get_feed for paging.


earthquake://event/{event_id} resource

  • Pass a USGS event_id from a feed or search result. Returns the same event and optional detail products as earthquake_get_event.

  • Uses that tool's not_found, source_unavailable, and source_timeout error contract.

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

USGS/EMSC-specific:

  • Type-safe clients for the USGS FDSN/GeoJSON API and the EMSC FDSN-WS API, normalizing both into one shared earthquake domain schema

  • Automatic retry with backoff and per-request timeouts on every upstream call; detects USGS's rate-limited/CDN failure mode (HTML served instead of GeoJSON) and maps it to a typed service-unavailable error instead of parsing it as data

  • EMSC's two-character evtype code is decoded against the published event-type/certainty nomenclature into the same vocabulary USGS publishes, so event_type carries one meaning across both sources

  • USGS-only filters (alert_level, min_felt, min_significance, event_type) are named in ignoredFilters when source=emsc. On USGS, event_type="earthquake" excludes quarry blasts and other non-tectonic records.

  • No API key or rate-limit tier required — both USGS and EMSC are fully public, keyless APIs

Agent-friendly output:

  • Provenance — source: "usgs" | "emsc" on every response, plus source_catalog/auth fields naming the catalog and authoritative agency, so agents can weigh two independent solutions against each other

  • Discriminated output contracts — event_type and event_certainty travel with every event so a quarry blast or a suspected explosion is never silently read as a confirmed earthquake; exceeds_limit, countUnavailable, and truncated flags let callers branch on data instead of parsing prose

  • Response shaping — fields a source does not publish come back null, never a fabricated zero (tsunami, status, and mmi are always null on EMSC events); USGS-only filters dropped for an EMSC query are named in ignoredFilters rather than silently ignored

  • Graceful degradation — an upstream rejection surfaces the service's own explanation (offending parameter, accepted format) in the error message instead of a bare status code, and a failed follow-up count degrades to countUnavailable rather than failing the whole search

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.4.0 or higher.

  • No API keys required — USGS and EMSC data is fully public.

Installation

  1. Clone the repository:

git clone https://github.com/cyanheads/earthquake-mcp-server.git
  1. Navigate into the directory:

cd earthquake-mcp-server
  1. 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 sessions: stateful, stateless, or auto (resolves to stateful). Overrides the createApp() declaration; Docker and .env.example also pin stateless.

stateless (declared in src/index.ts)

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 on Node.js and Bun

<project-root>/logs

LOG_TOOL_FAILURE_PAYLOADS

Log failed tool arguments and results, redacted by key name. Secrets inside free-form values remain.

false

LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES

UTF-8 byte cap per logged failure payload

16384

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

OTEL_EXPORTER_OTLP_ENDPOINT

Base URL for traces (/v1/traces) and metrics (/v1/metrics); signal-specific endpoint variables override it

none

OTEL_EXPORTER_OTLP_LOGS_ENDPOINT

Opt-in OTLP log endpoint, used as-is; the base URL never enables logs

none

Empty values and unsubstituted whole-value ${…} placeholders use the defaults. See .env.example for optional overrides.

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

Docker

docker build -t earthquake-mcp-server .
docker run --rm -p 3010:3010 earthquake-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/earthquake-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

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/catch in tool logic

  • Use ctx.log for logging, ctx.state for storage

  • Register new tools and resources in the createApp() arrays

  • Validate upstream data, normalize to domain types, and preserve missing values rather than inventing facts

Contributing

Issues 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.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    An MCP server for querying the FDSN Web Service Event APIs of multiple seismological datacenters and retrieving earthquake information as JSON.
    6
    2
    AGPL 3.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides access to the USGS Earthquake Catalog for querying earthquake events via the FDSNWS API, enabling natural language questions about earthquake data.
    173 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    MCP server wrapping the USGS Earthquake Hazards API, enabling AI assistants to search the global earthquake catalog, look up event details, count quakes, find 'Did You Feel It' reports, and read realtime feeds.
    5
    MIT