DEV Community

atu ino
atu ino

Posted on

Japan Earthquake API — Free JMA JSON with Magnitude, Intensity and Depth

Japan sits on four tectonic plates, so earthquake data matters — and the authoritative source is the Japan Meteorological Agency (JMA, 気象庁), not USGS. The JMA publishes a free JSON feed with no API key. The catch is that the hypocentre coordinates are not stored in fields named lat, lon, or depth.

This post shows the shape of the data, the one field that trips everyone up, and a free MCP server that returns it already parsed.

The feed

https://www.jma.go.jp/bosai/quake/data/list.json
Enter fullscreen mode Exit fullscreen mode

No key, no signup. It returns ~236 entries covering recent weeks, newest first. Each entry looks like this (real record, trimmed):

{
  "ctt": "20261012203531",
  "eid": "20261012203309",
  "rdt": "2026-10-12T20:35:00+09:00",
  "ttl": "震源・震度情報",
  "at": "2026-10-12T20:33:00+09:00",
  "anm": "釧路地方中南部",
  "cod": "+43.2+144.8-80000/",
  "mag": "3.3",
  "maxi": "1"
}
Enter fullscreen mode Exit fullscreen mode

The field that breaks everyone: cod

There is no lat, lon, or depth key. All three are concatenated into a single string:

cod: "+43.2+144.8-80000/"
      └──────┴──────┴──────┘
      lat    lon    depth
Enter fullscreen mode Exit fullscreen mode
  • +43.2 — latitude
  • +144.8 — longitude
  • -80000 — depth in metres, positive upward, so the minus sign means 80 km below the surface
  • / — terminator

Parsing it is a one-liner regex, but the sign convention catches people out:

import re

_COD_RE = re.compile(r"^([+-]\d+(?:\.\d+)?)([+-]\d+(?:\.\d+)?)([+-]\d+)?/?")

def parse_cod(cod: str) -> tuple[float | None, float | None, float | None]:
    """-> (latitude, longitude, depth_km)"""
    if not isinstance(cod, str) or not cod:
        return None, None, None
    m = _COD_RE.match(cod)
    if not m:
        return None, None, None
    lat = float(m.group(1))
    lon = float(m.group(2))
    depth_km = abs(float(m.group(3))) / 1000.0 if m.group(3) else None
    return lat, lon, depth_km
Enter fullscreen mode Exit fullscreen mode

Note abs(): the value is metres with an upward-positive sign, so -80000 becomes 80.0 km.

Other traps

Intensity is a string, and it goes past 7. JMA intensity (震度) is maxi: "1" … "7", but the scale also includes "5-", "5+", "6-", "6+". If you treat it as an integer you will silently drop the strongest quakes. Sort it against an explicit ordering, not numerically.

Entries without intensity are overseas. Quakes outside Japan's observation network have no maxi. Filtering them out is usually what you want for domestic monitoring.

mag is missing on some records. Coerce defensively — float(q.get("mag") or 0) — rather than assuming it is always present.

Using it

Rather than reimplement this every time, the parsing lives in a free MCP server. Calling japan_earthquakes(min_magnitude=3.0, limit=3) returns this (real output):

{
  "retrieved_at": "2026-10-12T12:12:00+00:00",
  "sources": ["https://www.jma.go.jp/bosai/quake/data/list.json"],
  "data_gaps": [],
  "data": [
    {"time": "2026-10-12T20:33:00+09:00", "epicenter": "釧路地方中南部",
     "max_intensity": "1", "magnitude": 3.3, "depth_km": 80.0,
     "latitude": 43.2, "longitude": 144.8},
    {"time": "2026-10-12T12:45:00+09:00", "epicenter": "釧路沖",
     "max_intensity": "2", "magnitude": 4.0, "depth_km": 70.0,
     "latitude": 42.5, "longitude": 144.3},
    {"time": "2026-10-12T09:53:00+09:00", "epicenter": "硫黄島近海",
     "max_intensity": "1", "magnitude": 5.0, "depth_km": 180.0,
     "latitude": 25.5, "longitude": 140.8}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Every response carries sources (the upstream URL) and data_gaps (anything that failed to fetch) so a downstream agent can tell whether it is looking at complete data. Failures are surfaced, never silently dropped.

The other 7 tools

Same server, same contract — free, keyless:

Tool What it returns Source
japan_earthquakes Quakes: epicenter, magnitude, intensity, depth, coordinates JMA
japan_weather_warnings Active warnings/advisories by prefecture JMA
japan_weather_overview Narrative weather summary JMA
japan_weekly_forecast 7-day high/low temps, precipitation %, reliability JMA
japan_typhoons Active typhoon tracking JMA
japan_edinet_filings Statutory corporate disclosures EDINET
japan_postal_lookup Postal code → address (kanji and kana) zipcloud
japan_watch_summary One-call cross-source summary JMA

Install

pip install -e .
japan-intel-mcp          # stdio MCP server
Enter fullscreen mode Exit fullscreen mode
{
  "mcpServers": {
    "japan-intel-mcp": {"command": "japan-intel-mcp"}
  }
}
Enter fullscreen mode Exit fullscreen mode

Source: github.com/atushi1841/japan-intel-mcp · Official MCP registry: io.github.atushi1841/japan-intel-mcp

If you are monitoring Japan for logistics, insurance, travel, or just want an agent that knows when the ground moved, this keeps you off scraped HTML and off the wrong agency's data.


Data used in this post

The datasets behind this analysis are available on Apify (pay-per-result, free tier to start):

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.