Appearance
外部データ取込 MCP(Cursor)
min-repo / ana-slo のページ HTML を、管理画面を開かずに Cursor エージェント(取込 bot)から db2023 に取り込むための MCP です。WordPress の REST API data-import/v1 を、権限を絞った取込担当ユーザーのアプリケーションパスワードで呼びます。管理者アカウントは渡しません。
HTML の取得(ブラウザでページを開いて保存する作業)はこの MCP の範囲外です。保存済みの HTML ファイルのパスを渡します。
関連: Issue #3873 / 設計 API-005 外部データ取込 REST / ADM-011 min-repo HTML インポート / ADM-020 ana-slo データ取得 / ADM-035 権限管理画面
できること・できないこと
| 操作 | 取込担当ロール | 管理者 |
|---|---|---|
| HTML の検証と紐付け状況の確認(preview。DB に書かない) | できる | できる |
| 機種名の紐付け保存と db2023 への取込(既存データの削除込み) | できる | できる |
| ホールの db2023 最新日の確認 | できる | できる |
| 取込履歴の確認 | できる | できる |
| 日別記事・有料記事の編集、機種マスタの編集・削除 | できない | できる |
取込担当ロールは管理画面の「min-repo HTML インポート」「ana-slo データ取得」も開けます。ほかに開けるのはダッシュボードと自分のプロフィールだけです(WordPress の read / upload_files 権限の範囲)。min-repo と ana-slo の Capability は別なので、片方だけ任せることもできます。
運用手順(WordPress 側)
bot が叩く WordPress(通常は本番)で、管理者が次の作業をします。
1. 取込担当ユーザーを作る
- 管理画面 → ユーザー → 新規追加
- ユーザー名は用途が分かる名前にする(例:
data-import-bot)。メールアドレスは管理者が受け取れるものにする - 権限グループで「min-repo 取込担当」(
min_repo_importer)を選んで追加する
既存ユーザーに任せる場合は、そのユーザーの編集画面で権限グループを「min-repo 取込担当」に変えます。取込担当ロールの Capability は ADM-035 権限管理画面 の「外部データ取込」で確認・変更できます(既定は import_min_repo_html と import_ana_slo_html)。
2. アプリケーションパスワードを発行する
- 管理画面 → ユーザー → 取込担当ユーザーの編集画面
- 「アプリケーションパスワード」で名前(例:
cursor-data-import-tools)を入れて追加する - 表示されたパスワード(
xxxx xxxx xxxx xxxx xxxx xxxx)を控える。この画面を閉じると二度と表示されません
アプリケーションパスワードは HTTPS のサイトでのみ使えます(ローカルの HTTP では wp-config.php に define( 'WP_ENVIRONMENT_TYPE', 'local' ); が必要)。
3. 失効させる
bot をやめるときは、同じ画面で該当のアプリケーションパスワードを「取り消す」。
4. パスワードが漏れた疑いがあるとき
取り消しだけでは足りません。WordPress では本人のプロフィール編集(メールアドレス・ログインパスワードの変更)とアプリケーションパスワードの追加発行が read 権限でできるため、漏れた資格情報で取込担当ユーザーが乗っ取られている可能性があります。
- 取込担当ユーザーのアプリケーションパスワードをすべて取り消す
- メールアドレスを確認したうえでログインパスワードをリセットする。確実にするなら、取込担当ユーザーを削除して作り直す
- 管理画面「min-repo HTML インポート」の取込履歴(または
data_import_history)で、心当たりのない取込が無いか確認する。あれば該当の日付・ホールを正しい HTML で取り込み直す(delete_existing: true) - 必要ならサーバーの PHP エラーログで
[bot-rest-audit]の行を確認する(いつ・どのユーザーが・どの日付とホールに取り込んだかが残る)
管理者権限への昇格はできないため、影響は上の表の「取込担当ロール」の操作(db2023 の日別データ・機種名の紐付け)と、取込担当ユーザー自身のプロフィールに限られます。
設定(Cursor 側)
.cursor/mcp.json.exampleを.cursor/mcp.jsonにコピーする(.cursor/mcp.jsonは gitignore。パスワードをコミットしない)data-import-toolsのenvを書き換える
| 変数 | 必須 | 説明 |
|---|---|---|
WP_SITE_URL | はい | WordPress のサイト URL(例: https://example.com)。https:// 必須(http:// は localhost / 127.0.0.1 / [::1] / *.local / *.test のみ)。リダイレクトは追わないので、リダイレクト先の URL(www の有無も含む)を書く |
DATA_IMPORT_WP_USERNAME | はい | 取込担当ユーザーのユーザー名 |
DATA_IMPORT_WP_APP_PASSWORD | はい | 取込担当ユーザーのアプリケーションパスワード(スペース込みで可) |
有料記事用の .env.local(WP_USERNAME / WP_APP_PASSWORD)や新台情報担当 MCP(NEW_MACHINE_WP_*)とは別の変数名です。資格情報を混ぜないでください。
json
{
"mcpServers": {
"data-import-tools": {
"command": "node",
"args": ["scripts/mcp-data-import-tools.mjs"],
"env": {
"WP_SITE_URL": "https://example.com",
"DATA_IMPORT_WP_USERNAME": "data-import-bot",
"DATA_IMPORT_WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
}
}
}
}設定変更後は Cursor を再読み込みし、MCP data-import-tools が有効になっていることを確認します。リポジトリで npm install 済み(@modelcontextprotocol/sdk)であることが前提です。
利用可能な Tool
| MCP Tool name | 主な引数 | REST |
|---|---|---|
data_import_preview | source, html_file_path, date, hall, 任意 mappings, include_masters | POST /data-import/v1/{source}/preview |
data_import_execute | source, html_file_path, date, hall, 任意 mappings, delete_existing | POST /data-import/v1/{source}/import |
data_import_latest_day | source, hall | GET /data-import/v1/{source}/latest-day |
data_import_history | 任意 source, limit | GET /data-import/v1/history |
sourceはmin-repo(island/espasu)またはana-slo(island/espasu/bigapple)html_file_pathは拡張子が.html/.htm(大文字小文字は問わない)の通常ファイルに限る(ディレクトリ・シンボリックリンクは不可)。MCP 側で存在と 5MB 以下であることを確かめてから base64 にして送る(WAF が HTML 本文を弾くのを避けるため)mappingsは{ kishu_name, master_id }か{ kishu_name, new_name }の配列(500 件まで)
戻り値は REST のレスポンス JSON そのままです。HTTP エラー・通信失敗・設定不足・ファイル不備のときは isError: true で {"error":"...","status":422,"data":{...}} のように返します。入出力とエラー条件の正本は API-005 です。
bot の作業の流れ
data_import_latest_dayで次に取り込む日付(expected_next_day)を確認するdata_import_previewにinclude_masters: trueを付けて呼び、unmappedと機種マスタ候補を見る- 未紐付けの機種ごとに、候補に同じ機種があれば
master_id、なければnew_nameを決めてmappingsに入れ、ready_to_import: trueになるまでdata_import_previewを呼び直す - 同じ引数(
mappings込み)でdata_import_executeを呼ぶ。取り直しのときはdelete_existing: true - 迷う紐付け(似た名前の機種が複数ある等)は取り込まずに人間に報告する
HTTP 422 は未紐付けが残っている(data.unmapped)、409 は同じ日付・ホールの取込が実行中、429 はレート制限(取込は 1 分 10 回まで)、503 は DB エラーで取込ロックを取れなかったことを表します。409・429・503 は時間をおいて再実行します。
data_import_execute は 180 秒で応答を待つのをやめますが、サーバー側の取込は続き、ロック(最長 300 秒)も持ったままです。タイムアウト後は data_import_latest_day か data_import_history で取り込まれたかを確かめてから再実行してください。すぐ再実行すると 409 になります。
REST の例(curl)
MCP を使わずに動作確認するときの例です。
bash
SITE=https://example.com
AUTH='data-import-bot:xxxx xxxx xxxx xxxx xxxx xxxx'
# 最新日
curl -sS -u "$AUTH" "$SITE/wp-json/data-import/v1/min-repo/latest-day?hall=island"
# 紐付け状況の確認
B64=$(base64 < day.html | tr -d '\n')
curl -sS -u "$AUTH" -X POST "$SITE/wp-json/data-import/v1/min-repo/preview" \
-H 'Content-Type: application/json' \
-d "{\"html_base64\":\"$B64\",\"date\":\"2026-10-02\",\"hall\":\"island\",\"include_masters\":true}"
# 取込
curl -sS -u "$AUTH" -X POST "$SITE/wp-json/data-import/v1/min-repo/import" \
-H 'Content-Type: application/json' \
-d "{\"html_base64\":\"$B64\",\"date\":\"2026-10-02\",\"hall\":\"island\",\"mappings\":[{\"kishu_name\":\"スマスロ新機種\",\"new_name\":\"スマスロ新機種\"}]}"
# 取込履歴
curl -sS -u "$AUTH" "$SITE/wp-json/data-import/v1/history?limit=5"トラブルシューティング
| 症状 | 確認 |
|---|---|
WP_SITE_URL / DATA_IMPORT_WP_USERNAME / ... を設定 | .cursor/mcp.json の data-import-tools.env |
HTML ファイルが見つかりません / 大きすぎます | html_file_path(相対パスは MCP サーバーの作業ディレクトリ基準)。5MB を超える HTML は不要部分を削ってから渡す |
.html / .htm のファイルを指定してください / 通常のファイルではありません | 保存した HTML の拡張子を .html / .htm にする。シンボリックリンクではなく実ファイルのパスを渡す |
HTTP 401(incorrect_password / invalid_username) | ユーザー名・アプリケーションパスワードの誤り、取り消し済み、HTTP サイトでの利用 |
HTTP 403(rest_forbidden) | 未ログイン扱い(認証ヘッダーが PHP に届いていない)と権限不足のどちらも同じ応答になる。下の「403 の切り分け」を参照 |
| HTTP 400(HTML が取込元のページとして検証できない) | source と HTML の取り違え、data.errors の内容 |
リダイレクトされました | WP_SITE_URL を location の URL(https / www の有無)に合わせる |
HTTP 404(rest_no_route) | テーマが本機能を含むバージョンか。パーマリンク設定が「基本」だと /wp-json/ が使えない場合がある |
JSON 以外の応答 | WAF・メンテナンス画面・PHP エラー。body の先頭を確認 |
403 の切り分け
同じ資格情報で WordPress コアの /users/me を呼び、ログインできているかを確かめます。
bash
curl -sS -u "$AUTH" "$SITE/wp-json/wp/v2/users/me"- 401(
rest_not_logged_in): 認証ヘッダーが PHP に届いていない。HTTP サイトで使っていないか、Apache の CGI / FastCGI 構成なら.htaccessにSetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1等があるかを確認する - 200(取込担当ユーザーが返る): ログインはできている。権限グループが「min-repo 取込担当」か、ADM-035 で該当の取込 Capability が外されていないかを確認する
実装メモ
- 本体:
scripts/mcp-data-import-tools.mjs(テスト:npm run test:mcp-data-import。npm testにも含まれる) - 5MB の上限は
DailyDataHtmlImportConstants::MAX_HTML_LENGTH、mappingsの上限 500 件はDataImportRestController::MAX_MAPPING_ITEMSと同期する - 権限判定は REST 側(
import_min_repo_html/import_ana_slo_html)。MCP 側では権限を判定しない