{"id":4653,"date":"2026-04-08T18:41:17","date_gmt":"2026-04-08T18:41:17","guid":{"rendered":"https:\/\/frontlinenewsng.org\/?p=4653"},"modified":"2026-04-08T18:41:17","modified_gmt":"2026-04-08T18:41:17","slug":"weston-ruter-adding-an-mcp-server-to-the-wordpress-core-development-environment","status":"publish","type":"post","link":"https:\/\/frontlinenewsng.org\/?p=4653","title":{"rendered":"Weston Ruter: Adding an MCP Server to the WordPress Core Development Environment"},"content":{"rendered":"<p class=\"wp-block-paragraph\">I wanted to hook up Claude Code to be able to interact with my local <a href=\"https:\/\/github.com\/WordPress\/wordpress-develop\">wordpress-develop<\/a> core development environment via MCP (Model Context Protocol). I couldn\u2019t find documentation specifically for doing this, so I\u2019m sharing how I did it here.<\/p>\n<p class=\"wp-block-paragraph\">Assuming you have <a href=\"https:\/\/github.com\/WordPress\/wordpress-develop#getting-started\">set up the environment<\/a> (with Docker) and started it via <code>npm run env:start<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">1. Install &amp; Activate the MCP Adapter plugin<\/h2>\n<p class=\"wp-block-paragraph\">The MCP adapter is not currently available as a plugin to install from the plugin directory. You instead have to obtain it from GitHub and <a href=\"https:\/\/github.com\/WordPress\/mcp-adapter#installation\">install<\/a> it from the command line. I <a href=\"https:\/\/github.com\/WordPress\/mcp-adapter#as-a-plugin-alternative-method\">installed it as a plugin<\/a> instead of as a Composer package:<\/p>\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-shell\">cd src\/wp-content\/plugins\ngit clone https:\/\/github.com\/WordPress\/mcp-adapter\ncd mcp-adapter\ncomposer install<\/code><\/span><\/pre>\n<p class=\"wp-block-paragraph\">Next,  activate the plugin. Naturally, you can also just activate the \u201cMCP Adapter\u201d plugin from the WP admin. You can also activate it via WP-CLI (but from the project root working directory, since you can\u2019t run this command from inside of the <code>mcp-adapter<\/code> directory:<\/p>\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-shell\">npm run env:cli -- plugin activate mcp-adapter<\/code><\/span><\/pre>\n<h2 class=\"wp-block-heading\">2. Register the MCP server with Claude<\/h2>\n<p class=\"wp-block-paragraph\">Here\u2019s the command I used to register the <code>wordpress-develop<\/code> MCP server with Claude:<\/p>\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-shell shcb-wrap-lines\">claude mcp add-json wordpress-develop --scope user '{\"command\":\"npm\", \"args\":[\"--prefix\", \"~\/repos\/wordpress-develop\/\", \"run\", \"env:cli\", \"--\", \"mcp-adapter\", \"serve\", \"--server=mcp-adapter-default-server\", \"--user=admin\"]}'<\/code><\/span><\/pre>\n<p class=\"wp-block-paragraph\">Here\u2019s the JSON with formatting:<\/p>\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-json\">{\n\t<span class=\"hljs-attr\">\"command\"<\/span>: <span class=\"hljs-string\">\"npm\"<\/span>,\n\t<span class=\"hljs-attr\">\"args\"<\/span>: [\n\t\t<span class=\"hljs-string\">\"--prefix\"<\/span>,\n\t\t<span class=\"hljs-string\">\"~\/repos\/wordpress-develop\/\"<\/span>,\n\t\t<span class=\"hljs-string\">\"run\"<\/span>,\n\t\t<span class=\"hljs-string\">\"env:cli\"<\/span>,\n\t\t<span class=\"hljs-string\">\"--\"<\/span>,\n\t\t<span class=\"hljs-string\">\"mcp-adapter\"<\/span>,\n\t\t<span class=\"hljs-string\">\"serve\"<\/span>,\n\t\t<span class=\"hljs-string\">\"--server=mcp-adapter-default-server\"<\/span>,\n\t\t<span class=\"hljs-string\">\"--user=admin\"<\/span>\n\t]\n}<\/code><\/span><\/pre>\n<p class=\"wp-block-paragraph\">You may want to remove <code>--scope user<\/code> if you just want to register the MCP server for the one project. I tend to re-use the same WP environment for multiple projects (core and plugins), so I think it may make it easier for me to install at the user level instead.<\/p>\n<p class=\"wp-block-paragraph\">You will also need to change the <code>--prefix<\/code> arg\u2019s <code>~\/repos\/wordpress-develop\/<\/code> value to correspond to where the repo is actually cloned on your system. I include this arg here so that when I start <code>claude<\/code> inside of a plugin project (e.g. inside <code>src\/wp-content\/plugins\/performance<\/code>), it is able to successfully run the <code>npm<\/code> command in the <code>package.json<\/code> in the ancestor directory. You can remove this <code>--prefix<\/code> arg if this is not relevant to you.<\/p>\n<p class=\"wp-block-paragraph\">Change the user from <code>admin<\/code> according to your needs.<\/p>\n<h2 class=\"wp-block-heading\">3. Expose all abilities to MCP<\/h2>\n<p class=\"wp-block-paragraph\">Registered abilities are not exposed to MCP by default. This is a safety measure so that AI agents have to be explicitly allowed to perform potentially sensitive actions. So without any plugins active other than the MCP Adapter, prompting Claude with \u201cdiscover abilities\u201d results in:<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">No abilities found. The MCP server connection may be unstable. Try reconnecting again with <code>\/mcp<\/code>.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">However, since this is a local development environment, there is no concern about this (for me at least). To opt in all abilities to be exposed to MCP by default, you can use the following plugin code:<\/p>\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-php\">add_filter(\n\t<span class=\"hljs-string\">'wp_register_ability_args'<\/span>,\n\t<span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">( array $args, string $ability_id )<\/span>: <span class=\"hljs-title\">array<\/span> <\/span>{\n\t\t<span class=\"hljs-keyword\">if<\/span> (\n\t\t\t<span class=\"hljs-comment\">\/\/ Prevent exposing abilities in MCP except on a local dev environment.<\/span>\n\t\t\twp_get_environment_type() === <span class=\"hljs-string\">'local'<\/span>\n\t\t\t&amp;&amp;\n\t\t\t<span class=\"hljs-comment\">\/\/ Omit abilities which the MCP Adapter already makes available itself.<\/span>\n\t\t\t! str_starts_with( $ability_id, <span class=\"hljs-string\">'mcp-adapter\/'<\/span> )\n\t\t) {\n\t\t\t$args[<span class=\"hljs-string\">'meta'<\/span>][<span class=\"hljs-string\">'mcp'<\/span>][<span class=\"hljs-string\">'public'<\/span>] = <span class=\"hljs-keyword\">true<\/span>;\n\t\t}\n\t\t<span class=\"hljs-keyword\">return<\/span> $args;\n\t},\n\t<span class=\"hljs-number\">10<\/span>,\n\t<span class=\"hljs-number\">2<\/span>\n);<\/code><\/span><\/pre>\n<p class=\"wp-block-paragraph\">This is also available in a <a href=\"https:\/\/gist.github.com\/westonruter\/3a37d35ef66cdd58315a7c1347d92560\">gist<\/a> to facilitate installation via <a href=\"https:\/\/git-updater.com\/\">Git Updater<\/a>.<\/p>\n<p class=\"wp-block-paragraph\">Note: This filter does not currently apply if your ability is registered by extending <code>Abstract_Ability<\/code> in the AI plugin.<\/p>\n<p class=\"wp-block-paragraph\">At this point, I can now open Claude (or re-connect to the MCP server) and see that it is able to see all (er, most) abilities that are registered on my wordpress-develop env with the same prompt \u201cdiscover abilities\u201d:<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>3 WordPress abilities<\/strong> available:<\/p>\n<p class=\"wp-block-paragraph\"><strong>core\/get-environment-info<\/strong> \u2014 Returns runtime context (PHP, database, WordPress version) with the ability name.<\/p>\n<p class=\"wp-block-paragraph\"><strong>core\/get-site-info<\/strong> \u2014 Returns site information (all fields or filtered subset)<\/p>\n<p class=\"wp-block-paragraph\"><strong>core\/get-user-info<\/strong> \u2014 Returns current user profile details<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">When I prompt \u201cwhat\u2019s the environment info?\u201d it executes the <code>core\/get-environment-info<\/code> ability via MCP and prints out:<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<ul class=\"wp-block-list\">\n<li><strong>Environment<\/strong>: local<\/li>\n<li><strong>PHP Version<\/strong>: 8.3.26<\/li>\n<li><strong>Database Server<\/strong>: 8.4.8 (MySQL)<\/li>\n<li><strong>WordPress Version<\/strong>: 7.1-alpha-62161-src<\/li>\n<\/ul>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">Now the environment just needs more abilities! I\u2019ve filed a Performance Lab <a href=\"https:\/\/github.com\/WordPress\/performance\/issues\/2441\">issue<\/a> for us at the Core Performance table to work on adding abilities during <a href=\"https:\/\/asia.wordcamp.org\/2026\/contributor-day\/\">Contributor Day<\/a> at <a href=\"https:\/\/asia.wordcamp.org\/2026\/\">WordCamp Asia<\/a> tomorrow.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n<p class=\"has-medium-font-size wp-block-paragraph\">Where I\u2019ve shared this:<\/p>\n<ul class=\"wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex\">\n<li class=\"wp-social-link wp-social-link-linkedin  wp-block-social-link\"><a class=\"wp-block-social-link-anchor\" href=\"https:\/\/www.linkedin.com\/posts\/westonruter_adding-an-mcp-server-to-the-wordpress-core-share-7447717681786617856-Fo0y?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAACIeJ0BUsdEu-G5aiGg1JkXrMQ-C6tbCsI\"><span class=\"wp-block-social-link-label screen-reader-text\">LinkedIn<\/span><\/a><\/li>\n<li class=\"wp-social-link wp-social-link-twitter  wp-block-social-link\"><a class=\"wp-block-social-link-anchor\" href=\"https:\/\/x.com\/westonruter\/status\/2041952919378129271\"><span class=\"wp-block-social-link-label screen-reader-text\">Twitter<\/span><\/a><\/li>\n<li class=\"wp-social-link wp-social-link-bluesky  wp-block-social-link\"><a class=\"wp-block-social-link-anchor\" href=\"https:\/\/bsky.app\/profile\/weston.ruter.net\/post\/3miyxsxvnek2y\"><span class=\"wp-block-social-link-label screen-reader-text\">Bluesky<\/span><\/a><\/li>\n<li class=\"wp-social-link wp-social-link-threads  wp-block-social-link\"><a class=\"wp-block-social-link-anchor\" href=\"https:\/\/www.threads.com\/@westonruter\/post\/DW4atcEDsCO?xmt=AQF09yVgY9426bf4GJZXdKIDdfPxO-IOSdR_WbrxXdA6Ew\"><span class=\"wp-block-social-link-label screen-reader-text\">Threads<\/span><\/a><\/li>\n<li class=\"wp-social-link wp-social-link-mastodon  wp-block-social-link\"><a class=\"wp-block-social-link-anchor\" href=\"https:\/\/mastodon.social\/@westonruter\/116370617285521944\"><span class=\"wp-block-social-link-label screen-reader-text\">Mastodon<\/span><\/a><\/li>\n<\/ul>\n<p>The post <a href=\"https:\/\/weston.ruter.net\/2026\/04\/08\/adding-an-mcp-server-to-the-wordpress-core-development-environment\/\">Adding an MCP Server to the WordPress Core Development Environment<\/a> appeared first on <a href=\"https:\/\/weston.ruter.net\/\">Weston Ruter<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>I wanted to hook up Claude Code to be able to interact with my local wordpress-develop core development environment via MCP (Model Context Protocol). I couldn\u2019t find documentation specifically for doing this, so I\u2019m sharing how I did it here. Assuming you have set up the environment (with Docker) and started it via npm run [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4653","post","type-post","status-publish","format-standard","hentry","category-latest-news"],"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=\/wp\/v2\/posts\/4653","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4653"}],"version-history":[{"count":0,"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=\/wp\/v2\/posts\/4653\/revisions"}],"wp:attachment":[{"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4653"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4653"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontlinenewsng.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4653"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}