quake-lens MCP server
by kenimo49
README.md
# quake-lens

[](LICENSE)
[](pyproject.toml)
[-1E3A5F.svg)](pyproject.toml)
公開地震データの取得と統計分析を行うCLI + MCPサーバ。地震の「予知」はできないが、「予測(forecasting)」として科学的に成立している統計量 — b値、大森・宇津則による余震減衰 — を公開APIのカタログから計算する。
Earthquake statistics CLI & MCP server in pure-stdlib Python: Gutenberg-Richter b-value (Aki MLE) and Omori-Utsu aftershock decay (Ogata MLE) from public catalogs (JMA / P2P / USGS).
> 📖 解説記事: [地震予知はなぜ無理で、余震予測はなぜできるのか — 能登の余震130件で実測](https://kenimoto.dev/ja/blog/jishin-yochi-vs-yoshin-yosoku-jissoku/)
## Status
v1 実装済み: `recent`(P2P / JMA) / `catalog`(USGS) / `bvalue` / `omori` + MCPサーバ(4 tools)
## Install / run
```bash
git clone https://github.com/kenimo49/quake-lens.git
cd quake-lens
python3 -m quake_lens --help # インストール不要でそのまま動く
# pip install する場合
pip install . # CLI のみ
pip install ".[mcp]" # MCPサーバ込み
quake-lens --help
```
ランタイム依存は Python 標準ライブラリのみ(`urllib` / `json` / `math` / `datetime` / `argparse`)。
## Subcommands
### `recent` — 直近の地震リスト (P2P地震情報 / 気象庁)
```bash
python3 -m quake_lens recent --limit 5 --min-scale 30
python3 -m quake_lens recent --limit 5 --src jma
```
出力(table形式):
```
time lat lon depth mag src place
2024-01-01T07:10:00Z 37.500 137.300 10.0 7.6 p2p 石川県能登地方
2024-01-01T07:12:00Z 37.400 137.200 10.0 5.8 p2p 石川県能登地方
```
`--format json` で正規化イベントJSONを出力。
`--src` で取得元を選べる(default: `p2p`)。`jma` は気象庁の地震リスト
(list.json) を直接取得する。同一地震の続報は最新の1件に集約される。
`--min-scale` はP2Pのscale値前提のフィルタなので `--src p2p` 専用
(`jma` と併用するとエラー)。
### `catalog` — USGSカタログ取得
```bash
python3 -m quake_lens catalog \
--start 2024-01-01 --end 2024-01-02 \
--min-mag 5.0 --bbox 24,122,46,146 \
--format json
```
出力(json形式):
```json
[
{
"time": "2024-01-01T09:10:00Z",
"lat": 37.5,
"lon": 137.3,
"depth_km": 10.0,
"mag": 7.6,
"place": "Noto Peninsula, Japan",
"source": "usgs"
}
]
```
`--bbox` のデフォルトは日本周辺 `24,122,46,146`。
### `bvalue` — Gutenberg-Richter b値推定 (Aki MLE)
正規化イベントJSON(ファイル or stdin)から b値を推定:
```bash
python3 -m quake_lens catalog --min-mag 2.0 --format json > events.json
python3 -m quake_lens bvalue events.json --mc 2.5
```
出力:
```
b = 0.9873
se = 0.0139
n_used = 5024
mc = 2.50
mean_m = 2.990
```
stdin 経由:
```bash
cat events.json | python3 -m quake_lens bvalue - --mc 2.5 --format json
```
`--mc` は completeness magnitude(必須)。`M < Mc` のイベントは除外される。SE は Aki (1965) 近似 `b / √N`。
### `omori` — 修正大森・宇津則フィット (Ogata MLE)
余震系列に対して `λ(t) = K / (t + c)^p` をフィット:
```bash
python3 -m quake_lens omori aftershocks.json \
--mainshock 2024-01-01T07:10:00Z
```
出力:
```
K = 152.7413
c = 0.0219
p = 1.0834
logL = -234.5610
n_used = 812
window = [0.0000, 10.5432] days
```
最適化は pure Python の Nelder-Mead(外部ライブラリなし)。
出力フィールド(`b` / `se` / `mc` / `K` / `c` / `p` / `logL` など)の意味は [docs/glossary.md](docs/glossary.md) を、尤度計算の中身(Aki MLE / Ogata MLE の導出と最適化手順)は [docs/likelihood.md](docs/likelihood.md) を参照。
## MCP server
LLMクライアント(Claude Code / Claude Desktop 等)向けに、4 tools
(`get_recent` / `get_catalog` / `estimate_bvalue` / `fit_omori`)を公開する
MCPサーバを同梱している。mcp SDK は optional dependency で、base install の
stdlib-only は維持される:
```bash
pip install "quake-lens[mcp]"
claude mcp add quake-lens -- quake-lens-mcp
```
設計判断(optional依存、tool分離、統計toolがイベント配列を引数に取らない理由)は
[docs/mcp.md](docs/mcp.md) を参照。
## ドキュメント
| ドキュメント | 内容 |
|-------------|------|
| [docs/glossary.md](docs/glossary.md) | 出力フィールドの読み方(b値・Mc・K/c/p の意味) |
| [docs/likelihood.md](docs/likelihood.md) | 尤度計算の導出(Aki MLE / Ogata MLE・プロファイル尤度・最適化手順) |
| [docs/mcp.md](docs/mcp.md) | MCPサーバの設計判断と Claude Code / Claude Desktop への登録手順 |
## Data sources
- [P2P地震情報 API](https://www.p2pquake.net/develop/json_api_v2/) — 気象庁情報のリレー、認証不要
- [気象庁 地震リスト list.json](https://www.jma.go.jp/bosai/quake/data/list.json) — 気象庁の一次ソース、認証不要
- [USGS Earthquake Catalog API](https://earthquake.usgs.gov/fdsnws/event/1/)
## Design principles
- ランタイム依存は標準ライブラリのみ
- HTTP取得は `quake_lens/sources/` に隔離、fetch関数は注入可能(テストではfixture JSONを注入)
- 統計計算 `quake_lens/stats/` は純関数(ネットワーク・IOなし)
- テストは fixture ベースで決定的(実APIを叩かない)
## Normalized event schema
全ソースはこの形に正規化される:
```json
{
"time": "2024-01-01T07:10:00Z",
"lat": 37.5,
"lon": 137.3,
"depth_km": 10.0,
"mag": 7.6,
"place": "石川県能登地方",
"source": "p2p"
}
```
`source` は `"p2p"`, `"usgs"`, `"jma"` のいずれか。
## Tests
```bash
python3 -m pytest -q
```
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessResponsive