AIとWordPressをMCPで繋ぐ(Claude Opus 5版)

ブログを書いていて、いちばん面倒なのは「書く」ことそのものではありません。
書き終わったあとに管理画面を開き、囲み枠を作り、コードエディターに切り替え、プレビューで崩れを確認し、また戻る——この往復です。

WordPress 6.9 で Abilities API がコアに入り、MCP Adapter が公式プラグインとして整備されたことで、この往復をターミナルの中に畳み込めるようになりました。
この記事では、Claude Code から WordPress へ直接下書きを投稿するところまでを解説します。
また、MCPを使って記事毎にバップアップをとるのにMCPが使えるかについての調査も行う。


注)本記事の内容は正確性を保証するものではない。

(2026年8月11日 追記)YouTube動画を追加しました。 https://youtu.be/_t9dA2lTJ84

目次

この記事でできるようになること

  • Claude Code から WordPress の記事一覧を取得する
  • 手元の Markdown を、そのまま下書きとして投稿する
  • 質疑応答のログから記事の下書きを生成する

また、独自記法(:::note)を 、下図のSWELL のキャプションボックスに自動変換する方法を検討する。

キャプションボックス

全体の流れ

記事作成の手順

まず、ブログ執筆者とClaude Opus 5が、記事のテーマについて質疑応答を繰り返しClaude Opus 5が、それらの質疑応答の内容をまとめてブログ記事の下書きを作成する。
その際、図解を挿入した方が良い場合は、後でCodexが図解を作成できるように、図解の挿入箇所にClaude Opus 5が図解の説明を挿入する。

次に、拡張機能でClaude Codeを導入したVS Codeで下書きを開き、ブログ執筆者が加筆・修正を加える。
その際、予め設定した「独自記法(:::note)」を、記事中に挿入する。その独自記法で追記された箇所は最終的には「キャプションボックス」のようなSwellブロックとなる。
また、「独自記法(【質問】)」で追加質問内容を記事中に追記しておくと、Claude Opus 5が回答をその箇所に挿入する。

加筆・修正された下書きを、Claude Opus 5がMCPを利用してWordPressに出力する。
その際、Claude Opus 5がAbilitiesレジストリを読んでどのツールを呼べばいいかを判断する。
呼ばれたツールが記事内容を投稿DBに書き込む。

前提知識:Ability とは何か

MCP 連携の話に入る前に、土台となる Abilities API を押さえます。

Ability とは、WordPress の中にある機能を、AI や他のプラグインから見つけて呼び出せる形で登録したものです。
Home Assistant のサービス(light.turn_on のように、名前・引数スキーマ・実行処理がセットで登録されているもの)を思い浮かべると近いかもしれません。

Ability は namespace/ability-name 形式の一意な名前を持ち、次の要素で構成されます。

要素役割
label / descriptionAI が読む仕様書。何ができるか、いつ使うか
input_schema引数の型と説明(JSON Schema)
output_schema戻り値の型
execute_callback実処理。ここだけが普通の PHP
permission_callback権限チェック

重要なのは、description が飾りではないという点です。
AI エージェントはこの説明文を読んで「どのツールをどう呼べばいいか」を判断します。
説明のないスキーマは、この API の存在意義を失わせます。

(補足)Abilities API は WordPress 6.9 からコアに含まれているため、別途プラグインを入れる必要はありません。6.9 未満の場合のみ、abilities-api.zip を別途導入します。

そして権限チェックは実行前に効きます。
execute() は権限チェックと入力バリデーションを自動で行い、どちらかが失敗した時点でコールバックに到達する前にエラーを返します。
AI に自由文で操作させる怖さを、型と権限で押さえ込む設計です。

MCP Adapter の導入

注意:情報が古い記事に気をつける

まずここでつまずきます。
Automattic/wordpress-mcp は2026年1月にアーカイブされました。
公式の後継は WordPress/mcp-adapter です。
ネット上の解説記事はまだ古い方を前提にしたものが多く残っているため、リポジトリ名を確認してから読んでください。

手順

① 専用ユーザーを作る

管理者アカウントで繋がないでください。
アプリケーションパスワードは API トークンと同等で、それを持つ者はそのユーザーとして行動できます。
プラグイン操作が不要なら、権限グループは「編集者」で十分です。

② プラグインを導入する

https://github.com/WordPress/mcp-adapter/releases から最新の mcp-adapter.zip をダウンロードし、「プラグイン → 新規追加 → プラグインのアップロード」で導入します。

