WordPress MCP プラグインをサブディレクトリインストールで動作させる方法

Claude Desktopからワードプレスの操作をしたかったが、ワードプレスがルートディレクトリの場合は問題なく動作するのものの、サブディレクトリの場合はエラーが発生することが判明。
結局、ワードプレスのプラグインや公式のMCPサーバーにバグがあることがわかり、修正した記録です。

※以降、AI出力のテキストなので、実施の際はご注意ください。

問題の概要

WordPress MCP プラグイン (v0.2.5) には、サブディレクトリにインストールされた WordPress で動作しないバグが2つあります:

  1. クライアント側のバグ: サブディレクトリのパスを正しく処理できない
  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}`;
  }
}

変更点の説明

  1. hasCustomPath チェックを削除: サブディレクトリの存在をチェックしていた条件を削除
  2. URL構築方法を変更: new URL() ではなく文字列連結を使用してパスを保持
  3. 末尾スラッシュを追加: WordPressのリライトルール互換性のため

修正済みパッケージのインストール方法

方法1: グローバルインストール(推奨)

修正済みパッケージをダウンロード後:

npm install -g /path/to/automattic-mcp-wordpress-remote-0.2.18-patched.tgz

Claude 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. プラグインの再起動

  1. WordPress管理画面 → プラグイン → インストール済みプラグイン
  2. 「WordPress MCP」を無効化
  3. 再度有効化
  4. 設定 → パーマリンク設定 → 「変更を保存」をクリック

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

接続の流れとしては、以下のようにすべてのリクエストが拒否されます。

  1. JSON-RPC方式で初期化リクエスト送信 → 401で失敗
  2. Simple方式にフォールバック → これも401で失敗
  3. ツール一覧(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トークンを再生成してみてください。

あなたへのおすすめ