どうもカッツプロダクション代表のカッツです

今回は「AIエージェントでWordPressサイトをメンテするなら、どう繋ぐのがベストなの?という話です。いろいろ検討した結果、最終的に自作のMCPツールでWordPressを読み書きする仕組みを作って、実案件で運用を始めました。そこに至るまでの検討と、実際の運用ルールをまとめておきます。

テーマはgit管理できてるのに、固定ページの中身だけ手作業

今のWordPress案件では、header.phpやfooter.phpなどテーマ一式はgitで管理していて、Claude Codeに「ヘッダーのメニューに〇〇追加して」みたいに自然言語で頼めばサクッと直してくれる状態になってます。ここまではめちゃくちゃ快適なんですよ。

ところが固定ページや投稿の本文だけは別なんですよね。WordPressの本文はファイルじゃなくてデータベースに入っているので、gitの外。結局そこだけ管理画面を開いて手で直すことになります。

テーマはAIが直せる、でも本文は人間が直す。この「分断」があると、AIに任せられる範囲が中途半端になって、むしろ手間が逆に増える場面すらあるんですよね、、、

で、「AIエージェント時代的にはどう繋ぐのがベストなの?」とClaudeさんと壁打ちしてみました。

案1:SSH経由でWP-CLIを叩く

最初に自分が考えたのがこれ。WP-CLI(WordPressをコマンドで操作するツール)を、Claude CodeからSSH経由で叩く方法です。

調べてみたら、WP-CLIには最初からリモートのサーバーに対してコマンドを実行する機能がついてるんですよね。wp-cli.ymlに接続先を書いておけば、手元から@prodみたいな名前で本番環境を操作できます。

wp-cli.yml(イメージ)@prod:
  ssh: user@example.com
  path: /home/user/www/wordpress
手元から本番の固定ページ(ID:12)の本文をファイルで上書き(イメージ)wp @prod post update 12 ./page-contents/about.html

技術的にはかなりスマート。ただ、、、AIにSSHの鍵を預けることになるのが引っかかりました。SSHで入れるということは、サーバー上でほぼ何でもできるということ。固定ページを1枚直したいだけなのに、サーバーの全権を渡すのはさすがに怖いですよね。

案2:固定ページの中身をファイルに逃がす(→即ツッコミ)

次にClaudeさんが出してきたのが「固定ページの中身をHTMLファイルにして、テンプレートからfile_get_contentsで読み込めばいいのでは?」という案。git管理できてSSHも要らない、と一見よさそうなんですが、、、いやこれWordPressのシステムの外じゃん!とツッコみました(笑)

本文としてWordPressに保存されないので、サイト内検索に出ない、リビジョンが残らない、編集画面は空っぽ、と、CMSを使ってる意味がほぼなくなっちゃうんですよね。Claudeさんもすぐ「おっしゃる通りです」と引っ込めてました。

案3:REST APIで本文を更新する

WordPressのシステムに乗せたまま操作するなら、REST API経由で本文を更新するという手もあります。以前のMCP記事で作ったwp-blog-usrも、REST APIで記事一覧を読みにいく仕組みでしたね。Application Password(アプリケーションパスワード)で認証すれば、SSHより渡す権限をグッと絞れます。

ただサーバーの方針で、WAF(Webアプリケーションファイアウォール)をONにしてるんですよね。HTMLを丸ごとPOSTするような本文更新は攻撃っぽく見えて弾かれる可能性があって、AIのためにWAFを切るのは本末転倒だよなー、と、、、

ちなみに、実際にREST API経由(WordPress公式のMCPプラグイン「MCP Adapter」)でつないでみたら、認証まわりで丸一日ハマりました、、、その話はこちらの記事にまとめています。

結局 自作MCPツールでWordPressを読み書きする

で、最終的にどうしたかというと、WordPressを読み書きできるMCPツール(wp-agent-ssh)を自作して、とある企業サイトの案件で運用を始めました。名前の通りSSH経由でサーバー上のWP-CLIを叩いて、WordPressを操作する仕組みで、案1の「怖さ」は運用ルールで縛る、という方針にしました。

