Skip to content

X告知担当 MCP(Cursor) ​

公開済みの日別記事・有料記事を X で告知するとき、告知に使う記事のメタ情報(URL・タイトル・考察日・号数・アイキャッチ URL・告知履歴)を読み、X に投稿した結果を記事に記録するための MCP です。WordPress の REST API x-announce/v1 を、X告知担当ロールのユーザーのアプリケーションパスワードで呼びます。編集用・取込用・運用確認用・管理者のアカウントは渡しません。

関連: Issue #3885 / 設計 API-007 X告知 REST / ADM-035 権限管理画面

できること・できないこと ​

操作X告知担当
公開済み日別記事のメタ情報(URL・タイトル・考察日・公開/更新日時・アイキャッチ URL)と告知履歴できる
公開済み有料記事のメタ情報(URL・タイトル・号数・対象月・無料公開フラグ・公開/更新日時・アイキャッチ URL)と告知履歴できる
X に投稿した結果(tweet_id・投稿日時・種類)を記事の告知履歴に記録するできる
記事の本文・考察欄・抜粋・有料記事の冒頭挨拶やセクションの取得できない
下書き・予約・非公開の記事の取得できない
告知履歴の記録以外の書き込み(記事・取込・新台情報・自分のプロフィールやアプリケーションパスワードの変更を含む。アプリケーションパスワード経由の REST・XML-RPC と wp-admin)できない
wp-admin を開く(ダッシュボード・記事一覧・プロフィールを含む)できない
X への投稿できない

告知文の要約は各記事の編集 bot が作ります。X告知担当は本文を読まず、編集 bot から受け取った要約と、この MCP で取ったメタ情報で告知文を組み立てます。

X告知担当ロール(x_announcer)が持つのは WordPress の read と read_x_announce・record_x_announcement だけです。wp-admin を開くとサイトトップへリダイレクトされます。

WordPress は read だけのユーザーにも自分のプロフィール編集とアプリケーションパスワードの発行を許すため、x_announcer を持ち、他には REST 用 bot ロール(ops_status_reader / birthday_linker)しか持たないユーザーには BotWriteGuardHooks で次の制限をかけています(詳細は API-007 の「権限・nonce・レート制限」)。

  • REST は GET / HEAD / OPTIONS と POST /x-announce/v1/announcements 以外を 403(/wp/v2/users/me の更新、アプリケーションパスワードの発行・削除を含む)
  • 自分自身に対する edit_user とアプリケーションパスワードの発行・編集・削除の権限を外す(管理者による取り消しはできる)
  • XML-RPC にはログインできない
  • birthday_linker を併せ持つユーザーは birthday/v1 の決められた書き込みも通り、拒否時のエラーコードは birthday_write_forbidden / birthday_xmlrpc_forbidden になる

ログインパスワードには注意してください。 上の制限はアプリケーションパスワードでのアクセスと wp-admin が対象です。ログインパスワードで wp-login からブラウザにログインすると、フロントの会員プロフィール・退会フォームやコメント投稿などは使えてしまいます。X告知担当ユーザーのログインパスワードは長いランダムな値にし、どこにも保存せず使わないでください。bot にはアプリケーションパスワードだけを渡します。

X の資格情報 ​

X の API キー・アクセストークンは bot 側のシークレットにだけ置き、WordPress には保存しません。この MCP も X には投稿しません。X への投稿は bot が自分の資格情報で行い、投稿できたあとに x_announce_record で結果だけを WordPress に記録します。

運用手順(WordPress 側) ​

bot が叩く WordPress(通常は本番)で、管理者が次の作業をします。

1. X告知担当ユーザーを作る ​

  1. 管理画面 → ユーザー → 新規追加
  2. ユーザー名は用途が分かる名前にする(例: x-announce-bot)。メールアドレスは管理者が受け取れるものにする
  3. 権限グループで「X告知担当」を選んで追加する
  4. パスワードは長いランダムな値を生成したまま、控えずに追加する(ログインパスワードは使わない。bot にはアプリケーションパスワードだけを渡す)

bot ごと・用途ごとにアカウントを分けてください。 日別記事編集bot・運用確認bot などのアカウントに read_x_announce / record_x_announcement を足して兼用しないこと。X告知担当ロールの Capability は ADM-035 権限管理画面 で確認できます(既定は「告知用メタ情報の取得」「告知履歴の記録」のみ)。

