Appearance
新台情報担当 MCP(Cursor)
新台情報の取得と、未紐付け機種の機種マスタへの紐付けを、管理画面を開かずに Cursor エージェント(新台情報担当 bot)から行うための MCP です。WordPress の REST API new-machine/v1 を、権限を絞った担当ユーザーのアプリケーションパスワードで呼びます。管理者アカウントは渡しません。
関連: Issue #3869 / 設計 API-003 新台情報 REST / ADM-035 権限管理画面
できること・できないこと
| 操作 | 担当ロール | 管理者 |
|---|---|---|
| 最新の新台情報を取得(クールダウン中はスキップ) | できる | できる |
| 過去 1 ヶ月・過去月の取得、クールダウン無視の取得 | できない | できる |
| 一覧の取得(未紐付け / 全件、機種マスタ候補つき) | できる | できる |
| 既存の機種マスタへの紐付け | できる | できる |
| 新しい名前での紐付け(同名が未登録なら新規登録) | できる | できる |
| 表示・非表示の切替 | できる | できる |
担当ロールは管理画面の「新台情報取得」「未紐付け機種の紐付け」も開けます。ほかに開けるのはダッシュボードと自分のプロフィールだけです(WordPress の read 権限の範囲)。
運用手順(WordPress 側)
bot が叩く WordPress(通常は本番)で、管理者が次の作業をします。
1. 担当ユーザーを作る
- 管理画面 → ユーザー → 新規追加
- ユーザー名は用途が分かる名前にする(例:
new-machine-bot)。メールアドレスは管理者が受け取れるものにする - 権限グループで「新台情報担当」を選んで追加する
既存ユーザーに任せる場合は、そのユーザーの編集画面で権限グループを「新台情報担当」に変えます。担当ロールの Capability は ADM-035 権限管理画面 で確認・変更できます(既定は「新台情報の取得・紐付け」のみ)。
2. アプリケーションパスワードを発行する
- 管理画面 → ユーザー → 担当ユーザーの編集画面
- 「アプリケーションパスワード」で名前(例:
cursor-new-machine-tools)を入れて追加する - 表示されたパスワード(
xxxx xxxx xxxx xxxx xxxx xxxx)を控える。この画面を閉じると二度と表示されません
アプリケーションパスワードは HTTPS のサイトでのみ使えます(ローカルの HTTP では wp-config.php に define( 'WP_ENVIRONMENT_TYPE', 'local' ); が必要)。
3. 失効させる
bot をやめるときは、同じ画面で該当のアプリケーションパスワードを「取り消す」。
パスワードが漏れた疑いがあるときは、取り消しだけでは足りません。WordPress では本人のプロフィール編集(メールアドレス・ログインパスワードの変更)とアプリケーションパスワードの追加発行が read 権限でできるため、漏れた資格情報で担当ユーザーが乗っ取られている可能性があります。次のどちらかを行ってください。
- アプリケーションパスワードをすべて取り消し、メールアドレスを確認したうえでログインパスワードをリセットする
- 担当ユーザーを削除して作り直す(確実)
管理者権限への昇格はできないため、影響は上の表の「担当ロール」の操作と、担当ユーザー自身のプロフィールに限られます。
取得・紐付け・表示切替の操作は監査ログ(サーバーの PHP エラーログの [bot-rest-audit] の new-machine/v1/... の行)に、いつ・どのユーザーが・どの取得モードで取得したか、何件紐付けたか、どの行の表示を切り替えたかが残ります。漏えいが疑われるときはこのログで操作を確認してください(機種名や取得ログの本文は残りません)。
設定(Cursor 側)
.cursor/mcp.json.exampleを.cursor/mcp.jsonにコピーする(.cursor/mcp.jsonは gitignore。パスワードをコミットしない)new-machine-toolsのenvを書き換える
| 変数 | 必須 | 説明 |
|---|---|---|
WP_SITE_URL | はい | WordPress のサイト URL(例: https://example.com)。https:// 必須(http:// は localhost / 127.0.0.1 / [::1] / *.local / *.test のみ)。リダイレクトは追わないので、リダイレクト先の URL(www の有無も含む)を書く |
NEW_MACHINE_WP_USERNAME | はい | 担当ユーザーのユーザー名 |
NEW_MACHINE_WP_APP_PASSWORD | はい | 担当ユーザーのアプリケーションパスワード(スペース込みで可) |
有料記事用の .env.local(WP_USERNAME / WP_APP_PASSWORD)とは別の変数名です。管理者の資格情報と混ぜないでください。
json
{
"mcpServers": {
"new-machine-tools": {
"command": "node",
"args": ["scripts/mcp-new-machine-tools.mjs"],
"env": {
"WP_SITE_URL": "https://example.com",
"NEW_MACHINE_WP_USERNAME": "new-machine-bot",
"NEW_MACHINE_WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
}
}
}
}設定変更後は Cursor を再読み込みし、MCP new-machine-tools が有効になっていることを確認します。リポジトリで npm install 済み(@modelcontextprotocol/sdk)であることが前提です。
利用可能な Tool
| MCP Tool name | 主な引数 | REST |
|---|---|---|
new_machine_fetch | 任意 mode(latest / last_month / past_month)等 | POST /new-machine/v1/fetch |
new_machine_list | 任意 filter(unlinked / all)、include_masters | GET /new-machine/v1/items |
new_machine_save_links | items(1〜200 件) | POST /new-machine/v1/links |
new_machine_set_visibility | id, is_hidden | POST /new-machine/v1/visibility |
戻り値は REST のレスポンス JSON そのままです。HTTP エラー・通信失敗・設定不足のときは isError: true で {"error":"...","status":403,"data":{...}} のように返します。入出力とエラー条件の正本は API-003 です。
bot の作業の流れ
new_machine_fetch(引数なし)で最新の新台情報を取り込む。result.skipped_sitesにサイトが入っていればクールダウン中なので、時間をおいて再実行するnew_machine_listにinclude_masters: trueを付けて未紐付けの行と機種マスタ候補を取る- 候補に同じ機種があれば
mode: "existing"とkishu_id、なければmode: "new"とnew_nameでnew_machine_save_linksを呼ぶ - 紐付け不要な行(パチンコ等)は
new_machine_set_visibilityで非表示にする new_machine_save_linksのrowsでstatus: "error"の行を確認し、必要なら人間に報告する
new_machine_fetch は取得元サイトの読み込みを含むため時間がかかります(MCP 側の待ち時間は最大 3 分)。Cursor 側が先にタイムアウトしても、WordPress 側では取得が最後まで進み、クールダウンも始まっていることがあります。すぐに再実行せず、new_machine_list で取り込まれた行を確認するか、管理画面「新台情報取得」の最終実行結果を見てください。
REST の例(curl)
MCP を使わずに動作確認するときの例です。
bash
SITE=https://example.com
AUTH='new-machine-bot:xxxx xxxx xxxx xxxx xxxx xxxx'
# 最新の新台情報を取得
curl -sS -u "$AUTH" -X POST "$SITE/wp-json/new-machine/v1/fetch" \
-H 'Content-Type: application/json' -d '{}'
# 未紐付けの一覧と機種マスタ候補
curl -sS -u "$AUTH" "$SITE/wp-json/new-machine/v1/items?include_masters=true"
# 紐付けを保存
curl -sS -u "$AUTH" -X POST "$SITE/wp-json/new-machine/v1/links" \
-H 'Content-Type: application/json' \
-d '{"items":[{"new_machine_id":12,"mode":"existing","kishu_id":345},{"new_machine_id":13,"mode":"new","new_name":"スマスロ新機種"}]}'
# 非表示にする
curl -sS -u "$AUTH" -X POST "$SITE/wp-json/new-machine/v1/visibility" \
-H 'Content-Type: application/json' -d '{"id":14,"is_hidden":true}'/links のレスポンス例:
json
{
"success": true,
"has_errors": false,
"counts": { "updated": 2, "unchanged": 0, "error": 0 },
"rows": [
{
"new_machine_id": 12,
"machine_name": "スマスロ〇〇",
"status": "updated",
"message": "",
"kishu_id": 345,
"kishu_name": "スマスロ〇〇",
"kishu_inactive": false
}
]
}トラブルシューティング
| 症状 | 確認 |
|---|---|
WP_SITE_URL / NEW_MACHINE_WP_USERNAME / ... を設定 | .cursor/mcp.json の new-machine-tools.env |
HTTP 401(incorrect_password / invalid_username) | ユーザー名・アプリケーションパスワードの誤り、取り消し済み、HTTP サイトでの利用 |
HTTP 403(rest_forbidden、権限がありません) | 未ログイン扱い(認証ヘッダーが PHP に届いていない)と権限不足のどちらも同じ応答になる。下の「403 の切り分け」を参照 |
リダイレクトされました | WP_SITE_URL を location の URL(https / www の有無)に合わせる |
| HTTP 403(過去データの取得は…管理者のみ) | 担当ロールでは mode を省略(latest)する |
| HTTP 429(リクエストが多すぎます) | ユーザー単位のレート制限(一覧 1 分 120 回、紐付け・表示切替 1 分 20 回、取得 1 時間 20 回)。入力エラー(400・403)で返った呼び出しも回数に含まれる。時間をおいて再実行する。詳細は API-003 |
HTTP 404(rest_no_route) | テーマが PR #3870 以降か。パーマリンク設定が「基本」だと /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(担当ユーザーが返る): ログインはできている。担当ユーザーの権限グループが「新台情報担当」か、ADM-035 で「新台情報の取得・紐付け」が外されていないかを確認する
実装メモ
- 本体:
scripts/mcp-new-machine-tools.mjs(テスト:npm run test:mcp-new-machine。npm testにも含まれる) itemsの上限 200 件はNewMachineRestController::MAX_LINK_ITEMSと同期する- 権限判定は REST 側(
manage_new_machine_info)。MCP 側では権限を判定しない