Skip to main content
Glama
bitpackman

tokyo-opendata-mcp

by bitpackman
README.md
# tokyo-opendata-mcp

東京都オープンデータを **AI が正しく扱えるようにする MCP サーバー**。

単なる API プロキシではない。実データを調査して判明した「**AI が誤解する罠**」を、
ツールの応答に組み込んで返す。

## なぜ必要か

東京都は 9,642 データセット・71,451 の API を公開しているが、AI から見ると 3 つの壁がある。

| 壁 | 実測 | このMCPの対応 |
|---|---|---|
| **検索が同義語を吸収しない** | 「避難」で 96 件、「避難所」で 937 件(広い語ほど少ない逆転) | 表記ゆれを自動展開して並列に横断検索し統合 |
| **更新日が信用できない** | `metadata_modified=2025-12-12` が 9,642 件中 **7,118 件**(カタログ一括移行日) | 鮮度の誤認を警告し、本文から実際の基準日を抽出 |
| **API化=クレンジングではない** | 元CSVの空行がそのまま返る(先頭ページが空行のAPIも実在する) | 空行をスキップして要求件数まで読み進め、正確な `next_offset` を返す |

## ツール

| ツール | 説明 |
|---|---|
| `search_datasets` | 日常語で検索。行政用語への表記ゆれを自動展開 |
| `get_dataset` | 提供元・メンテナー・更新頻度・**鮮度の警告** |
| `query_dataset_api` | 実データの行を取得(空行スキップ+安全なページ送り) |
| `list_dataset_resources` | CSV/Excel リソース一覧 |

### 実際の応答例

```
$ get_dataset("t000003d0000000093")

title: 東京都防災マップ 避難所・避難場所一覧データ
maintainer: 東京都総務局総合防災部防災計画課 | 更新頻度: 不定期
metadata_modified: 2025-12-12T10:04:13

⚠️ warnings:
  - metadata_modified が 2025-12-12 ですが、これはカタログ全体の一括移行日です
    (全9,642件中7,118件が同日)。実データの鮮度ではありません。
  - 本文に基準日の記載があります:「令和3年4月1日基準」。これが実際のデータ基準日です。
```

更新日だけを見た AI は「2025年の最新データ」と誤認する。このMCPは**2021年基準であることを伝える**。

## 使い方

### ローカル(stdio)

```bash
npm install && npm run build
```

Claude Code / Claude Desktop の設定に追加する:

```json
{
  "mcpServers": {
    "tokyo-opendata": {
      "command": "node",
      "args": ["/absolute/path/to/tokyo-opendata-mcp/dist/stdio.js"]
    }
  }
}
```

### リモート(Cloudflare Workers)

同じツール定義を Streamable HTTP で公開できる。

```bash
npx wrangler deploy
```

エンドポイントは `https://<your-worker>.workers.dev/mcp`(ヘルスチェックは `/health`)。

## テスト

4層構成。層1〜3は fetch モックと `InMemoryTransport` によりネットワーク不要で、追加依存もない(`node:test` 標準ランナー)。

| 層 | 対象 | コマンド | ネットワーク |
|---|---|---|---|
| 1 | ロジック(同義語展開・空行スキップ・鮮度警告・リトライ) | `npm test` | 不要 |
| 2 | MCPプロトコル(ツール公開・zodバリデーション・isError) | `npm test` | 不要 |
| 3 | Remoteトランスポート(`worker.fetch` をインプロセス直呼び) | `npm test` | 不要 |
| 4 | 実データE2E(都のAPIに対する assert 付き検証) | `npm run test:live` | 必要 |

検証している主な罠:

- 空行がページ境界をまたいでも要求件数まで読み進める/全ページ空行でも `MAX_PAGES` で必ず停止する
- `next_offset` によるページ送りで行の重複・読み飛ばしが起きない
- 5xx は1回だけリトライし、4xx はリトライしない
- 検索変種の一部失敗は握りつぶさず note で通知される
- バリデーション違反(`-32602`)はツールハンドラ実行前に拒否される

## 構成

```
src/
  tokyo.ts   東京都APIアクセス層(fetchのみ。Node/Workers 両対応)
  tools.ts   MCPツール定義(stdio と Remote で共有)
  stdio.ts   ローカル用エントリ
  worker.ts  Cloudflare Workers 用エントリ
test/
  smoke.mjs  実データに対するE2Eテスト
```

## 関連

- 索引データ: [tokyo-opendata-api-index](https://github.com/JYFULL/tokyo-opendata-api-index) — 5,611データセットの項目定義(CC BY 4.0)
- 東京都オープンデータカタログ: https://catalog.data.metro.tokyo.lg.jp/

## ライセンス

MIT(コード)。取得されるデータは東京都オープンデータカタログの CC BY 4.0 に従う。
出典表示が必要である — 出典:東京都オープンデータカタログサイト

本リポジトリは東京都とは無関係の第三者による非公式なものである。

TDQS

A4.3/5.0

Scored across 3 tools

Disambiguation5/5

Each tool serves a distinct purpose: searching datasets, retrieving dataset metadata, and listing resources within a dataset. There is no overlap.

Naming Consistency5/5

All tools use a consistent snake_case verb_noun pattern (search_datasets, get_dataset, list_dataset_resources), making their actions predictable.

Tool Count5/5

Three tools are well-scoped for a focused server on Tokyo open data metadata. Each tool adds clear value without redundancy.

Completeness4/5

The tool set covers search, metadata retrieval, and resource listing, but lacks a direct tool to download or query the actual data files, relying on hints instead.

Maintenance

ActivitySlowing
ResponsivenessNo issues