WP Manifestindependent plugin directory

Install

Download od-mcp-bridge-0.5.0.zip From the 0.5.0 release on GitHub, Sep 3, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/olein-jp/od-mcp-bridge/releases/download/0.5.0/od-mcp-bridge-0.5.0.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

OD MCP Bridge は、WordPress Abilities API で登録した機能を、公式の WordPress MCP Adapter 経由で MCP クライアントへ安全に公開するためのプラグインです。

実サイトへのインストールから MCP クライアントでの確認、各 Ability の入力項目、 トラブル対応までの詳しい手順は、利用マニュアルを参照してください。

実サイトへ導入する場合は、GitHub のソースコード ZIP ではなく、最新リリースに添付された od-mcp-bridge-0.5.0.zip を使用してください。配布 ZIP には実行に必要な Composer 依存パッケージが含まれています。

提供する Ability

初期状態では、公開情報を扱う次の6件が有効です。

  • od-mcp-bridge/get-site-info: サイト基本情報
  • od-mcp-bridge/get-posts / get-post: 公開済み投稿の一覧・本文
  • od-mcp-bridge/get-pages / get-page: 公開済み固定ページの一覧・本文
  • od-mcp-bridge/get-terms: カテゴリーまたはタグの一覧

保守情報を扱う次の9件は初期状態で無効です。管理画面で必要なものだけを有効にし、 各 Ability が要求する権限を持つ専用ユーザーで利用してください。

  • get-update-status: キャッシュ済み更新状況
  • get-plugins / get-themes: サニタイズ済みプラグイン・テーマ情報
  • get-site-health: 外部通信を伴わない限定的なサイトヘルス結果
  • get-content-summary / get-stale-content: コンテンツ活動・長期未更新コンテンツ
  • get-cron-status: 引数を除外した WP-Cron 状況
  • get-maintenance-snapshot: 上記の保守情報を権限境界付きで集約
  • get-security-posture: 外部通信や認証情報の取得を行わないセキュリティ設定要約

安全な write 系 Ability も初期状態では無効です。create-post-draft は通常投稿の下書き、 create-page-draft は固定ページの下書きを、接続ユーザーを作成者として作成します。 create-template-part は、現在のブロックテーマへデータベース保存型のテンプレートパーツを新規作成します。 いずれもUUIDによる冪等性を備え、既存コンテンツの更新や削除は行いません。新しい固定ページと テンプレートパーツのAbilityはApplication Password接続専用で、OAuth経由では既定で拒否します。

下書きや非公開コンテンツ、ユーザー情報、認証情報、ファイルパス、Cron 引数は返しません。 詳細な権限と入出力は利用マニュアルを参照してください。

必要な環境

  • Docker
  • Node.js 22.19 以上 / npm(HTTP MCP 検証時)
  • WordPress 6.9 以上
  • PHP 7.4 以上
  • Composer 2

開発環境

composer install
npm install
npm run env:start
npm run env:cli -- rewrite structure '/%postname%/' --hard

WordPress は http://localhost:8888、管理画面は http://localhost:8888/wp-admin で開けます。wp-env の初期認証情報は ユーザー名 admin、パスワード password です。

npm run env:status
npm run env:logs
npm run env:stop

自動テスト

Docker と wp-env を起動した状態で、WordPress の専用テスト DB を使う統合テストを実行します。 テストデータは各テスト内で作成されるため、開発環境の投稿やユーザーには依存しません。

npm run env:start
composer test:integration
composer lint

翻訳対象の文言は od-mcp-bridge テキストドメインで管理しています。日本語翻訳はプラグインへ 同梱され、WordPress のサイト言語が日本語の場合に自動で読み込まれます。ほかの言語を追加する場合は languages/od-mcp-bridge.pot を翻訳元として使用してください。

翻訳対象文字列を変更した場合は、wp-env を起動して POT ファイルを再生成できます。

npm run i18n:pot