WP-CLI が使えるなら1行です。

wp plugin install https://github.com/WordPress/mcp-adapter/releases/latest/download/mcp-adapter.zip --activate

③ 疎通確認

有効化すると既定サーバーが自動登録されます。
ブラウザで開いて JSON が返れば成功です。

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

404 が出たら「設定 → パーマリンク」で「変更を保存」を押し、リライトルールを再生成してください。

④ アプリケーションパスワードを発行

専用ユーザーの編集画面下部で生成します。この値は一度しか表示されないので、その場で控えてください。

⑤ Claude Code に登録

printf 'mcp-bot:xxxx yyyy zzzz aaaa bbbb cccc' | base64
claude mcp add --transport http roompine \
  https://example.com/wp-json/mcp/mcp-adapter-default-server \
  --header "Authorization: Basic <上で得た文字列>"

claude mcp add は保存時に認証情報を検証しません。
値が間違っていても登録は通り、後で接続に失敗します。
/mcp で「connected」を必ず確認してください。

Ability を自作する

導入自体はここまでですが、有効化で公開されるのはアダプター自身のコア Ability が3つだけです。
実際に記事を扱うには、自分で Ability を登録する必要があります。

公式ブログも「まずは破壊的でない読み取り専用の ability を少数公開するところから始めよ」と推奨しています。
ここでは投稿一覧を返すだけのものを作ります。

add_action( 'wp_abilities_api_init', function () {
    if ( ! function_exists( 'wp_register_ability' ) ) {
        return;
    }

    wp_register_ability(
        'roompine/list-posts',
        array(
            'label'       => '投稿の一覧を取得',
            'description' => '投稿を新しい順に取得する。タイトル・ID・公開状態・日付・URLを返す。'
                . '既存記事の確認や、内部リンク先を探す用途に使う。',
            'category'    => 'roompine',
            'input_schema' => array(
                'type'       => 'object',
                'properties' => array(
                    'number' => array(
                        'type'        => 'integer',
                        'description' => '取得する件数。1〜50。省略時は10。',
                        'minimum'     => 1,
                        'maximum'     => 50,
                    ),
                ),
                'required'   => array(),
            ),
            'execute_callback'    => 'roompine_ability_list_posts',
            'permission_callback' => function () {
                return current_user_can( 'edit_posts' );
            },
            'meta' => array(
                'mcp' => array( 'public' => true ),
            ),
        )
    );
} );

これをプラグインとして設置し、Claude Code で /mcp を開いてツール一覧に出ていれば成功です。「最近の投稿を5件教えて」で一覧が返ります。

独自記法を SWELL のブロックに変換する

読み取りが通ったら、書き込み側に進みます。ここで設計上いちばん重要な判断があります。

ブロックマークアップを AI に生成させない

SWELL のキャプションボックスなどは静的ブロックで、保存された HTML がそのまま post_content に書き込まれます。
ブロックエディタは記事を開くたびに、保存されている HTML が「そのブロックの save 関数が出力するはずの HTML」と一致するか照合します。

クラス名が1つ違う、div の入れ子が1段違う、それだけで「このブロックには、予期しないエラーが含まれています」が出て装飾が壊れます。

そこで、変換は WordPress 側の execute_callback の中で行います。
Claude が書くのはマーカー付きの Markdown だけです。

:::note
(補足)ここに補足文が入ります。
:::

これを PHP 側で正規表現により検出し、あらかじめ管理画面からコピーしておいた SWELL の実マークアップに差し込みます。

テンプレートは実物から採る

使う予定のブロックを管理画面で1回ずつ作り、エディタ右上の「︙ → コードエディター」から <!-- wp:loos/... --> を丸ごとコピーしておきます。
これが変換処理の正解データになります。
推測で書くと、ほぼ確実に検証エラーになります。

(補足)SWELL ブロックは SWELL 依存のため、将来テーマを変えると単なる div になります。
とはいえ使い続ける前提なら、既存記事との統一感のほうが実利は大きいでしょう。

執筆ワークフロー全体

ここまでの部品を組み合わせると、次の流れになります。

ディレクトリ構成

roompine-blog/
├── CLAUDE.md                    # 記法・文体・禁止事項
├── .mcp.json                    # WordPress接続設定
├── .claude/
│   ├── skills/qa-to-draft/SKILL.md
│   └── commands/answer.md
├── templates/swell-blocks.md    # SWELLブロックの実マークアップ
├── qa/                          # 素材(質疑応答ログ)
├── drafts/                      # 下書き
└── figures/                     # 図解画像

