{"id":717,"date":"2026-10-14T14:41:47","date_gmt":"2026-10-14T05:41:47","guid":{"rendered":"https:\/\/mustbethecode.com\/?p=717"},"modified":"2026-10-15T22:21:33","modified_gmt":"2026-10-15T13:21:33","slug":"how-to-connect-claude-to-wordpress","status":"publish","type":"post","link":"https:\/\/mustbethecode.com\/en\/how-to-connect-claude-to-wordpress\/","title":{"rendered":"How to Connect Claude Desktop to WordPress with the MCP Adapter"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">AI assistants are only useful as what they can reach, and for most WordPress site owners that has meant copying and pasting between a chat window and wp-admin. WordPress&#8217;s official MCP Adapter removes that step. It lets clients like Claude work with your site directly, whether that means reading site details or creating draft posts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide is for WordPress owners, developers, and content teams who want to try AI-assisted workflows without building a custom integration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this post, we&#8217;ll walk through installing the MCP Adapter, creating an application password, and connecting Claude Desktop.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Is the MCP Adapter, and Why Does It Matter?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Three pieces work together here:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>MCP (Model Context Protocol) is and open standard that lets AI apps like Claude connect to outside tools and data in a consistent way. Instead of every app building its own integration, a tool exposes itself once as an MCP server and any compatible client can use it.<\/li>\n\n\n\n<li>The Abilities API is WordPress&#8217;s built-in way (as of 6.9) for plugins and core to register the things the site can do, such as &#8220;create a post&#8221; or &#8220;get site info&#8221;. Each ability has a name, a description, and a defined set of inputs and outputs\/<\/li>\n\n\n\n<li>The MCP Adapter is the official plugin that connects the two. It takes the abilities registered on your site and exposes them over MCP, so an AI client can discover them and call them.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Out of the box, the adapter gives clients three tools: one to discover abilities, one to get the details of a specific ability, and one to execute it. The adapter doesn&#8217;t decide what the AI can do. The abilities you register do.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why It Matters<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No more copy-paste: AI can act on your site directly instead of handing you text to move into the dashboard.<\/li>\n\n\n\n<li>You control the scope. AI can only do what has been registered as an ability, and only with the permissions of the WordPress user it logs in as. A create-post ability that defaults to drafts, for example, keeps a human in the loop before anything goes live.<\/li>\n\n\n\n<li>It&#8217;s built on standards. Because it uses MCP and WordPress&#8217;s own API, the same setup works with other compatible clients, not just Claude.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What You Need<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>WordPress 6.9 or later, on a site with HTTPS<\/li>\n\n\n\n<li>Claude Desktop and Node.js (for <code>npx<\/code>)<\/li>\n\n\n\n<li>An admin account to create the credentials<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. Install the plugin<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install and activate <strong>MCP Adapter<\/strong> from the plugin directory.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"543\" src=\"https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-135758-1024x543.webp\" alt=\"search result of mcp adopter plugin\" class=\"wp-image-718\" srcset=\"https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-135758-1024x543.webp 1024w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-135758-300x159.webp 300w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-135758-767x407.webp 767w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-135758.webp 1470w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Find the plugin &#8220;MCP Adapter&#8221; by WordPress.org<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Or with WP-CLI:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wp plugin install https:\/\/github.com\/WordPress\/mcp-adapter\/releases\/latest\/download\/mcp-adapter.zip --activate<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">2. Create an application password<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"543\" src=\"https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-140101-1024x543.webp\" alt=\"user profile application password\" class=\"wp-image-719\" srcset=\"https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-140101-1024x543.webp 1024w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-140101-300x159.webp 300w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-140101-767x407.webp 767w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/screenshot-2026-10-14-140101.webp 1470w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Go to Users \u2192 Profile \u2192 Application Passwords, name it &#8220;Claude&#8221;, and copy the password. Use a dedicated user with only the permissions you want the AI to have, because the password carries that user&#8217;s capabilities.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Configure Claude Desktop<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Go to Settings -> Developer -> Edit Config<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"712\" src=\"https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/Screenshot-2026-10-14-at-2.02.24-PM-1024x712.webp\" alt=\"Claude Desktop Edit Config\" class=\"wp-image-720\" srcset=\"https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/Screenshot-2026-10-14-at-2.02.24-PM-1024x712.webp 1024w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/Screenshot-2026-10-14-at-2.02.24-PM-300x209.webp 300w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/Screenshot-2026-10-14-at-2.02.24-PM-767x533.webp 767w, https:\/\/mustbethecode.com\/wp-content\/uploads\/2026\/10\/Screenshot-2026-10-14-at-2.02.24-PM.webp 1312w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Add this to <code>claude_desktop_config.json<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"mcpServers\": {\n    \"wordpress\": {\n      \"command\": \"npx\",\n      \"args\": &#91;\"-y\", \"@automattic\/mcp-wordpress-remote@latest\"],\n      \"env\": {\n        \"WP_API_URL\": \"https:\/\/your-site.com\/wp-json\/mcp\/mcp-adapter-default-server\",\n        \"WP_API_USERNAME\": \"your-username\",\n        \"WP_API_PASSWORD\": \"your application password\"\n      }\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Fully quit and reopen Claude Desktop, then start a new chat.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Test it<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ask Claude to call <code>mcp-adapter-discover-abilities<\/code>. A working setup lists the abilities your site exposes. Out of the box that&#8217;s only a few read-only core ones (site info, user info, environment info).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting: The 401 Rest_Forbidden Error<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">My first attempt failed with a 401 even though the plugin was working. The cause was an <code>http:\/\/<\/code> URL. WordPress disables application passwords on non-HTTPS sites, and redirects can drop the Authorization header. Switching <code>WP_API_URL<\/code> to <code>https:\/\/<\/code> fixed it. If you still see 401, check the username, the full password, and any security plugin or host rule that strips auth headers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Add real abilities<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The adapter only bridges abilities. Plugins or your own code must register them, for example a <code>create-post<\/code> ability that makes draft posts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is an example from the plugin repository<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/WordPress\/mcp-adapter\/blob\/trunk\/docs\/getting-started\/basic-examples.md\">https:\/\/github.com\/WordPress\/mcp-adapter\/blob\/trunk\/docs\/getting-started\/basic-examples.md<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\/\/ Register the ability\nadd_action( 'wp_abilities_api_init', function() {\n    wp_register_ability( 'my-plugin\/create-post', &#91;\n        'label' => 'Create Post',\n        'description' => 'Creates a new WordPress post with the specified content',\n        'category' => 'site',\n        'input_schema' => &#91;\n            'type' => 'object',\n            'properties' => &#91;\n                'title' => &#91;\n                    'type' => 'string',\n                    'description' => 'The post title',\n                    'minLength' => 1,\n                    'maxLength' => 200\n                ],\n                'content' => &#91;\n                    'type' => 'string',\n                    'description' => 'The post content (HTML allowed)',\n                    'minLength' => 1\n                ],\n                'status' => &#91;\n                    'type' => 'string',\n                    'description' => 'Post status',\n                    'enum' => &#91;'draft', 'publish'],\n                    'default' => 'draft'\n                ],\n                'category' => &#91;\n                    'type' => 'string',\n                    'description' => 'Category name (optional)'\n                ]\n            ],\n            'required' => &#91;'title', 'content']\n        ],\n        'output_schema' => &#91;\n            'type' => 'object',\n            'properties' => &#91;\n                'post_id' => &#91;\n                    'type' => 'integer',\n                    'description' => 'The ID of the created post'\n                ],\n                'post_url' => &#91;\n                    'type' => 'string',\n                    'description' => 'The URL of the created post'\n                ],\n                'edit_url' => &#91;\n                    'type' => 'string',\n                    'description' => 'The admin edit URL'\n                ]\n            ]\n        ],\n        'execute_callback' => function( $input ) {\n            if ( empty( $input&#91;'title'] ) ) {\n                return new \\WP_Error( 'missing_title', 'Post title is required.' );\n            }\n\n            $post_data = array(\n                'post_title'   => sanitize_text_field( $input&#91;'title'] ),\n                'post_content' => wp_kses_post( $input&#91;'content'] ),\n                'post_status'  => in_array( $input&#91;'status'], array( 'draft', 'publish' ), true ) ? $input&#91;'status'] : 'draft',\n                'post_type'    => 'post',\n            );\n            \n            \/\/ Handle category if provided\n            if ( ! empty( $input&#91;'category'] ) ) {\n                $category = get_category_by_slug( sanitize_title( $input&#91;'category'] ) );\n                if ( ! $category ) {\n                    \/\/ Create category if it doesn't exist\n                    $category_id = wp_create_category( $input&#91;'category'] );\n                } else {\n                    $category_id = $category->term_id;\n                }\n                $post_data&#91;'post_category'] = &#91; $category_id ];\n            }\n            \n            $post_id = wp_insert_post( $post_data );\n            \n            if ( is_wp_error( $post_id ) ) {\n                throw new Exception( 'Failed to create post: ' . $post_id->get_error_message() );\n            }\n            \n            return &#91;\n                'post_id' => $post_id,\n                'post_url' => get_permalink( $post_id ),\n                'edit_url' => get_edit_post_link( $post_id, 'raw' )\n            ];\n        },\n        'permission_callback' => function() {\n            return current_user_can( 'publish_posts' );\n        },\n        'meta' => &#91;\n            'public' => true, \/\/ Expose to clients, including MCP\n            'annotations' => &#91;\n                'priority' => 2.0,\n                'readOnlyHint' => false,\n                'destructiveHint' => false\n            ]\n        ]\n    ]);\n});<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can make this as a plugin and add it to your website.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Closing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now you can use AI to manage your WordPress website.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is a new feature so the ecosystem around this is not that big now, so keep that it mind when finding abilities.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can find more information on<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/WordPress\/mcp-adapter\">https:\/\/github.com\/WordPress\/mcp-adapter<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>AI assistants are only useful as what they can reach, and for most WordPress site owners that has meant copying and pasting between a chat window and wp-admin. WordPress&#8217;s official MCP Adapter removes that step. It lets clients like Claude work with your site directly, whether that means reading site details or creating draft posts. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":722,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_locale":"en_US","_original_post":"https:\/\/mustbethecode.com\/?p=716","footnotes":""},"categories":[9],"tags":[],"class_list":["post-717","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized-ko","en-US"],"acf":[],"mb":[],"mfb_acf":[],"mfb_rest_fields":["title"],"_links":{"self":[{"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/posts\/717","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/comments?post=717"}],"version-history":[{"count":3,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/posts\/717\/revisions"}],"predecessor-version":[{"id":724,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/posts\/717\/revisions\/724"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/media\/722"}],"wp:attachment":[{"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/media?parent=717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/categories?post=717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mustbethecode.com\/wp-json\/wp\/v2\/tags?post=717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}