ちなみに、SSH+WP-CLI経由でMCP Adapterを動かすパターンもあるんですよね(wp mcp-adapter serveというコマンドで、REST APIを使わずにつなげる方法)。実際に試して動きはしたんですが、WP-CLIまで叩けるなら、わざわざabilityを登録して操作を絞る意味がない気がして却下しました。SSHの鍵がある時点で何でもできちゃうので、、、

仕組み:本番とステージングの2系統

Claude Codeのプロジェクト設定.mcp.jsonに、本番用とステージング用の2つのMCPサーバーを登録しています。中身は同じNode.js製のツールで、環境変数WP_PATHで操作対象のWordPressを切り替える形です。

.mcp.json(パスはダミーです){
  "mcpServers": {
    "wp-agent-ssh-prod": {
      "command": "node",
      "args": ["mcp-tools/wp-agent-ssh/wp-mcp-stdin.js"],
      "env": { "WP_PATH": "/path/to/production" }
    },
    "wp-agent-ssh-stg": {
      "command": "node",
      "args": ["mcp-tools/wp-agent-ssh/wp-mcp-stdin.js"],
      "env": { "WP_PATH": "/path/to/staging" }
    }
  }
}

用意したツールはこんな感じ。以前のPHP版は読み取りだけでしたが、今回は書き込みまでできます。

種別ツール
読み取りget_site_info / get_posts / get_post / get_categories / get_users
書き込みcreate_post / update_post / delete_post / create_category / update_category / delete_category / upload_media

もちろん固定ページ(post_type=page)だけでなく、投稿なども同じツールで操作できます。

怖さは運用ルールで縛る

書き込みツールを本番に向けると、AIの操作が即本番に反映されるわけです。なのでClaude Codeが読むルールファイル(AGENTS.md)に、こんなルールを書いておきました。

  • 読み取り系は確認なしで実行してOK
  • 本番の書き込み系は、実行前に必ず人間に確認を取る
  • 動作確認はまずステージングで行う

「AIに鍵は渡すけど、本番で手を動かす前には必ず声をかけてもらう」という、新人さんに仕事を任せるときと同じ考え方ですね(笑)

実際のクライアント依頼をAIに投げてみた

ある日、クライアントさんからこんな依頼が来ました(社名・部署名は伏せています)。

事業所案内の「〇〇事業部」ですが、現在△△から□□センターへ移動しておりますので、住所・TEL・FAX・地図は□□センターと同じにしてください。

これをほぼそのままClaude Codeに渡したところ、こんな流れで進みました。

  1. まずテーマのファイルを検索 → 見つからない(本文はデータベースにあるので当然)
  2. 本番にget_postsでキーワード検索 → 「事業所のご案内」ページを特定
  3. get_postで本文を取得して、該当の行を書き換えた内容を作成
  4. 「本番へ即反映されるので、実行前に確認させてください」と確認を求めてくる
  5. 「反映する」を選ぶとupdate_postで更新
  6. もう一度get_postで読み直して、反映されたことを確認
  7. 変更前・変更後の比較表を出して完了報告
当たり前ですがしっかり作業します流石人工知能!

1番目がまさに冒頭の「分断」問題そのもので、AIもまずファイルを探しにいって空振りしてるんですよね(笑)。そこからMCPツールに切り替えて、データベース側の本文にたどり着いてくれました。

そして4番目。AGENTS.mdに書いたルール通り、本番を書き換える前にちゃんと止まって聞いてくれました。住所・TEL・FAX・地図リンクの4か所を、電話リンクや地図のURLまで含めて漏れなく直してくれて、作業後の読み直し確認まで自分でやってくれる。ここまでやってくれると、正直もう人間が管理画面で直すより確実かも、、、と思いました。

やってみて気づいたこと

ひとつ気になったのが、更新前後で本文の改行コードが変わってたこと。もともとWindows式の改行(\r\n)だったのが、更新後は\nに揃っていました。表示には影響ないんですが、本文を丸ごと上書きする仕組みなので、頼んでない部分も「保存し直されてる」ってことなんですよね。変更箇所だけピンポイントで書き換えているわけではない、というのは覚えておきたいポイントです。