① 素材を置く

質疑応答を qa/ に Markdown で保存します。
Claude Code 内の質疑応答なら /export qa/2026-08-09-wp-mcp.md で書き出します。

ファイルにしておく理由は、コンテキストの自動圧縮を切り離すためです。
セッションが長くなると序盤のやりとりは要約された状態でしか残らず、「まとめて」と頼んだのに前半だけ妙に大雑把な記事になります。
ファイルになった時点で内容は確定します。

② 下書きを生成させる

qa/2026-08-09-wp-mcp.md をまとめて下書きを作って

この時点で、図解が要る箇所には、例えば、下記のような説明文が挿入されます。

[図解: WordPressコア内のAbilityレジストリを中心に置き、左からプラグインが
wp_register_ability で登録する矢印、右へmcp-adapterがMCPツールへ変換して
Claude Codeに公開する矢印。3層の横並び構成]
説明文に従って別途作成した図解例

③ 手直しする

VS Code で開いて読みながら直します。ここで書き足せるマーカーは4種類です。

マーカー意味
【質問】その場に回答を挿入させる
【要調査】検索して裏を取ってから書かせる
【要確認】AI が確証を持てなかった箇所(自動で付く)
【TODO】人間がやる。触らせない

読んでいる途中で疑問が湧いたら、その場に 【質問】 と書いておくだけです。
あとで一括処理すると、前後の文脈を踏まえた説明がその位置に挿入されます。
チャットで単独に質問すると一般論が返ってきますが、ファイル内に置かれていれば「この記事のこの流れで、この読者に向けた説明」になります。

実行前に git commit しておいてください。複数箇所を一度に処理させると差分が広範囲になり、意図しない改変が混ざったときの切り分けが面倒になります。

④ 図解を作る

[図解: …] の説明文をもとに画像を作りfigures/ に保存してマーカーを差し替えます。
ここは手作業が残りますが、何を描くかは既に文章化されているので迷いません。

⑤ WordPress へ送る

drafts/wp-mcp.md を下書きとして投稿して

変換は PHP 側で決定論的に行われるため、ブロック検証エラーは起きません。

⑥ 管理画面で仕上げ

アイキャッチ、カテゴリー、メタディスクリプション、内部リンク。プレビューで確認して公開します。

設計の要点

この構成を通して守っているルールは3つです。

変換は PHP、判断は AI、決定は人間。

ブロックマークアップを AI に生成させない。
事実確認できないものは書かせず 【要確認】 に逃がす。
投稿は必ず下書きにして、公開は人間が押す。

ファイルが唯一の正。

チャットの履歴ではなく qa/ と drafts/ が実体です。
セッションが切れても、日をまたいでも、別のツールを行き来しても壊れません。

小さく始める。

読み取り専用の Ability を1つ通してから、書き込みを足す。
いきなり本番サイトに繋がない。

まとめ

Abilities API と MCP Adapter は、まだ発展途上のコンポーネントです。
実際、公式ドキュメントにも「これらの構成要素は急速に変化しているため、インストール手順は変わる可能性がある」と注記されています。

それでも、記事を書く場所と公開する場所が分断されているという長年の不便に、初めて筋の通った解決策が出てきたのは確かです。
管理画面を開かずに記事が出せるようになると、書く量が変わります。

今後、:::note を SWELL のキャプションボックスに変換する create-draft Ability の実装などを行う必要があります。

(参考)ブログ記事毎の圧縮バックアップにMCPが使えるか

WordPressの特定のプラグインを使えば、記事のバックアップ及び復元が可能だが、復元するのが難しそうなので、1つの記事を作成し公開した段階で、その記事の圧縮バックアップ(中身はHTMLファイル、画像ファイルなど)を外部SSDに保存する方法について、Claude Opus 5に相談した。


(以下、CLaude Opus 5の回答)

できます。ただ、この用途に MCP を使うのは勧めません。 理由を先に説明させてください。

MCP を挟まないほうがいい理由

バックアップは「毎回まったく同じ結果になること」が価値の全てです。
AI を経路に入れると、判断が挟まる分だけ非決定的になります。
ファイル名の付け方が微妙に揺れる、画像を1枚取りこぼす、といった事故が起きたとき、それに気づくのは復元しようとした瞬間です。

必要なのは WordPress の REST API とアプリケーションパスワードだけで、これは MCP 導入時にすでに揃っています。
素のスクリプトで完結します。

