oyama-opendata-mcp
# oyama-opendata-mcp
小山市オープンデータを **読取専用** で提供する MCP(Model Context Protocol)サーバ。
Code for Oyama プロジェクト。
ユーザーは Claude などの AI クライアントからこの MCP に接続し、
「小山市の人口推移をグラフ化して」のような依頼で公開データを活用できます。
MCP 側は構造化データ(JSON)を返すだけで、可視化・分析は AI クライアント側が行います。
## 公開エンドポイント(稼働中)
**https://mcps.code4oyama.org/opendata/**
Claude(デスクトップ/web)の**カスタムコネクタ**に上記URLを登録すれば、誰でも利用できます。
公開版の実装とデプロイ手順は [php/README.md](php/README.md) を参照(さくらのレンタルサーバ + PHP)。
ローカルで stdio 接続する場合は下記セットアップを参照。
## 提供ツール(すべて参照系・書込み不可)
| ツール | 説明 |
| --- | --- |
| `list_datasets` | 提供中のデータセット一覧(収録月・行数を含む) |
| `list_areas` | 絞り込みに使える地区名・地域名(大字町丁)の一覧 |
| `get_population` | 大字町丁別の総人口・男女別人口・世帯数(月次)。`fromYearMonth`/`toYearMonth`・`district`・`area` で絞り込み、`level`(area/district/city) で集計粒度を選択 |
| `get_age_distribution` | 5歳階級×男女別の年齢構成(人口ピラミッド用)。`yearMonth`(未指定で最新月)・`district`(未指定で市全体合算) |
| `get_metadata` | 出典・ライセンス(CC BY)・帰属表示・収録月 |
データセットは2種類:
- **population** … 大字町丁別の人口・世帯数(月次・2015〜2026の約2.5万行)
- **population_by_age** … 地区別の5歳階級×男女の年齢構成(人口ピラミッド)
データ粒度は **月次 × 大字町丁別**。`level: "city"` で市全体の人口推移、`level: "district"` で地区別、既定の `area` で町丁別の時系列が得られる。
## セットアップ
```bash
npm install
npm run build
```
### ローカル利用(stdio)
Claude Desktop などの設定例:
```json
{
"mcpServers": {
"oyama-opendata": {
"command": "node",
"args": ["/絶対パス/oyama-opendata-mcp/dist/stdio.js"]
}
}
}
```
開発時は `npm run dev`。
### リモート公開(Streamable HTTP)
```bash
npm run start:http # http://localhost:3000/mcp (PORT で変更可)
```
ステートレス構成なので Cloudflare Workers / Render / Fly.io などに載せやすく、
利用者はエンドポイント URL を登録するだけで使えます。
## データ更新(取り込み時に統合)
月次CSVは1ファイル1か月。これを取り込み時に1つの正規化JSON(`data/population.json`)へ畳み込む。
現在 **2015-01〜2026-06 の137か月・約2.5万行** を収録。
1. 小山市オープンデータ(人口・世帯 → 大字町丁名別世帯数人口統計)から月次CSVをダウンロード
2. `data/raw/` に置く(複数月まとめてOK)
3. 統合を実行:
```bash
npm run update-data
```
`data/raw/*.csv` を全部読み、単一の時系列JSONを再生成する。年代によりフォーマットが
混在するため、取り込み時に自動判別する:
- **エンコーディング**: UTF-8 / Shift-JIS を自動判定
- **スキーマ**: 標準系(`地区名,地域名,総人口,男性,女性,世帯数`/年月はファイル名)と
旧系(`基準年月日,行政区コード,大字町丁名,合計,男,女,世帯数`/年月は基準年月日列、地区名なし)を吸収
- **桁区切り**: `"1,399"` のような引用符付き数値にも対応
- **年齢別ファイル**(5歳階級×男女)は別スキーマのため取り込み時にスキップ(ログ出力)
> 注: 旧系ファイルには地区名(district)が無いため、2022年以前の行は `level: "district"`
> 集計に含まれない。`level: "city"`(市全体)と `area`(町丁別)は全期間で利用可能。
## ライセンス・出典
- コード: MIT
- データ: 小山市オープンデータ(CC BY 4.0)。出典表示「出典:小山市オープンデータ」
- ポータル: https://www.city.oyama.tochigi.jp/opendata.php
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: get_age_distribution returns age pyramids, get_population returns population counts, get_metadata returns source information, list_areas returns filtering options, and list_datasets returns available datasets. No overlap in functionality.
All tool names follow a consistent verb_noun pattern using underscores: get_* for data retrieval and list_* for enumerations. The naming is predictable and readable.
With 5 tools, the set is well-scoped for an open data MCP focused on population demographics. Each tool serves a necessary role without redundancy or unnecessary complexity.
The tool surface covers core operations: listing datasets and areas, retrieving age distribution and population data, and accessing metadata. Minor gaps exist (e.g., no direct tool for household composition), but the main query needs are addressed.