あと、どうでもいい話ですが、ステージングと本番の中身は全然一致してません(笑)。運用してるとよくある話で、正直知ってて放置してたやつです(ズボラ)。テーマ(ファイル)はgitで揃っても、本文(データベース)は勝手には同期されないんですよね。AIが勘違いしないように、念のためルールにも「ステージングと本番のコンテンツは同期していない」と書いておきました。

ちなみに.mcp.jsonとツール本体(mcp-tools/)は、GitHub Actionsのデプロイ対象から除外しています。このリポジトリはほぼ丸ごと本番の公開フォルダにデプロイされる構成なので、何も考えずに置くとMCPのコードまで本番に上がっちゃうんですよね。それを防ぐための保険です。

AIエージェント時代、CMSの方がデメリット多い?

ちゃんと運用できてはいるものの、ここまでやってみて思ったのは、CMSってそもそもAIエージェントと相性が悪いんじゃないかということです。

やりたいことWordPress(CMS)静的HTML+PHP include
本文の管理データベース(gitに乗らない)ファイル(gitで管理できる)
AIからの更新専用ツールやAPIの用意が必要ファイルを直接編集するだけ
本番とステージング中身の同期は別作業gitで自然に揃う
セキュリティ設定との衝突WAFやアクセス制限とぶつかりがちデプロイ経路だけ守ればOK

AIエージェントが得意なのは「ファイルを読んで、書き換えて、gitで管理する」こと。データベースの中身を安全に書き換えるには、今回みたいに専用ツールと運用ルールを用意してあげないといけないんですよね。

以前静的サイトジェネレーターを試したけど素のPHP+HTML構成に戻った話を書きましたが、あのとき感じた「普通のPHP includeの方がいい」という直感が、AIエージェント時代に改めて裏付けられた気がします。体感的にはわかってたんですが文章にして体系化すると面白ーい!!

とはいえCMSが要らなくなるわけじゃなくて、クライアントさん自身が更新するならCMS、制作側がAIで更新するなら静的ファイル、という使い分けがハッキリしてきた、という感じですね。今回の案件みたいに「既にWordPressで動いてるサイト」なら、ツールとルールを整えて繋ぐのが現実解かなと思ってます。

ただ、本当の最適解は、クライアントさん自身が、AIエージェントに頼んで更新できる機能がCMSに入ることだと思うんですよね。実際Wixでは、エディタに組み込まれたAIエージェント(Aria)に話しかけながらサイトを編集できるようになってます。Jimdoにも質問に答えるとサイトを自動で作ってくれるAI機能はありますが、作ったあとに会話で更新していく形まで進んでいるかは確認できませんでした。WordPressの公式MCPの動きも、もしかしたらその方向への一歩なのかもしれません。

これは率直に感じてることなんですが、CMS側にAIエージェントが入れば、クライアントさんの利便性は飛躍的に上がると思います。ただ、セキュリティとの兼ね合いがめちゃくちゃ難しいんですよね。SaaS系のCMSは、AIにどこまで操作させるかかなり悩ましいはずですが、せめてAPIくらいは公開しておかないと、AIエージェント時代に取り残されてやばいんじゃないかと。WordPressみたいなOSSのパッケージ型CMSも、ただでさえ「セキュリティが弱い」と言われがちなのに、AIに操作の入口を開けたらさらに言われそうで、、、きっと悩んでるんだろうなと思います。うーん難い、、、

まとめ

今回の検討と実装で見えてきたのは、

  • WordPressはテーマ(ファイル)と本文(データベース)が分かれていて、AIが触れるのはファイル側だけになりがち
  • 本文をファイルに逃がすとWordPressの機能が使えなくなるので、結局データベース側を操作する手段が必要
  • 自作MCPツールで繋ぐなら、本番・ステージングを分けて、本番の書き込みは必ず人間の確認を挟むルールにする
  • 実際のクライアント依頼も、AIが確認を挟みながら本番更新まで完結できた(ただし本文は丸ごと上書きされる)
  • 新人さんにお願いしてたような簡単な更新作業は、AIエージェントに任せるとあっという間に溶ける(仕事がなくなる)なんて(笑)

という点です。運用を続けてハマったことが出てきたら、また続きを書きたいと思います!

参考になれば幸いです!ツッコミどころあれば連絡くださいね。AIの困りごとあれば相談にのれますよ!