2. アプリケーションパスワードを発行する ​

X告知担当ユーザーは wp-admin を開けないため、管理者が発行します。

  1. 管理者でログイン → 管理画面 → ユーザー → X告知担当ユーザーの編集画面
  2. 「アプリケーションパスワード」で名前(例: cursor-x-announce-tools)を入れて追加する
  3. 表示されたパスワード(xxxx xxxx xxxx xxxx xxxx xxxx)を控える。この画面を閉じると二度と表示されません

アプリケーションパスワードは HTTPS のサイトでのみ使えます(ローカルの HTTP では wp-config.php に define( 'WP_ENVIRONMENT_TYPE', 'local' ); が必要)。

3. 失効させる ​

bot をやめるときは、管理者が同じ画面で該当のアプリケーションパスワードを「取り消す」。

4. 漏れた疑いがあるとき ​

漏れたパスワードでできるのは、公開済み記事のメタ情報の読み取りと告知履歴の記録だけです(記事本体は変えられません)。それでも念のため、次のどちらかを行ってください。

  • アプリケーションパスワードをすべて取り消し、ログインパスワードもリセットする
  • X告知担当ユーザーを削除して作り直す(確実)

偽の告知履歴が記録された可能性がある場合は、管理者が該当記事の _x_announcements を確認します。

この制限がかかるのは x_announcer だけ(または x_announcer と ops_status_reader だけ)を持つユーザーです。他のロールを足すと外れるため、兼用しないでください。

設定(Cursor 側) ​

  1. .cursor/mcp.json.example を .cursor/mcp.json にコピーする(.cursor/mcp.json は gitignore。パスワードをコミットしない)
  2. x-announce-tools の env を書き換える
変数必須説明
WP_SITE_URLはいWordPress のサイト URL。https:// 必須(http:// は localhost / 127.0.0.1 / [::1] / *.local / *.test のみ)。リダイレクトは追わないので、リダイレクト先の URL(www の有無も含む)を書く
X_ANNOUNCE_WP_USERNAMEはいX告知担当ユーザーのユーザー名
X_ANNOUNCE_WP_APP_PASSWORDはいX告知担当ユーザーのアプリケーションパスワード(スペース込みで可)

他の MCP(OPS_STATUS_WP_*・DAILY_ARTICLE_WP_* 等)とは別の変数名です。資格情報を混ぜないでください。

json
{
  "mcpServers": {
    "x-announce-tools": {
      "command": "node",
      "args": ["scripts/mcp-x-announce-tools.mjs"],
      "env": {
        "WP_SITE_URL": "https://example.com",
        "X_ANNOUNCE_WP_USERNAME": "x-announce-bot",
        "X_ANNOUNCE_WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
      }
    }
  }
}

設定変更後は Cursor を再読み込みし、MCP x-announce-tools が有効になっていることを確認します。リポジトリで npm install 済み(@modelcontextprotocol/sdk)であることが前提です。

利用可能な Tool ​

MCP Tool name主な引数REST
x_announce_daily_articlesdate_from, date_to(最大 31 日)GET /x-announce/v1/daily-articles
x_announce_daily_articleidGET /x-announce/v1/daily-articles/{id}
x_announce_paid_articles任意 modified_after(前回の modified_gmt か ISO 8601)GET /x-announce/v1/paid-articles
x_announce_paid_articleidGET /x-announce/v1/paid-articles/{id}
x_announce_recordpost_id, kind, tweet_id, posted_atPOST /x-announce/v1/announcements
x_announce_settingsなしGET /x-announce/v1/settings

戻り値は REST のレスポンス JSON そのままです。HTTP エラー・通信失敗・設定不足のときは isError: true で {"error":"...","status":403,"data":{...}} のように返します。入出力とエラー条件の正本は API-007 です。

