なぜMCPを使わずWP-CLI直呼びにしたか|Claude Codeの外部連携を実装で比較した

2026.07.09 約 15 分で読めます
開いたノートに描かれた2経路の比較。ノートPCからWordPressへ、上の経路は常駐サーバを迂回するMCP、下の経路は直接つながるWP-CLI直呼びを表した手描き線画のアイキャッチ

「AI 連携なら MCP でしょ」——そんな空気があります。でもこのブログの WordPress 操作は、MCP を使わず WP-CLI直呼びにしています。その判断が正しいのか、最小の MCP サーバを実際に立てて往復時間・依存数・起動コストを測りました。数字で見えた線引きを、正直に書きます。

先に結論:MCP を入れず WP-CLI直呼びにした

結論から言うと、いまの使い方なら直接叩くほうが素直でした。このブログの投稿スキル(koma-publisher)は、記事1本を上げるあいだに wp コマンドを十数回叩きます。回数はその程度で、頻度も1日に数回。ここに MCP という常駐サーバを1枚かませる理由が、測っても見つかりませんでした。

数字を先に置きます。WP-CLI直呼びは1コマンドあたり毎回およそ718ms。対して最小の MCP サーバは、初回の起動に972ms、依存パッケージは93個でした。この差が何を意味するのかを、実装と実測でほどきます。

経路の違い:MCP を1枚かませるか、PHP を直接叩くか

まず絵で見たほうが早いです。MCP(Model Context Protocol)は、AI と外部ツールを標準プロトコルでつなぐ仕組み。Claude Code はサーバへ JSON-RPC を投げ、サーバが WordPress を操作して返します。一方の直呼びは、PHP と WP-CLI をその場で起動して WordPress を触るだけ。終わればプロセスは捨てます。あいだに常駐する層がありません。

MCP経由とWP-CLI直呼びの2経路を並べた図。MCPはNode常駐サーバを1枚かませ初回起動972ms・追加依存93個、直呼びはphpとwp-cli.pharを毎回spawnし追加依存0
2経路の違い。MCP は常駐サーバを1枚かませ、直呼びは PHP を毎回起動して捨てる。

ポイントは、MCP を通しても最終的に WordPress を触るのは結局 WP-CLI か PHP だという点。MCP はその手前に通信レイヤーを足すもので、WordPress を速く操作する魔法ではありません。ここを押さえると、次の実測が読みやすくなります。

実測1:WP-CLI直呼びの往復は毎回718ms

まず WP-CLI直呼びから測ります。環境は Windows 11 / PHP 8.2.29(Local by Flywheel)です。呼び出しはこの PowerShell ラッパーを使います。同じ形をそのまま貼れば動きます。

$php  = "C:Userskoma0AppDataRoamingLocallightning-servicesphp-8.2.29+0binwin64php.exe"
$phar = "C:Userskoma0AppDataLocalProgramsLocalresourcesextraResourcesbinwp-cliwp-cli.phar"
$ini  = "C:Userskoma0AppDataRoamingLocalrunJukMWXMMyconfphp"
function wp { & $php -d display_startup_errors=0 -d error_reporting=0 -c $ini $phar --path="...public" @args 2>&1 }

# 往復を10回測る(副作用のない読み取りコマンド)
$t = @()
for ($i=0; $i -lt 10; $i++) {
  $sw = [System.Diagnostics.Stopwatch]::StartNew()
  wp option get siteurl | Out-Null
  $sw.Stop(); $t += $sw.Elapsed.TotalMilliseconds
}
"median = {0} ms" -f ([math]::Round(($t | Sort-Object)[5],1))

結果はこうなりました(N=10・単位 ms)。副作用のない読み取りを2種類、siteurl 取得と投稿数カウントで測っています。

コマンドcoldminmedianmax
wp option get siteurl720.1694.5718.2738.0
wp post list –format=count721.2699.5717.9842.1
WP-CLI直呼びの往復(実測)。cold と median にほぼ差がない=毎回フルブートしている。

初回(cold)と2回目以降(warm)で時間がほぼ変わらないのが、この方式の性格をよく表しています。永続プロセスを持たないので、リクエストのたびに PHP と WordPress コアをまるごとブートするからです。だから常に700〜720ms。中身は DB へのクエリ1回で、そこは軽いのに、ブートで時間を払っています。

そして地味に効くのが、追加の npm 依存がゼロだという点。Local 同梱の wp-cli.phar と PHP をそのまま使うだけ。プロジェクトの package.json を1行も汚しません。

実測2:最小 MCP サーバを立てて測る

比較のため、最小の MCP サーバを Node で書きました。公開するツールは1個だけ。公式 SDK は @modelcontextprotocol/sdk@1.29.0。ランタイムは Node v24.15.0 です。ping は WordPress を触らず即返します。プロトコルの往復だけを切り出したいからです。

// server-sdk.js — ツール1個だけの最小 MCP サーバ(stdio)
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new McpServer({ name: "mcp-min", version: "1.0.0" });
server.registerTool(
  "ping",
  { description: "returns pong (no WordPress access)", inputSchema: {} },
  async () => ({ content: [{ type: "text", text: "pong" }] })
);
await server.connect(new StdioServerTransport());

依存93パッケージ・起動972ms

まず入れた時点で数字が出ます。npm install @modelcontextprotocol/sdk を叩くと、こうなりました。

$ npm install @modelcontextprotocol/sdk
added 93 packages, and audited 94 packages in 3s

$ du -sh node_modules
23M     node_modules

ツール1個のために、推移的な依存も含めて93パッケージ・23MB を抱えます。次に、クライアントからつないで往復を測るベンチを書きました。

