Table of Contents
はじめに
この記事では、WordPress 6.9 の mcp-adapter プラグインを使って、Claude Desktop アプリから直接 WordPress へ投稿できるようにするまでの手順をまとめます。
全体の構成
Claude Desktop → mcp-wordpress-remote(npx)→ mcp-adapter(WordPressプラグイン)→ Abilities API(WordPress 6.9 コア)という流れでデータがやり取りされます。
STEP 1|mcp-adapter プラグインをインストール
- GitHub Releases から最新の mcp-adapter.zip をダウンロード
- WordPress管理画面 → プラグイン → 新規追加 → プラグインのアップロード でインストール
- 有効化する
STEP 2|投稿用 Ability プラグインを作成
wp-content/plugins/wp-post-abilities/wp-post-abilities.php を作成し、get-posts / create-post / update-post の3つの Ability を登録します。各 Ability に meta.mcp.public = true を設定することが必須です。以下のコードを保存したら、インストール済みプラグインの画面で追加したプラグインを有効にしてください。
wp-post-abilities.php のコード
<?php
/**
* Plugin Name: Enable Core Abilities for MCP
* Version: 1.0.0
*/
add_filter( 'wp_register_ability_args', 'enable_core_abilities_mcp_access', 10, 2 );
function enable_core_abilities_mcp_access( array $args, string $ability_name ) {
$core_abilities = [
'core/get-site-info',
'core/get-user-info',
'core/get-environment-info',
];
if ( in_array( $ability_name, $core_abilities, true ) ) {
$args['meta']['mcp']['public'] = true;
}
return $args;
}
if ( ! defined( 'ABSPATH' ) ) exit;
// ── カテゴリーは専用フックで登録 ──────────────────
add_action( 'wp_abilities_api_categories_init', function() {
wp_register_ability_category( 'posts', [
'label' => '投稿',
'description' => 'WordPress投稿の管理',
] );
} );
// 変更後(優先度を下げて遅めに実行)
add_action( 'wp_abilities_api_init', 'register_post_abilities_for_mcp', 20 );
function register_post_abilities_for_mcp() {
// ── 投稿一覧取得 ──────────────────────────────
wp_register_ability( 'posts/get-posts', [
'label' => '投稿一覧を取得',
'description' => 'WordPressの投稿を一覧取得します',
'category' => 'posts',
'input_schema' => [
'type' => 'object',
'properties' => [
'numberposts' => [ 'type' => 'integer', 'default' => 10, 'minimum' => 1, 'maximum' => 100 ],
'post_status' => [ 'type' => 'string', 'enum' => ['publish','draft','private'], 'default' => 'publish' ],
],
],
'output_schema' => [ 'type' => 'array' ],
'execute_callback' => function( $input ) {
return get_posts([
'numberposts' => $input['numberposts'] ?? 10,
'post_status' => $input['post_status'] ?? 'publish',
'post_type' => 'post',
]);
},
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
'meta' => [ 'mcp' => [ 'public' => true ] ],
] );
// ── 投稿作成 ──────────────────────────────────
wp_register_ability( 'posts/create-post', [
'label' => '投稿を作成',
'description' => '新しい投稿を作成します',
'category' => 'posts',
'input_schema' => [
'type' => 'object',
'required' => ['title', 'content'],
'properties' => [
'title' => [ 'type' => 'string', 'description' => '投稿タイトル' ],
'content' => [ 'type' => 'string', 'description' => '投稿本文' ],
'status' => [ 'type' => 'string', 'enum' => ['publish','draft'], 'default' => 'draft' ],
],
],
'output_schema' => [ 'type' => 'object' ],
'execute_callback' => function( $input ) {
$post_id = wp_insert_post( [
'post_title' => sanitize_text_field( $input['title'] ),
'post_content' => wp_kses_post( $input['content'] ),
'post_status' => $input['status'] ?? 'draft',
'post_type' => 'post',
], true );
if ( is_wp_error( $post_id ) ) {
return [ 'success' => false, 'message' => $post_id->get_error_message() ];
}
return [ 'success' => true, 'post_id' => $post_id, 'edit_url' => get_edit_post_link( $post_id, 'raw' ) ];
},
'permission_callback' => function() {
return current_user_can( 'publish_posts' );
},
'meta' => [ 'mcp' => [ 'public' => true ] ],
] );
// ── 投稿更新 ──────────────────────────────────
wp_register_ability( 'posts/update-post', [
'label' => '投稿を更新',
'description' => '既存の投稿を更新します',
'category' => 'posts',
'input_schema' => [
'type' => 'object',
'required' => ['post_id'],
'properties' => [
'post_id' => [ 'type' => 'integer', 'description' => '更新する投稿のID' ],
'title' => [ 'type' => 'string' ],
'content' => [ 'type' => 'string' ],
'status' => [ 'type' => 'string', 'enum' => ['publish','draft','private'] ],
],
],
'output_schema' => [ 'type' => 'object' ],
'execute_callback' => function( $input ) {
$args = [ 'ID' => (int) $input['post_id'] ];
if ( isset( $input['title'] ) ) $args['post_title'] = sanitize_text_field( $input['title'] );
if ( isset( $input['content'] ) ) $args['post_content'] = wp_kses_post( $input['content'] );
if ( isset( $input['status'] ) ) $args['post_status'] = $input['status'];
$result = wp_update_post( $args, true );
if ( is_wp_error( $result ) ) {
return [ 'success' => false, 'message' => $result->get_error_message() ];
}
return [ 'success' => true, 'post_id' => $result ];
},
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
'meta' => [ 'mcp' => [ 'public' => true ] ],
] );
}
STEP 3|Application Password を発行
WordPress管理画面 → ユーザー → プロフィール → アプリケーションパスワードセクションで「Claude Desktop」用のパスワードを発行します。
STEP 4|Node.js をインストール
nodejs.org から LTS 版をインストールし、which npx で絶対パスを確認します。
STEP 5|claude_desktop_config.json を編集
{
"mcpServers": {
"wordpress-mcp-server": {
"command": "/usr/local/bin/npx",
"args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
"env": {
"WP_API_URL": "https://yoursite.example/wp-json/mcp/mcp-adapter-default-server",
"WP_API_USERNAME": "WordPressのユーザー名",
"WP_API_PASSWORD": "Application Password"
}
}
}
}
command には npx の絶対パスを指定することが重要です。
STEP 6|動作確認
Claude Desktop を完全に再起動し「WordPressの最新10件の投稿を見せて」と入力して確認します。
よくあるエラーと対処
- Failed to spawn process → npx の絶対パスを指定する
- rest_no_route (404) → mcp-adapter が無効。有効化後にパーマリンクを再保存
- rest_forbidden (401) → ブラウザ直接アクセス時は正常。Claude Desktop 側の認証情報を確認
- ツールが表示されない → meta.mcp.public = true が設定されているか確認

コメント