告知の流れ ​

  1. 告知する記事を探す。日別記事は x_announce_daily_articles に考察日の期間を、有料記事は x_announce_paid_articles に前回取得時の modified_gmt(2026-09-30 15:00:00 の形式のまま)を modified_after で渡す
  2. announcements に同じ kind の履歴があれば、告知済みなのでスキップする
  3. 編集 bot から受け取った要約と、url・title 等のメタ情報で告知文を組み立てる。画像を添付するときは featured_image_url を使う(null なら画像なし)
  4. x_announce_settings で投稿方法を確認する。kind が daily_* なら posting_modes.daily_article、paid_update なら posting_modes.paid_article を見る。設定は途中で変わり得るため、告知のたびに呼ぶ
  5. api のとき: 人間の承認後、bot が X に投稿する。投稿できたら x_announce_record に post_id・kind・X の tweet_id(文字列)・posted_at を渡す。result: created(201)なら記録済み。タイムアウトなどで結果が分からないときは同じ内容で再送してよい(result: duplicate が返り、履歴は増えない。重複の判定は記事ごとに保存している最新 20 件が対象)
  6. manual のとき: X には投稿せず、告知文と url・featured_image_url を人間に渡して終わる。人間が投稿した分は告知履歴に記録しない(x_announce_record は呼ばない)。そのため手順 2 の「告知済み」の判定は効かないので、同じ記事を二重に渡さないよう人間側で確認する(有料記事は更新のたびに modified_after の結果に再び出るため、特に注意する)

投稿方法は管理画面の「サイト運営 > X告知設定」(ADM-036)で管理者だけが変更できます。未設定のときは manual です。X の API キーを bot に用意してから api に切り替えてください。

kind対象用途
daily_pre日別記事示唆考察の告知
daily_after日別記事結果考察の告知
paid_update有料記事有料記事の公開・更新告知

1 ユーザーあたり GET は 1 分 120 回、記録は 1 分 20 回までです。超えると 429 になるので、1 件ずつループで叩かず一覧の Tool を使ってください。

REST の例(curl) ​

bash
SITE=https://example.com
AUTH='x-announce-bot:xxxx xxxx xxxx xxxx xxxx xxxx'

# 考察日の期間の公開済み日別記事
curl -sS -u "$AUTH" "$SITE/wp-json/x-announce/v1/daily-articles?date_from=2026-10-01&date_to=2026-10-03"

# 指定日時より後に更新された公開済み有料記事
curl -sS -u "$AUTH" "$SITE/wp-json/x-announce/v1/paid-articles?modified_after=2026-10-01T00:00:00Z"

# X への投稿方法(api / manual)
curl -sS -u "$AUTH" "$SITE/wp-json/x-announce/v1/settings"

# 告知履歴の記録
curl -sS -u "$AUTH" -H 'Content-Type: application/json' \
  -d '{"post_id":123,"kind":"daily_pre","tweet_id":"1840000000000000000","posted_at":"2026-10-03T09:00:00+09:00"}' \
  "$SITE/wp-json/x-announce/v1/announcements"

トラブルシューティング ​

症状確認
WP_SITE_URL / X_ANNOUNCE_WP_USERNAME / ... を設定.cursor/mcp.json の x-announce-tools.env
HTTP 401(incorrect_password / invalid_username)ユーザー名・アプリケーションパスワードの誤り、取り消し済み、HTTP サイトでの利用
HTTP 403(rest_forbidden、権限がありません)認証ヘッダーが PHP に届いていない、または権限グループが「X告知担当」でない・ADM-035 で「告知用メタ情報の取得」「告知履歴の記録」が外されている
HTTP 404(記事が見つかりません)記事が公開済みでない、または kind と投稿タイプが合っていない(daily_* に有料記事の ID を渡した等)
HTTP 429GET 1 分 120 回・記録 1 分 20 回を超えた。1 分待つ
HTTP 503(告知履歴を保存できませんでした)DB 書き込みの一時的な失敗。時間をおいて同じ内容で再送する
リダイレクトされましたWP_SITE_URL を location の URL(https / www の有無)に合わせる
HTTP 404(rest_no_route)テーマが本機能を含むバージョンか。パーマリンク設定が「基本」だと /wp-json/ が使えない場合がある
JSON 以外の応答WAF・メンテナンス画面・PHP エラー。body の先頭を確認

403 の切り分けは 新台情報担当 MCP の「403 の切り分け」 と同じ手順(/wp/v2/users/me で認証できているかを見る)です。

実装メモ ​

  • 本体: scripts/mcp-x-announce-tools.mjs(テスト: npm run test:mcp-x-announce。npm test にも含まれる)
  • 期間の上限 31 日は XAnnounceRestController::MAX_RANGE_DAYS と同期する
  • 権限判定とレート制限は REST 側(WordPressXAnnouncePermissionChecker)。MCP 側では判定しない