// bench-mcp.mjs(要点)— コールドスタートと往復レイテンシを測る
const t0 = performance.now();
const transport = new StdioClientTransport({ command: process.execPath, args: ["server-sdk.js"] });
const client = new Client({ name: "bench", version: "1.0.0" });
await client.connect(transport);              // node起動 + SDK読込 + initialize
const cold = performance.now() - t0;

const rt = [];
for (let i = 0; i < 20; i++) {
  const s = performance.now();
  await client.callTool({ name: "ping", arguments: {} });  // ハンドシェイク後の1往復
  rt.push(performance.now() - s);
}
cold_start_ms : 972.06
roundtrip_ms  : { N: 20, min: 0.22, median: 0.41, avg: 0.56, max: 2.65 }

コールドスタートは972ms。ただしこれは一度きりで、常駐させれば以降は無料です。そのうえでハンドシェイク後の往復は中央値0.41ms。桁が3つ違うので、ここだけ見ると MCP の圧勝に見えます。この見え方に落とし穴があるのですが、それは次の節で書きます。

ちなみに972ms の中身も測りました。素の node -e "" がこの環境で約846ms。SDK 読み込みで+約115ms、ハンドシェイクで+約11ms です。つまり大半は Node 本体のプロセス起動でした。Windows だと spawn 自体が重い、という事情も見えます。

実装で並べる比較表

WP-CLI直呼びと最小 MCP を、測れたものと測れない設計判断の両面で1枚に並べます。緑が実測、灰が判断です。

WP-CLI直呼びと最小MCPの比較表。往復718ms対0.41ms、起動は毎回内包対初回972ms、依存0対93個、認証はwp-config.php対.mcp.json。緑が実測・灰が設計判断
実装で並べた比較。往復・起動・依存は実測、認証と壊れにくさは運用上の判断。

認証情報の置き場も、地味だけど無視できません。直呼びは既存の wp-config.php(gitignore 済み)を単一の出所として使い回します。MCP を採ると、そこに秘匿ファイル .mcp.json がひとつ。うっかりコミットしないよう気を配る対象も、その分だけ増えます。

正直に:ここは実測、ここは設計判断(0.4msの罠)

ここが一番大事なので、はっきり分けます。先ほどの往復0.41msは、あくまで JSON-RPC のトランスポートだけの数字。ping は WordPress を一切触っていません。

もし MCP のツールが本当に WordPress を操作するなら、その中で結局 WP-CLI か PHP を呼びます。すると、あの718msのブートがまるごと往復に戻ってきます。MCP を通したから WordPress 操作が0.4msで返る、という話ではないのです。

MCP 側で本当に0.4msを出したいなら、サーバに PHP や DB の永続接続層を自前で組む必要があります。けれどそれこそ、わたしが避けたかった追加実装そのもの。表面的な損益分岐(972ms 払えば以降ずっと得)は、実際の WordPress 操作では成立しません。だから測れた事実は、こう区別しています。

  • 実測できたこと:直呼びの往復718ms、MCP の起動972ms とトランスポート往復0.41ms、依存93個。
  • 設計上の判断:実操作では MCP がブートを内包する点、認証ファイルが増える点、常駐プロセスの運用コスト。ここは時間より運用で効いてくる話。

数字を都合よく切り取れば「MCP は0.4msで爆速」と書けてしまいます。でもそれは、測定条件を隠した数字。ここを濁さないのが、この検証でいちばん守りたかった線でした。

それでも MCP が正解になる場面

直呼びを選んだからといって、MCP を否定したいわけではありません。向く場面ははっきりあります。

  • つなぎ先が多く、複数クライアント(Claude Desktop・Cursor・VS Code)で操作を共有したいとき。標準化の恩恵がそのまま効きます。
  • 1セッションで大量の呼び出しをする対話的な使い方。永続接続層まで作り込めば、往復コストを本当に削れます。
  • チームで配布して、接続方法を1つの規約にそろえたいとき。

裏を返すと、つなぎ先が WordPress 1つで呼び出しもたまに数回、という個人運用では、標準化のうまみは薄めです。少数ツールなら直接 API を叩くほうが素直、という整理は他でも語られています。わたしの結論も、実測を経て同じ場所に着きました。

Claude Code の設計判断は、ほかの記事でも同じ姿勢で扱っています。hooks でうっかりを止める話や、逐次 vs 並列を実測した記事も、よかったらどうぞ。

まとめ:ツールが少ないうちは直呼びで十分

  • WP-CLI直呼びは毎回718ms(実測)。永続プロセスがなく、追加依存はゼロ。
  • 最小 MCP は起動972ms・依存93個(実測)。往復0.41msはトランスポートのみで、実操作ではブートが戻ります。
  • 認証は wp-config.php 一本 vs .mcp.json 追加。常駐サーバは監視・再起動の運用コストを連れてきます。
  • つなぎ先が少なく呼び出しもまばらな個人運用は、直呼びが素直。多クライアント共有や大量呼び出しなら MCP が効きます。

「流行っているから入れる」ではなく、自分のワークフローの回数と頻度で決める——それだけで、抱える依存と運用はずいぶん軽くなります。ほかの設計判断は爆速開発・環境構築のカテゴリにまとめました。こうした「連携をどう実装すると自社にとって軽いか」の設計は、NEORIVA として法人向けにも一緒に組んでいます。

こま

こま

元SE × AI開発 × 業務自動化の実践者

SE 4年 + プログラミング歴 8年。業務自動化と AI 組み込み開発を仕事にしながら、現場で使えるものだけを書いています。 最新のAIの現場を発信中!!