Skip to main content
Glama

igepn-mcp

Ecuador earthquakes and volcano activity from the IGEPN (Instituto Geofísico de la Escuela Politécnica Nacional) → SQLite (accumulating, never pruned) → structured MCP tools. Source: the IGEPN public Telegram channel, read through its keyless public preview t.me/s/SismosVolcanesIGEPN. Design rationale: CLAUDE.md.

Tools

tool

use

last_quake()

the most recent quake (revised value if available, plus the preliminary estimate) — "¿qué fue ese temblor?"

latest_quakes(hours=24, min_mag?, place?, n=15)

recent quakes, one per event; place is accent-insensitive ("Manabí", "Quito")

volcano_status(volcano?)

latest surface/internal activity level + trend (all volcanoes reported in the last 30 days, or one)

ig_alerts(hours=48, volcano?, n=10)

#IGAlInstante bulletins (lahars, ash, activity) and special volcano reports, as written

Times come in Ecuador local time (occurred_local_ec, UTC−5) and UTC. Quakes keep IGEPN's status (PRELIMINAR / REVISADO, older posts CONFIRMADO). Every item carries a post_url (the Telegram post, with its image) for the UI to show.

Related MCP server: TMD Earthquake MCP Server

Run

uv sync
uv run igepn-mcp poll                        # fetch new posts once (watermark-incremental; run every ~3 min)
uv run igepn-mcp backfill --pages 50         # walk history backwards, ~20 posts/page, resumable (see below)
uv run igepn-mcp reparse                     # rebuild parsed tables from the raw log after a parser change
uv run igepn-mcp serve                       # stdio (Claude Desktop / dev)
IGEPN_MCP_TOKEN=secret uv run igepn-mcp serve --transport http --host 0.0.0.0 --port 8000   # streamable-http at /mcp
uv run pytest

env

default

IGEPN_DB

data/igepn.db

SQLite path (WAL; poller and server can share it)

IGEPN_POLL_MINUTES

0 (off)

>0: serve also polls in the background (no timer needed); 3 recommended

IGEPN_MCP_TOKEN

unset

bearer token required on HTTP (/healthz stays open)

IGEPN_CHANNEL

SismosVolcanesIGEPN

Telegram channel

IGEPN_MAX_CATCHUP_PAGES

25

pages one poll may walk back to reach the watermark after downtime

IGEPN_USER_AGENT, IGEPN_FETCH_TIMEOUT

honest UA, 20

Storage

posts_raw is the append-only record of every kept post (procurement notices are dropped). quakes keeps every report (preliminary and revised) and the view v_quake_current gives the latest per event (the revised one wins). volcano_reports covers daily, weekly and monthly reports, and alerts holds the free-text bulletins. The parsed tables are derived from posts_raw, so reparse can rebuild them at any time.

History

The preview pages back to the channel's first post (2019), so backfill can recover the full archive through the same keyless route, about 620 pages. Its default of 3 s between pages keeps it polite. It is resumable, so it can run in chunks (--pages 100 at a time). The parser handles all three post formats the channel has used (2019, 2021, 2023+).

Claude Desktop

%APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "igepn": {
      "command": "uv",
      "args": ["--directory", "C:\\Code\\igepn-mcp", "run", "igepn-mcp", "serve"],
      "env": { "IGEPN_DB": "C:\\Code\\igepn-mcp\\data\\igepn.db", "IGEPN_POLL_MINUTES": "3" }
    }
  }
}

Docker Compose (e.g. mcpo → Open WebUI)

Build the image with docker build -t igepn-mcp .. It serves HTTP on :8000 at /mcp, and the healthcheck uses the open /healthz endpoint.

services:
  igepn-mcp:
    image: igepn-mcp:latest
    restart: unless-stopped
    environment:
      IGEPN_MCP_TOKEN: ${IGEPN_MCP_TOKEN}    # put it in .env; clients send "Authorization: Bearer <token>"
      IGEPN_POLL_MINUTES: "3"                # poll at startup, then every 3 min (no timer needed)
      IGEPN_USER_AGENT: "igepn-mcp/0.1 (+https://example.org/your-contact)"   # identify your deployment
    volumes:
      - igepn-data:/data                     # SQLite; local disk, not NFS/SMB. Accumulates - back it up.
volumes:
  igepn-data:

One-time history backfill into the same volume: docker compose run --rm igepn-mcp backfill --pages 700.

mcpo entry (from a container on the same network):

