Skip to main content
Glama
code4nerima

nerima-open-data-mcp

by code4nerima

nerima-open-data-mcp

東京都練馬区のオープンデータをAIクライアントから検索しやすくするMCPサーバーです。Claude、Cursor、ChatGPT系クライアントなどから、練馬区の公共施設、AED設置箇所、避難所・防災関連施設、公園、行政手続情報、ごみ・資源収集曜日、新着情報を検索できるようにします。

Tools

search_nerima

練馬区について広く検索する入口toolです。公共施設、AED、避難所、公園、ごみ・資源収集曜日、公式ニュース、オープンデータのデータセット候補をまとめて検索します。ChatGPTなどのAIクライアントで、ユーザーが「練馬区」「練馬」「区役所」「施設」「防災」「ごみの日」「行政手続」「文化財」「人口」「オープンデータ」などについて質問したとき、まず候補にしやすいtoolです。

引数:

  • keyword?: string

  • area?: string

  • category?: string

  • includeOpenDataRows?: boolean

  • limit?: number

search_facilities

練馬区オープンデータの「公共施設一覧」を検索します。区役所、図書館、地域集会所、区民館、体育館、文化施設、住所、電話番号、施設分類を調べる質問に向いています。

引数:

  • keyword?: string

  • category?: string

  • area?: string

  • limit?: number

search_aed

練馬区オープンデータの「AED設置箇所一覧」を検索します。AED、救命設備、設置施設、住所、地域、公共施設内のAEDを探す質問に向いています。

引数:

  • keyword?: string

  • area?: string

  • limit?: number

search_shelters

練馬区オープンデータの「指定緊急避難場所一覧」「避難拠点」を検索します。避難所、避難場所、防災、地震、火災、洪水、災害時の行き先を探す質問に向いています。

引数:

  • keyword?: string

  • area?: string

  • limit?: number

list_shelters

避難所・防災関連施設を一覧表示します。収容人数順や名称順で並び替えできます。

引数:

  • area?: string

  • disasterType?: string

  • sortBy?: "name" | "capacity"

  • sortOrder?: "asc" | "desc"

  • limit?: number

search_parks

公園を検索します。初期版では、公共施設一覧から公園相当データを抽出したJSONを使います。

引数:

  • keyword?: string

  • area?: string

  • limit?: number

search_open_data

練馬区オープンデータサイトから取り込んだ全CSVを横断検索します。公共施設一覧、AED設置箇所一覧、行政手続情報、人口統計、文化財、防災、子育て、教育、産業、まちづくりなど、専用toolがないデータセットを広く調べる質問に向いています。

引数:

  • keyword?: string

  • category?: string

  • dataset?: string

  • limit?: number

search_open_data_datasets

練馬区オープンデータサイトから取り込んだデータセット一覧を検索します。練馬について調べるときに、人口、施設、防災、子育て、教育、文化財、行政手続、産業、まちづくりなど、どのデータセットが存在するか探す質問に向いています。

引数:

  • keyword?: string

  • category?: string

  • sortBy?: "title" | "rowCount" | "updatedAt"

  • sortOrder?: "asc" | "desc"

  • limit?: number

list_open_data_datasets

練馬区オープンデータサイトから取り込んだデータセット一覧を表示します。利用可能なデータ、カテゴリ別のデータ、行数が多いデータ、更新されたデータを把握したい質問に向いています。

引数:

  • category?: string

  • sortBy?: "title" | "rowCount" | "updatedAt"

  • sortOrder?: "asc" | "desc"

  • limit?: number

get_open_data_rows

練馬区オープンデータの指定データセットからCSV行をページング取得します。search_open_data は本文検索用ですが、このtoolは「世帯と人口(総括表)」の過去月分、人口推移、統計時系列、文化財一覧など、検索語に依存せずデータセット全体を分析したい質問に向いています。

引数:

  • dataset: string

  • fileTitle?: string

  • fileIndex?: number

  • offset?: number

  • limit?: number

例:

  • get_open_data_rows(dataset="世帯と人口(総括表)", limit=1000)

  • nextOffset が返った場合は offset に指定して続きの行を取得します。

search_news

練馬区公式サイトの新着情報RSSを検索します。

引数:

  • keyword?: string

  • category?: string

  • from?: string

  • to?: string

  • limit?: number

list_recent_news

練馬区公式サイトの新着情報RSSを新しい順に一覧表示します。

引数:

  • category?: string

  • from?: string

  • to?: string

  • limit?: number

search_garbage_collection

練馬区公式サイトの「地域別収集曜日一覧」を検索します。ごみの日、可燃ごみ、不燃ごみ、容器包装プラスチック、古紙、びん、缶、ペットボトル、町名、丁目、収集カレンダーPDFを調べる質問に向いています。

引数:

  • keyword?: string

  • town?: string

  • district?: string

  • day?: string

  • wasteType?: string

  • limit?: number

search_procedures

練馬区オープンデータの「行政手続情報」を検索します。申請、届出、証明書、相談、必要書類、担当課、担当係、窓口、場所、電話番号、電子申請URLを調べる質問に向いています。

引数:

  • keyword?: string

  • department?: string

  • location?: string

  • hasOnlineApplication?: boolean

  • limit?: number

search_service_counters

練馬区オープンデータの「行政手続情報」から、場所・担当課・担当係・電話番号ごとに手続き窓口候補を検索します。どこで申請するか、証明書や相談の窓口、担当窓口、本庁舎や石神井庁舎の窓口を調べる質問に向いています。

引数:

  • keyword?: string

  • department?: string

  • location?: string

  • limit?: number

get_dataset_stats

GCSキャッシュと主要データセットの統計情報を返します。避難所については、指定緊急避難場所と避難拠点を合算した総件数、収容人数ありの件数、最大収容人数、収容人数上位10件を返します。

引数はありません。

Related MCP server: MLIT Data Platform MCP Server

ローカル起動

.env を編集して、GCSを使う場合は GCS_BUCKET とGoogle Cloudのサービスアカウント認証情報を設定してください。GCS未設定の場合は、少数サンプルデータで起動します。

サービスアカウントJSONはBase64化して GOOGLE_APPLICATION_CREDENTIALS_BASE64 に設定する方法を推奨します。

base64 -i service-account.json | tr -d '\n'
npm install
npm run build
npm run dev

ヘルスチェック:

curl http://localhost:3000/health

MCP endpoint:

http://localhost:3000/mcp

キャッシュ状態:

curl http://localhost:3000/open-data/cache

Herokuデプロイ

Herokuでは Procfile のWebプロセスが npm start を実行します。

npm run build
heroku create
git push heroku main

Heroku上のMCP endpoint:

https://<your-app-name>.herokuapp.com/mcp

PORT はHerokuが設定するため、アプリケーション側では process.env.PORT || 3000 をlistenします。

Heroku Scheduler

Herokuのファイルシステムは永続ではないため、公式CSVから生成したキャッシュはGoogle Cloud Storageに保存します。SchedulerはWeb dynoの保護付きエンドポイントを呼び出し、公式CSVの再取得とGCSキャッシュ更新を行わせます。

設定する環境変数:

heroku config:set IMPORT_TOKEN=<long-random-token>
heroku config:set APP_BASE_URL=https://<your-app-name>.herokuapp.com
heroku config:set GCS_BUCKET=<bucket-name>
heroku config:set GCS_PREFIX=nerima-open-data/cache
heroku config:set GOOGLE_APPLICATION_CREDENTIALS_BASE64='<base64-encoded-service-account-json>'

GOOGLE_APPLICATION_CREDENTIALS_JSON も利用できますが、Heroku Config VarsではJSON内の改行やクォートが崩れやすいため、Base64形式を推奨します。両方を設定している場合は GOOGLE_APPLICATION_CREDENTIALS_JSON が優先されます。

Heroku Schedulerに登録するコマンド:

npm run scheduler:import

手元でGCSキャッシュを生成して動作確認する場合:

export GCS_BUCKET=<bucket-name>
export GCS_PREFIX=nerima-open-data/cache
export GOOGLE_APPLICATION_CREDENTIALS_BASE64='<base64-encoded-service-account-json>'
npm run build
npm run import:open-data

ローカルでGCSキャッシュを更新し、本番サーバーを再起動せずにメモリ内キャッシュだけクリアする場合:

npm run import:open-data -- --full --notify-production

通知先の既定値は https://nod-mcp.code4nerima.org/tasks/clear-cache です。別のURLや本番専用トークンを使う場合は次を設定します。

export PRODUCTION_APP_BASE_URL=https://nod-mcp.code4nerima.org
export PRODUCTION_IMPORT_TOKEN='<production-import-token>'

通常の npm run import:open-data は差分更新です。既存の catalog.json と新しいオープンデータ一覧を比較し、データセットID、タイトル、分類、最終更新日、ページURLが変わっていないデータセットは既存JSONを再利用します。全データセットを取り直したい場合は次を実行します。

npm run import:open-data -- --full

外部スケジューラーから直接呼ぶ場合:

curl -X POST \
  -H "Authorization: Bearer $IMPORT_TOKEN" \
  https://<your-app-name>.herokuapp.com/tasks/import-open-data

GCSキャッシュを別環境で更新した後、本番サーバーのメモリ内キャッシュだけをクリアする場合:

curl -X POST \
  -H "Authorization: Bearer $IMPORT_TOKEN" \
  https://nod-mcp.code4nerima.org/tasks/clear-cache

サーバー経由の通常インポートも差分更新です。フル更新したい場合はJSON bodyで forceRefresh を指定します。

curl -X POST \
  -H "Authorization: Bearer $IMPORT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"forceRefresh":true}' \
  https://<your-app-name>.herokuapp.com/tasks/import-open-data

データ

初期JSONの data/*.json はフォールバックです。通常はGoogle Cloud Storageに保存した公式CSVキャッシュを読み込みます。

公式CSVキャッシュは取得時点の生成物なので、Gitには含めません。Herokuのslugにも含めず、GCSに保存します。

インポート処理は、練馬区オープンデータサイトの「オープンデータ一覧(CSV)」とカテゴリページを起点に、CSV形式で公開されている各データセットページを巡回してページ内のCSVリンクを取得します。取得したCSVは行データを nerima-open-data/cache/dataset-files/*/*.json にチャンク保存し、データセット本体の nerima-open-data/cache/datasets/*.json にはメタデータとチャンク参照を保存します。最後に nerima-open-data/cache/catalog.json を更新します。差分更新では未変更データセットの既存JSONを再利用するため、毎回すべてのCSVを取得し直す必要はありません。

CSVチャンクは既定で5,000行単位です。CSVパースはストリーム処理なので、通常は検索時のGCS読み込み回数を減らすため大きめのchunkを推奨します。Herokuのメモリに余裕がない場合だけ小さくします。

heroku config:set CSV_CHUNK_ROW_COUNT=5000

検索時のchunk読み込みは既定で4並列です。GCSへの同時アクセスを抑えたい場合は小さく、検索速度を優先したい場合は大きくできます。

heroku config:set SEARCH_CHUNK_READ_CONCURRENCY=4

公式サイト取得時の一時的な接続断や 429 / 5xx は自動でリトライします。既定は3回、待機は1秒からの線形バックオフです。必要に応じて調整できます。

heroku config:set FETCH_RETRY_COUNT=5
heroku config:set FETCH_RETRY_DELAY_MS=2000

キャッシュ生成結果の例:

  • データセット数: 34

  • CSVファイル数: 531

  • 行数: 84,802

  • 生成JSONの合計サイズ目安: 約252MB

公式サイトの更新により、対象データセット数や行数は変わります。インポート時点の正確な件数は /open-data/cache または get_dataset_stats で確認してください。

専用toolは公式CSVキャッシュを優先し、キャッシュがない場合のみ data/*.json の少数サンプルにフォールバックします。GCSキャッシュは全件を一括ロードせず、manifestを起点に必要なデータセットだけ遅延読み込みします。

Herokuで起動時にGCSキャッシュがない場合だけ公式CSVを取得するには、次を設定します。

heroku config:set AUTO_IMPORT_ON_START=true

起動時取得は公式サイトへのアクセスとCSVパース、GCSアップロードが発生するため、起動時間が長くなります。通常運用ではHeroku Schedulerまたは外部スケジューラーから /tasks/import-open-data を呼び出して更新してください。

GCSに置くオブジェクト:

gs://<bucket>/nerima-open-data/cache/catalog.json
gs://<bucket>/nerima-open-data/cache/datasets/*.json
gs://<bucket>/nerima-open-data/cache/dataset-files/**/*.json
gs://<bucket>/nerima-open-data/cache/rss/news.json
gs://<bucket>/nerima-open-data/cache/garbage/collection-days.json

運用確認

MCP endpointはStreamable HTTPです。SSE方式の /sse は提供していません。

汎用URL:

https://<your-app-name>.herokuapp.com/mcp

このプロジェクトの運用URL:

https://nod-mcp.code4nerima.org/mcp

汎用URLでの疎通確認:

curl -X POST https://<your-app-name>.herokuapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  --data '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

運用URLでの疎通確認:

curl -X POST https://nod-mcp.code4nerima.org/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  --data '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

MCP tool実行時は、開始・完了・失敗と処理時間を標準出力へ出します。Herokuでは以下で確認できます。

heroku logs --tail

使用・参照する練馬区オープンデータ:

  • 練馬区オープンデータサイト

  • オープンデータ一覧

  • 公共施設一覧

  • AED設置箇所一覧

  • 指定緊急避難場所一覧

  • 避難拠点

  • 公園トイレ一覧

ライセンス・出典

本リポジトリの初期データは、練馬区オープンデータサイトで公開されているコンテンツを参考に、MCPサーバーの初期検証用に整形したものです。

出典:

練馬区オープンデータサイトで公開しているコンテンツは、特段の定めがあるものを除き、クリエイティブ・コモンズ・ライセンス表示4.0国際の下に提供されています。改変して利用する場合は、編集・加工等を行ったことを明記してください。

注意

AED・避難所・防災関連情報は命に関わる可能性があります。本サーバーの結果だけに依存せず、最新情報は必ず練馬区公式情報を確認してください。

初期版ではMCP endpointは認証なしで公開できますが、公開運用時はレート制限や監視を検討してください。キャッシュ更新エンドポイント /tasks/import-open-data/tasks/clear-cacheIMPORT_TOKEN が必要です。Herokuのファイルシステムは永続保存に使わないでください。

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/code4nerima/nerima-open-data-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server