composer test:integration は wp-env の tests-cli コンテナで PHPUnit を実行します。 テストでは WordPress 6.9以上、Ability の登録とスキーマ、権限、公開コンテンツの絞り込み、 保守情報のサニタイズ、設定による無効化、保守スナップショットの失敗分離、 セキュリティ設定要約の権限・情報漏えい・外部通信禁止に加え、投稿・固定ページ下書きと テンプレートパーツ作成の入力制限、 権限分離、冪等性、同時実行防止、OAuth write scopeを確認します。

WordPress 管理画面の「設定 → OD MCP Bridge」では、MCP エンドポイントの確認と、 公開する Ability の有効・無効を設定できます。接続診断では、HTTPS、Application Password、OAuth設定、 MCP Adapter、専用ロール、Abilityごとの必要capabilityとOAuth scopeを外部通信なしで確認できます。 初期状態では公開情報を扱う6件だけが有効です。

MCP 接続

HTTP エンドポイントは次のURLです。

https://example.com/wp-json/mcp/mcp-adapter-default-server

本番環境では必ず HTTPS の endpoint を使用してください。

Codex 以外の AI クライアントで使う

OD MCP Bridge は Codex 専用ではありません。WordPress 側は MCP の仕組みを通して Ability を公開するため、 stdio 形式の MCP サーバーを登録できる AI アプリケーションやエディターから利用できます。 Claude、Visual Studio Code、Cursor、Gemini CLI などでも、各クライアントが対応する MCP 設定へ @automattic/mcp-wordpress-remote のコマンド、引数、環境変数を登録するのが基本です。

この README にある mcpServers の JSON は構成例です。設定ファイル名やトップレベルのキー、 登録コマンド、ツール実行時の確認画面はクライアントごとに異なります。必ず利用中のバージョンに 対応する各社の公式ドキュメントを確認してください。

提供元・クライアント MCP 登録に関する一次情報
OpenAI Codex/ChatGPTデスクトップアプリ OpenAI公式:Model Context Protocol
Anthropic Claude Code Anthropic公式:Connect Claude Code to tools via MCP
Anthropic Claude Desktop Anthropic公式:Getting Started with Local MCP Servers on Claude Desktop
Microsoft Visual Studio Code Microsoft公式:Add and manage MCP servers in VS Code
Cursor Cursor公式:Model Context Protocol
Google Gemini CLI Google公式:MCP servers with Gemini CLI

MCP そのものの仕様と考え方は、Model Context Protocol 公式ドキュメント を参照してください。クライアントのプラン、組織ポリシー、対応 transport、認証方式によっては MCP 機能を利用できない場合があります。

ブラウザから送信されるMCPリクエストは、DNS Rebinding対策として Origin を検証します。 WordPressのhome/site Originは既定で許可され、Originを送らないサーバー間クライアントも利用できます。 別Originのブラウザクライアントを許可する場合は、ワイルドカードを使わず od_mcp_bridge_allowed_origins フィルターへ完全なOriginを追加してください。

OAuth 2.1リソースサーバー

Application Passwordに加えて、外部認可サーバーが発行するRS256 JWTアクセストークンを 検証できます。「設定 → OD MCP Bridge」でIssuer、JWKS URI、OAuth resource URIを設定し、 MCP専用ユーザーのプロフィールへトークンの sub を対応付けます。

OAuth接続では、MCP初期化と探索用の od-mcp:discover に加え、実行対象に応じて od-mcp:content:read、od-mcp:content:write、または od-mcp:maintenance:read が必要です。Scopeと既存のWordPress capabilityを両方満たした場合だけAbilityが実行されます。未登録の第三者AbilityはOAuth経由では 既定で拒否します。OAuthでのAbility探索結果には、現在のアクセストークンのScopeで実行できる Abilityだけが表示され、対象Scopeを持たないAbilityの詳細取得も拒否されます。

Protected Resource Metadata:

https://example.com/wp-json/od-mcp-bridge/v1/oauth-protected-resource

認可サーバーの構成、ユーザー対応付け、対応トークン、移行手順は 利用マニュアルのOAuth 2.1で接続するを参照してください。

実サイトで取得したアクセストークンを使うE2Eスモークテストは、トークンをファイルや引数へ 書かず環境変数へ設定して composer test:oauth:live を実行できます。必要な変数と確認内容は 利用マニュアルの実サイトでOAuth E2Eを確認するを参照してください。

専用ユーザーと Application Password

  1. 管理者で「ユーザー → ユーザーを追加」を開き、MCP 接続専用ユーザーを作成します。
  2. 公開コンテンツ系だけを使う場合は「購読者(Subscriber)」、保守系も使う場合は プラグインが作成する「MCP Maintenance Reader」ロールを選びます。この専用ロールには プラグイン有効化、テーマ変更、設定変更などのWordPress管理権限は含まれません。 create-post-draft を使う場合は「投稿者(Author)」など edit_posts を持つ専用ユーザーを、 create-page-draft には edit_pages を持つ専用ユーザーを用意します。テンプレートパーツ作成用ユーザーには od_mcp_bridge_create_template_parts capabilityだけを個別に付与できます。MCP Maintenance Readerには これらの作成権限を付与しません。
  3. 専用ユーザーでログインし、「ユーザー → プロフィール」の「Application Passwords」で OD MCP Bridge などの識別しやすい名前を入力して発行します。
  4. 表示された Application Password は一度だけコピーし、MCP クライアント側の 環境変数またはシークレットストアで管理します。WordPress の通常のログインパスワードは 使用しません。
  5. 接続確認を終えた場合やクライアントを廃止した場合は、同じプロフィール画面の Application Passwords 一覧から該当するものを失効させます。

Application Password、通常のログインパスワード、実際のユーザー名を、このプラグインの 設定、WordPress option、リポジトリ、Issue、ログへ保存しないでください。Application Password の詳細は WordPress REST API Handbook も参照してください。

MCP クライアント設定

@automattic/mcp-wordpress-remote を stdio MCP server として起動し、WordPress の HTTP endpoint へ中継します。次はサンプル値だけを含む設定例です。実際の値はローカルの MCP クライアント設定または、そのクライアントを起動する環境から渡してください。

Codex 以外で使う場合も、登録する stdio プロセスの実体は同じです。次の例にある command、args、 env を、利用するクライアントの公式ドキュメントに従って移してください。

{
  "mcpServers": {
    "od-mcp-bridge": {
      "command": "npx",
      "args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
      "env": {
        "WP_API_URL": "https://example.com/wp-json/mcp/mcp-adapter-default-server",
        "WP_API_USERNAME": "mcp-reader",
        "WP_API_PASSWORD": "<APPLICATION_PASSWORD>",
        "OAUTH_ENABLED": "false"
      }
    }
  }
}

MCP Inspector での確認

シェルの環境変数へ実サイトの値を設定します。値を含むコマンドをシェル履歴へ残さない 方法で設定してください。

export WP_API_URL='https://example.com/wp-json/mcp/mcp-adapter-default-server'
export WP_API_USERNAME='mcp-reader'
export WP_API_PASSWORD='<APPLICATION_PASSWORD>'
export OAUTH_ENABLED='false'

以下の関数は、環境変数を MCP Inspector が起動するプロキシへ渡します。

mcp_inspector() {
  npx -y @modelcontextprotocol/inspector@latest --cli \
    npx @automattic/mcp-wordpress-remote@latest \
    -e "WP_API_URL=$WP_API_URL" \
    -e "WP_API_USERNAME=$WP_API_USERNAME" \
    -e "WP_API_PASSWORD=$WP_API_PASSWORD" \
    -e "OAUTH_ENABLED=$OAUTH_ENABLED" \
    "$@"
}

まず、default server の3つの MCP tool を確認します。

mcp_inspector --method tools/list
  • mcp-adapter-discover-abilities
  • mcp-adapter-get-ability-info
  • mcp-adapter-execute-ability

次に、公開中の Ability を検出します。初期設定では、サイト情報、投稿、固定ページ、 カテゴリー・タグを扱う6件が含まれることを確認します。

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-discover-abilities \
  --tool-args-json '{}'

検出された Ability はすべて mcp-adapter-execute-ability から実行できます。 get-post の post_id は実サイトに存在する公開済み投稿 ID へ置き換えてください。

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/get-site-info","parameters":{}}'

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/get-posts","parameters":{"per_page":5}}'

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/get-post","parameters":{"post_id":1}}'

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/get-pages","parameters":{"per_page":5}}'

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/get-page","parameters":{"page_id":2}}'

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/get-terms","parameters":{"taxonomy":"category","per_page":20}}'

投稿下書きを作成する場合は、管理画面で create-post-draft を明示的に有効化し、edit_posts を 持つ専用ユーザーで接続します。request_id は実行ごとに新しい UUID を生成し、同じリクエストを 通信上の理由で再送するときだけ同じ値を使います。

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/create-post-draft","parameters":{"request_id":"550e8400-e29b-41d4-a716-446655440000","title":"夏季休業のお知らせ","content":"<!-- wp:paragraph --><p>8月13日から16日まで休業します。</p><!-- /wp:paragraph -->"}}'

成功時は投稿ID、固定値 draft の状態、管理画面の編集URL、実際に新規作成したかを示す created が返ります。プラグインから公開は行わないため、編集URLで内容を確認したうえで、 公開はWordPress管理画面から人が行ってください。

固定ページ下書きとテンプレートパーツはApplication Password接続専用です。対象Abilityを有効にし、 それぞれ edit_pages または od_mcp_bridge_create_template_parts を持つ専用ユーザーで実行します。

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/create-page-draft","parameters":{"request_id":"650e8400-e29b-41d4-a716-446655440000","title":"会社概要","content":"<!-- wp:paragraph --><p>会社概要を入力してください。</p><!-- /wp:paragraph -->"}}'

mcp_inspector \
  --method tools/call \
  --tool-name mcp-adapter-execute-ability \
  --tool-args-json '{"ability_name":"od-mcp-bridge/create-template-part","parameters":{"request_id":"750e8400-e29b-41d4-a716-446655440000","title":"キャンペーンヘッダー","slug":"campaign-header","content":"<!-- wp:group --><div class=\"wp-block-group\"></div><!-- /wp:group -->","area":"header"}}'

認証拒否も確認します。次のリクエストは Application Password を送らないため、HTTP 401 になる必要があります。

curl --include \
  --request POST \
  --header 'Accept: application/json, text/event-stream' \
  --header 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"od-mcp-bridge-check","version":"1.0.0"}}}' \
  "$WP_API_URL"

不正な認証情報でも確認する場合は、実際の Application Password をコマンドへ含めず、 --user "$WP_API_USERNAME:definitely-not-valid" を追加して同じリクエストを送ります。 確認後は unset WP_API_PASSWORD を実行してください。

ローカルの wp-env では、WP-CLI の STDIO transport でも確認できます。

npm run env:cli -- mcp-adapter list
npm run env:cli -- mcp-adapter serve \
  --server=mcp-adapter-default-server \
  --user=admin

default server では、各 Ability は個別のMCP toolとして直接列挙されません。 mcp-adapter-discover-abilities で検出し、mcp-adapter-execute-ability から実行します。

リリース

od-mcp-bridge.php の Version、package.json の version、readme.txt の Stable tag を同じ値へ更新してコミットした後、1.2.3 のような 0.0.0 形式(v 接頭辞なし)のタグを push します。

git tag 0.1.1
git push origin 0.1.1

タグとプラグインヘッダーのバージョンが一致すると、GitHub Actions が 本番用 Composer 依存を含む ZIP を作成し、同名の GitHub Release に添付します。 ローカルでは次のコマンドで同じ ZIP を生成できます。

npm run package -- 0.5.0

Releases

6 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
0.5.0 latest
Sep 3, 2026 1mo ago
od-mcp-bridge-0.5.0.zip
3
Aug 25, 2026 1mo ago
od-mcp-bridge-0.4.1.zip
17
Aug 12, 2026 2mo ago
od-mcp-bridge-0.4.0.zip
4
Aug 12, 2026 2mo ago
od-mcp-bridge-0.3.0.zip
2
Aug 11, 2026 2mo ago
od-mcp-bridge-0.2.0.zip
13
Aug 11, 2026 2mo ago
od-mcp-bridge-0.1.0.zip
4
D+ grade

Security

OD MCP Bridge 0.5.0 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
0.5.0
Findings
2
Worst severity
high
Content hash
297592970b9d187c17f100af…

Findings

  • high OAuth ability-scope checks miss the nested JSON-RPC params shape the MCP adapter executes

    auth_bypass

    When authentication mode is OAuth or Both, Resource_Server::protect_mcp_request() is the only place that enforces per-ability scopes (od-mcp:content:read, od-mcp:content:write, od-mcp:maintenance:read) on top of the mapped WordPress user. It collects target abilities only from a tools/call whose params.name is mcp-adapter-execute-ability / mcp-adapter-get-ability-info and whose params.arguments.ability_name is a string. The bundled adapter's ToolsHandler::extract_params() treats params.params as the real payload for backward compatibility, so a Bearer token that has only od-mcp:discover can POST {method:tools/call, params:{params:{name:mcp-adapter-execute-ability, arguments:{ability_name:od-mcp-bridge/..., parameters:{...}}}}}. get_requested_ability_names() sees no ability, required scopes stay [od-mcp:discover], wp_set_current_user() has already run, and execute-ability then runs the nested call. WordPress capability checks still apply, but they do not restore the product's stated least-privilege model: a discover-only token mapped to an administrator or author can execute every enabled ability that user can, including opt-in writes (create-post-draft) and maintenance reads (plugin inventory, security posture). Default Application Password mode does not use this gate.

    src/OAuth/class-resource-server.php:177-238

    Recommendation

    Do not pre-parse a single JSON-RPC shape. Enforce scopes at execution time (for example on mcp_adapter_pre_tool_call) after the adapter has resolved the tool name and arguments, including the nested params.params envelope extract_params() accepts. Fail closed on tools/call to execute-ability/get-ability-info when ability_name cannot be bound to a mapped scope. Keep the existing WordPress capability checks.

  • medium Public-content abilities return raw bodies of password-protected posts and pages

    information_disclosure

    Default-on abilities get-post and get-page are documented as returning only published public content and are gated solely by current_user_can('read'). execute_single_content() accepts any post/page with post_status=publish and copies $post->post_content with no post_password / has_password check. WordPress keeps password-protected content at status publish with a non-empty post_password; core REST hides content.raw from read-only callers unless the password is supplied. The plugin's recommended MCP identity is a dedicated Subscriber, so any holder of that Application Password (or a cookie-authenticated subscriber hitting /wp-abilities/v1/.../run, which is also enabled via show_in_rest) can read the full block markup of password-protected posts and pages by ID. get-posts/get-pages/get-stale-content use WP_Query post_status=publish without has_password=>false, so protected items also appear in listings. Drafts and private posts are correctly excluded.

    src/class-abilities.php:878-928

    Recommendation

    Treat password-protected content as non-public: add 'has_password' => false to collection/stale queries, and in execute_single_content() reject posts where post_password is non-empty (404, same as not found). Do not return post_content, excerpts, or titles beyond what core REST exposes to a read-only user without the password.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.