Claude Code の出番は「スクリプトを書く」「エラーが出たとき調べる」であって、毎回の実行経路に居座る必要はありません。

設計上の落とし穴が4つあります

① HTML ではなくブロックマークアップを保存する

これが最重要です。
レンダリング後の HTML を保存して貼り付け直すと、SWELL のブロックはすべてただの div になります。
保存すべきは post_content の生データ、つまり <!-- wp:loos/cap-block --> を含むブロックマークアップです。

REST API で ?context=edit を付けると content.raw として取得できます。
復元時はビジュアルエディタではなくコードエディタに貼るのが正解です。

② ファイル名にタイトルをそのまま使えない

日本語タイトルには / : ? などが混ざることがあり、macOS と Windows で扱いが違います。
また同名タイトルの記事があると上書きされます。

1234_Claude CodeとWordPressをMCPで繋ぐ.zip のように記事の ID を頭に付けることを勧めます。
一意性が保証され、番号順に並び、タイトルも読めます。

③ 画像 URL の張り直しが復元の弱点

貼り付けた本文の画像 URL は、旧記事のメディアを指しています。
メディアライブラリごと失われている状況で復元するなら、画像を再アップロード → URL を一括置換、という手順が必ず要ります。

なので ZIP には画像そのものに加えて、「元 URL とファイル名の対応表」を必ず入れておきます。
これが無いと、どの画像がどこに入るのか分からなくなります。

④ ZIP を作ったら必ず開いて検証する

壊れたバックアップは無いより悪いです。
書き込み後に読み直して、想定したファイルが全部入っているか確認する処理を入れます。


これらを踏まえたスクリプトを書けば実現できます。

環境変数を ~/.zshrc に入れておきます。MCP 用に作ったアプリケーションパスワードを流用できます。

export WP_URL="https://roompine.com"
export WP_USER="mcp-bot"
export WP_APP_PASSWORD="xxxx yyyy zzzz aaaa bbbb cccc"
export WP_BACKUP_DIR="/Volumes/SSD/roompine-backup"

公開直後に走らせるだけです。

python3 backup-post.py 1234
python3 backup-post.py --latest 5     # 移行時のまとめ取り

SSD が未マウントのときは保存先の親ディレクトリが存在しないので、書き込みを試みる前に止まります。
気づかないまま内蔵ディスクに保存されている、という事態を避けるためです。

残っている判断

自動実行にするかどうか。
WordPress 側のフックで公開を検知しても、書き込み先はサーバーになるので外部 SSD には届きません。
ローカルからの実行が前提になります。

現実的な選択肢は3つです。

方式実態
手動実行公開後にターミナルで1行。取りこぼす可能性はある
launchd で定期実行--latest 10 を毎晩。ID を意識しなくて済む
Claude Code から「1234をバックアップして」で実行。ついでに結果も読ませられる

私は定期実行+手動の併用を勧めます。
定期実行を保険にしておけば、手動を忘れても数時間以内には拾えます。

世代管理をどうするか。
現状は同じ ID を再実行すると上書きされます。
記事を大きく書き換えた際に旧版を残したいなら、ファイル名に日付を足す形(1234_タイトル_20260809.zip)に変えられます。
ただし容量は増えるので、記事数と SSD の余裕次第です。


もともと、一時的にプラグイン「LIQUID SPEECH BALLOON」(ふきだし)が使えなくなり、その代替えブロックとして、Swell純正のふきだしに全て置き換えるかを検討した際、MCPを使って一括して置き換えられないかを確認したいと思い、本記事の調査を行った。今記事はClaude Opus 5に相談して作成したものであるが、ChatGPT-5.6 Solにも同様の質疑応答を行なって別記事を作成する予定なので、その内容も考慮し、現時点のMCPの活用方法を決めていきたい。
また、今回、プラグインのブロックが一時的に使えなくなり、公開済みの記事が全て変わってしまったため、記事毎のバックアップの必要性を感じ、簡単に記事毎に復元できるバックアップというテーマについても調査を行った。

Claude Opus 5に記事の下書きを依頼して感じたのは、賢いためか、回答が短くて個性が強い、言葉足らずな下書きであるということだった。そのため、言い回しを修正したり、どういう言葉を補絵ばいいかを検討するのに手間がかかった。モデルを変更したり、どのような口調で回答してと指示した方がよかったのかもしれない。ChatGPT-5.6 Solの方が、より一般的な言い回しで長く回答されそうであり、言葉を補う必要がない回答、むしろ余分な部分を削除する必要がある回答が返ってくるのではないかと思う。

目次