WordPress MCP プラグインをサブディレクトリインストールで動作させる方法
Claude Desktopからワードプレスの操作をしたかったが、ワードプレスがルートディレクトリの場合は問題なく動作するのものの、サブディレクトリの場合はエラーが発生することが判明。
結局、ワードプレスのプラグインや公式のMCPサーバーにバグがあることがわかり、修正した記録です。
※以降、AI出力のテキストなので、実施の際はご注意ください。
問題の概要
WordPress MCP プラグイン (v0.2.5) には、サブディレクトリにインストールされた WordPress で動作しないバグが2つあります:
- クライアント側のバグ: サブディレクトリのパスを正しく処理できない
- プラグイン側のバグ: JWT認証が正しく機能しない
影響を受ける環境
- ✅ 動作する:
https://example.com/(ルートインストール) - ❌ 動作しない:
https://example.com/blog/(サブディレクトリインストール)
修正方法
パート1: クライアント側の修正(NPMパッケージ)
対象ファイル
@automattic/mcp-wordpress-remote パッケージの dist/proxy.js
修正箇所
38308行目付近の constructApiUrl 関数
修正前:
function constructApiUrl(baseUrl, defaultEndpoint) {
const cleanUrl = removeTrailingSlash(baseUrl);
try {
const urlObj = new URL(cleanUrl);
const hasCustomPath = urlObj.pathname && urlObj.pathname !== "/" && urlObj.pathname.length > 0;
const hasCustomQuery = urlObj.search && urlObj.search.length > 0;
if (hasCustomPath || hasCustomQuery) {
return cleanUrl; // ← バグ: サブディレクトリでクエリパラメータが付かない
} else {
return new URL(`/?rest_route=${defaultEndpoint}`, cleanUrl).toString();
}
} catch (error) {
return new URL(`/?rest_route=${defaultEndpoint}`, cleanUrl).toString();
}
}修正後:
function constructApiUrl(baseUrl, defaultEndpoint) {
const cleanUrl = removeTrailingSlash(baseUrl);
try {
const urlObj = new URL(cleanUrl);
const hasCustomQuery = urlObj.search && urlObj.search.length > 0;
// If there's already a custom query (like ?rest_route=...), use the URL as-is
if (hasCustomQuery) {
return cleanUrl;
} else {
// Always append ?rest_route= for all paths (including subdirectories)
// Add trailing slash before query parameter for WordPress compatibility
return `${cleanUrl}/?rest_route=${defaultEndpoint}`;
}
} catch (error) {
// Fallback: always append ?rest_route=
return `${cleanUrl}/?rest_route=${defaultEndpoint}`;
}
}変更点の説明
hasCustomPathチェックを削除: サブディレクトリの存在をチェックしていた条件を削除- URL構築方法を変更:
new URL()ではなく文字列連結を使用してパスを保持 - 末尾スラッシュを追加: WordPressのリライトルール互換性のため
修正済みパッケージのインストール方法
方法1: グローバルインストール(推奨)
修正済みパッケージをダウンロード後:
npm install -g /path/to/automattic-mcp-wordpress-remote-0.2.18-patched.tgzClaude Desktop 設定 (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"wordpress-mcp": {
"command": "npx",
"args": ["@automattic/mcp-wordpress-remote"],
"env": {
"WP_API_URL": "https://example.com/blog/",
"JWT_TOKEN": "your-jwt-token-here"
}
}
}
}方法2: ローカルパス指定
修正済みパッケージを展開後:
{
"mcpServers": {
"wordpress-mcp": {
"command": "node",
"args": ["/Users/username/mcp-packages/dist/proxy.js"],
"env": {
"WP_API_URL": "https://example.com/blog/",
"JWT_TOKEN": "your-jwt-token-here"
}
}
}
}パート2: プラグイン側の修正(WordPress プラグイン)
いくつかのファイルの修正が必要だったので、修正版をアップロードしました。
こちらから、zipファイルをダウンロードして使ってください。
インストール手順
1. バックアップ
必ず元のファイルをバックアップしてください:
wp-content/plugins/wordpress-mcp/includes/Core/にて
- McpTransportBase.php → コピーして名前を変更 TransportBase.php.backup
- McpStdioTransport.php → コピーして名前を変更 McpStdioTransport.php.backup
2. ファイルの修正
上記の修正を適用します。
3. プラグインの再起動
- WordPress管理画面 → プラグイン → インストール済みプラグイン
- 「WordPress MCP」を無効化
- 再度有効化
- 設定 → パーマリンク設定 → 「変更を保存」をクリック
4. Claude Desktop の再起動
Claude Desktop アプリを完全に終了して再起動します。
追加の問題:Apache環境でのJWT認証エラー(401 Unauthorized)
上記のバグ修正を行った後でも、サーバー環境によってはさらに別のエラーが発生する場合があります。
症状
MCPサーバーのログに以下のような401エラーが繰り返し記録され、接続が確立できない。
[ERROR] [API] API error response: {"code":"unauthorized","message":"Authentication required. Please provide a Bearer token or log in as an administrator.","data":{"status":401}}
[ERROR] [TRANSPORT_DETECT] ❌ Both JSON-RPC and simple transports failed
接続の流れとしては、以下のようにすべてのリクエストが拒否されます。
- JSON-RPC方式で初期化リクエスト送信 → 401で失敗
- Simple方式にフォールバック → これも401で失敗
- ツール一覧(ListTools)、プロンプト一覧(ListPrompts)なども → すべて401
JWTトークン自体は正しく送信されているにもかかわらず、WordPress側が認証を拒否している状態です。
原因
Apacheサーバーが Authorization ヘッダーを除去していることが原因です。
ApacheのデフォルトのCGI/FastCGI設定では、セキュリティ上の理由から Authorization ヘッダーがPHPに渡されないことがあります。そのため、MCPサーバーがJWTトークンを正しく送信していても、WordPress(PHP)側にはトークンが届かず、認証エラーになります。
この問題は特に以下の環境で発生しやすいです。
- Apache + mod_php ではなく、Apache + PHP-FPM(FastCGI)の環境
- 共用レンタルサーバー(Xserver、さくら、ConoHa WINGなど)
- サブディレクトリにWordPressをインストールしている場合
対処方法
WordPressがインストールされているサブディレクトリの .htaccess に、以下の1行を追加します。
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
この記述は、ApacheのRewriteEngineを使って Authorization ヘッダーの内容を環境変数 HTTP_AUTHORIZATION として設定し、PHPに渡す役割を果たします。
追記する場所
.htaccess ファイルの RewriteEngine On の直後に追加してください。WordPressの標準的な .htaccess であれば、以下のようになります。
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
※ RewriteBase のパスはご自身の環境に合わせてください。上記は /blog/ というサブディレクトリの例です。
注意点
- ルートディレクトリではなく、WordPressがインストールされているサブディレクトリの
.htaccessに追記する必要があります - ルートディレクトリにWordPressをインストールしている場合は、ルートの
.htaccessに追記します - この修正はWordPress本体の動作には影響しません(REST API以外の通常のページ表示などはこれまで通り動作します)
.htaccessを編集する前に、必ずバックアップを取ってください
この問題の見分け方
MCPのログで以下の条件がすべて当てはまる場合、この問題の可能性が高いです。
- ステータスコードが 401 である
"Authentication required. Please provide a Bearer token"というメッセージが出ている- ログ上ではJWTトークンが送信されている(
[AUTH] Using JWT token authenticationと表示されている) - プラグイン側・クライアント側のバグ修正は済んでいる
JWTトークンの期限切れや無効なトークンでも同じ401エラーが出ますが、その場合はトークンの再生成で解決します。.htaccess の修正で解決しない場合は、WordPress管理画面からJWTトークンを再生成してみてください。