{ "mcpServers": { "igepn": { "type": "streamable-http", "url": "http://igepn-mcp:8000/mcp",
  "headers": { "Authorization": "Bearer ${IGEPN_MCP_TOKEN}" } } } }

AI assistance

igepn-mcp is developed openly with the help of Claude (Anthropic). We state this plainly: commits Claude helped write carry a Co-Authored-By: Claude trailer. The code and design are open source so the work can be inspected, reused, and given back.

License

Code: MPL-2.0. The earthquake and volcano reports belong to the IGEPN (igepn.edu.ec); they are fetched from its public channel and stay in your local database. Attribute them to the IGEPN, keep polling polite (≥3 min), and set IGEPN_USER_AGENT to identify your own deployment. For official information and emergencies, follow the IGEPN and Ecuador's risk-management authorities directly.

Available Tools

4 tools
ig_alertsA
Read-only

Recent IGEPN instant bulletins (#IGAlInstante: lahars, ash emissions, increased activity) and special volcano reports, newest first, as IGEPN wrote them. Use for "any volcano alerts", "is there ash from the Sangay", "lahar warnings". Relay safety recommendations exactly as written.

    Args:
        hours: look-back window in hours (default 48; 168 = one week).
        volcano: optional volcano name filter, e.g. "Sangay".
        n: max bulletins (default 10, max 50).
    
ParametersJSON Schema
NameRequiredDescriptionDefault
nNo
hoursNo
volcanoNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnly and openWorld; the description adds real behavior beyond that: newest-first ordering, verbatim IGEPN text, and the instruction to relay safety recommendations exactly as written. It omits rate limits, coverage/latency caveats, and what an empty result means, keeping it below 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the resource and provenance in the first sentence, then intent examples, then a tidy Args block. Every line is useful, though the phrasing is slightly verbose and the Args formatting leaks into the description body.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly describes what comes back (bulletin text and special reports, newest first) and how to handle safety content. It leaves minor gaps around time-window semantics and empty results, but is otherwise complete for a read-only alert feed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the Args block carries the full load: it documents all three parameters with defaults (hours=48, n=10) and constraints (168=one week, max 50) plus a concrete volcano example ('Sangay'). This fully compensates for the missing schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Recent IGEPN instant bulletins... and special volcano reports') with ordering ('newest first') and provenance ('as IGEPN wrote them'). It does not explicitly distinguish itself from the sibling volcano_status, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete trigger queries ('any volcano alerts', 'is there ash from the Sangay', 'lahar warnings') that map user intent to this tool. It never names an alternative or exclusion condition against volcano_status or latest_quakes, so it stops short of explicit when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

last_quakeA
Read-only

The single most recent earthquake reported by the IGEPN, with its latest (revised if available) values. Use for "¿qué fue ese temblor?", "what was that earthquake just now", "did it just shake?".

    Check `ago`: if the last quake is hours or days old, the tremor the user felt may not be reported yet
    (a PRELIMINAR report usually appears within ~5 minutes) - say so rather than guessing.
    When the event was revised, `preliminary` shows the first estimate for comparison.
    
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true and openWorldHint=false, so safety is covered and the description adds genuine operational context: PRELIMINAR reports appear in ~5 minutes, results may be revised, and `preliminary` preserves the first estimate. This latency/revision behavior is not derivable from annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with scope, then user-intent triggers, then the caveat and field guidance. Every sentence contributes distinct information (scope, triggers, staleness handling, revision semantics) with no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must carry return-value burden; it explains the two most decision-relevant fields (`ago`, `preliminary`) and the revision model. Coverage of the full response shape is partial, but the critical caveats for correct use are present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter syntax to explain; baseline for a no-arg tool is 4. The description instead directs attention to the fields to inspect in the result (`ago`, `preliminary`), which is more useful than param documentation would be here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific resource and scope: 'the single most recent earthquake reported by the IGEPN, with its latest (revised if available) values.' The word 'single' implicitly separates it from the sibling latest_quakes (plural list), but no sibling is named explicitly, so an agent must infer the routing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete trigger phrases ('what was that earthquake just now', 'did it just shake?') and tells the agent what to do when the result is stale: check `ago` and say the report may not exist yet rather than guessing. It stops short of naming latest_quakes as the alternative for multi-event lookups.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

latest_quakesA
Read-only

Recent earthquakes reported by the IGEPN, newest first, one entry per event (its latest report). Use for "earthquakes today / this week", "any tremors near Quito?", "strong quakes this month".

    Args:
        hours: look-back window in hours (default 24; e.g. 168 = one week, 720 = 30 days).
        min_mag: only events with magnitude >= this (e.g. 4).
        place: text that must appear in the location, case/accent-insensitive: a city or province as IGEPN
            writes it, e.g. "Quito", "Manabí", "Esmeraldas" (IGEPN names the NEAREST town, so a quake felt
            in a city may be listed under a neighbouring one).
        n: max events (default 15, max 50).
    
ParametersJSON Schema
NameRequiredDescriptionDefault
nNo
hoursNo
placeNo
min_magNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely non-obvious behavior: the source is IGEPN, results are newest-first, repeated reports are collapsed to the latest entry per event, and IGEPN labels the NEAREST town — so a place match may miss the city where the quake was felt. That caveat is the kind of operational insight annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded summary sentence followed by a clean Args block; the usage examples earn their place by tying user phrasings to arguments. It is a little longer than strictly necessary, but there is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still conveys the result shape (one entry per event, latest report, newest first) and documents all four optional parameters including bounds and defaults. Nothing needed to call the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does so: hours with a default plus 168/720 conversions, min_mag as a >= threshold with an example, place with case/accent-insensitivity, examples and the nearest-town caveat, and n with default 15 and a max of 50. Every parameter gains meaning absent from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource (recent earthquakes from IGEPN), the ordering (newest first), and the de-duplication semantics (one entry per event, latest report). That scope plus ordering implicitly separates it from the singular sibling last_quake, so an agent can route without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete trigger phrases ('earthquakes today / this week', 'any tremors near Quito?', 'strong quakes this month') that map onto the hours/min_mag/place arguments, which is clear guidance about when to reach for this tool. It stops short of naming alternatives or stating exclusions relative to last_quake / ig_alerts, so it is not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

volcano_statusA
Read-only

Latest IGEPN activity report for Ecuadorian volcanoes: surface and internal activity level, each with its trend. Use for "how is the Sangay", "is Cotopaxi active", "volcano status".

    Without `volcano`: every volcano with a report in the last 30 days (IGEPN only publishes periodic
    reports for volcanoes it is actively following; others are not listed). With `volcano`: that
    volcano's latest report however old (check `report_date`) plus its recent instant alerts.

    Args:
        volcano: name, case/accent/space-insensitive, e.g. "Sangay", "reventador", "Cotopaxi".
    
ParametersJSON Schema
NameRequiredDescriptionDefault
volcanoNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint/openWorldHint already covering safety, the description adds genuinely non-obvious behavior: IGEPN only publishes periodic reports for volcanoes it actively follows, so unreported volcanoes are absent; the 30-day window for the no-argument mode; and the fallback to a possibly stale report (read `report_date`) plus instant alerts when a name is given.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the two calling modes and then the Args note, so scanning yields the key decision first. The `volcano` argument is described once in the prose and again in the Args block, which is mild redundancy but not noise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description largely compensates by enumerating the returned fields (activity levels, trends, report_date, instant alerts). It stops short of describing the structure or formatting of those fields, which is the only remaining gap for a single-parameter read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does: it defines the parameter as a volcano name, states case/accent/space-insensitivity with three worked examples, and fully specifies the default behavior when the parameter is omitted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (latest IGEPN activity report for Ecuadorian volcanoes) and names the exact payload fields (surface and internal activity level, each with trend). Sibling overlap with ig_alerts is preempted by clarifying that instant alerts are only attached when a volcano is named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete trigger phrasings ("how is the Sangay", "is Cotopaxi active") and clearly splits the two calling modes: omit `volcano` for every volcano reported in the last 30 days, supply `volcano` for that volcano's latest report however old. It never explicitly routes away from ig_alerts, which is the nearest sibling, so 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedig_alerts
    • First observedlast_quake
    • First observedlatest_quakes
    • First observedvolcano_status

TDQS

A4.4/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: last_quake fetches a single most-recent event, latest_quakes lists events with filters, volcano_status provides activity reports, and ig_alerts delivers bulletins. The descriptions explicitly differentiate use cases, leaving no ambiguity.

Naming Consistency4/5

All names use snake_case consistently, but the structural patterns vary (adjective_noun, noun_noun, abbreviation_noun). This minor deviation from a uniform pattern prevents a perfect score.

Tool Count5/5

Four tools are well-scoped for a focused monitoring server, covering core needs of recent earthquakes, volcano status, and alerts without redundancy. Each tool earns its place.

Completeness4/5

The surface covers the main earthquake and volcano information needs, but lacks detailed historical querying beyond hourly windows or event-specific lookups. These minor gaps are workable with existing filters.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers