Test page – Turn Your Local WordPress Install Into Your AI Coding Assistant
Workshop Welcome and Hands-On Goals
- 👋 Jonathan Bossinger opens the WordCamp US workshop from Cape Town and points attendees to jonathanbossinger.com/wcus2025 for links and software.
- 🛠️ He frames the session as a hands-on technical workshop focused on enabling Model Context Protocol on a local WordPress site.
- 👥 Attendees are encouraged to sit near partners, move forward, and help each other while volunteers Jai and Rocky pace the room.
[Jonathan Bossinger (Host)] [0:00:01]
Let’s give it up for Kinjal. Thank you. And if you haven’t already, you can all now tick your thank a volunteer bingo card.
[Audience] [0:00:10]
All right.
[Jonathan Bossinger (Host)] [0:00:16]
As mentioned earlier, my name is Jonathan Bossinger. I’m from Cape Town in South Africa. It is so weird to say good morning to you when my body clock is telling me it’s about dinner time. But the focus of today’s workshop is enabling something called Model Context Protocol on your local WordPress site. If you would like to access all of the links that we’ll be using, all of the software that we’ll be using today, I recommend either scanning the QR code or just going to my blog, jonathanbossinger.com/wcus2025. We are going to be needing to download some software to install in our local environments. There are some links to some articles I’ll be sharing. It’ll be great if you have them open on your browsers at the same time. It just makes it easier for everybody. Does everybody have the link or want to scan the QR code?
[Audience] [0:01:01]
Excellent.
[Jonathan Bossinger (Host)] [0:01:03]
This is a hands-on— I hate mics. This is a hands-on technical workshop. So hopefully you’re here to do some stuff, to write some code, to build some things, to connect some things. If you’re here to check emails and do work, that’s cool. More people in my workshop, happy me. But I would like to encourage you, if you are here today, to sit and do the workshop together. I would like to ask you one of— I’d like to ask you two things. Number one, if you’re sitting at the back, please come up to the front and join us. Number two, if you don’t have somebody sitting close to you, if you’re sitting on your own, please look around and see if you can find somebody to move to. I would like to be able to pair folks off with each other to help each other out as we go along. So if you’re sitting on your own, have a look around, see if there’s a gap you can move to. It’s just easier when we support and help each other.
Prerequisites: Node, Local WordPress, and an MCP-Ready Editor
- 💻 Required setup includes a laptop, Node.js for NPX, a local WordPress install (WordPress Studio demoed), and an AI code editor with MCP support.
- 🧩 VS Code with free-tier GitHub Copilot is recommended; Composer is no longer strictly required for the planned path but may still appear for plugin deps.
- 🎁 Interesting questions earn free t-shirts, and WordCamp US Wi-Fi is preferred for speed during installs.
[Jonathan Bossinger (Host)] [0:01:51]
Okay, you’re going to need a laptop. These requirements, hopefully if you saw this workshop, you saw the requirements on the WordCamp US site. You’re going to need a laptop. As of yesterday, and I’ll talk about this in a second, you don’t need Composer for today’s workshop. You will need Node.js installed on your machine because you’re going to be using something called NPX. Quick show of hands, who doesn’t have Node.js installed? 1 Or 2 people. Okay, that’s awesome. So more people jumped on the JavaScript bandwagon than I realized. That’s amazing. I’m not gonna be showing you how to install Node.js today. That’s not the purpose of this workshop. So while I’m doing my little preamble in a second, that’s a great time to get that installed. If you don’t want to install it and you just wanna follow along, that’s fine too. This is being recorded and I will record a version of this for my YouTube later. So that’s totally fine. You will need a local WordPress installation. I will be using WordPress Studio.
[Jonathan Bossinger (Host)] [0:02:52]
And I do have some t-shirts that I will give away to people with very, very interesting questions. So if you come up with a very, very good interesting question, you get a free t-shirt. And then you will need an AI-powered code editor with MCP support. If you don’t know what that is, I recommend using VS Code. We all know what VS Code is. VS Code comes with GitHub Copilot built in on the free tier. So if you haven’t got that installed on your laptop, please get that installed and set up now. So search VS Code, get VS Code installed, enable the GitHub Copilot extensions, and get those up and running. OK. Last but not least, I need a volunteer. This volunteer needs to have a very specific requirement. They cannot be one of my colleagues, so Ryan is right out. They need to be somebody who’s prepared to sit and do all the work in the workshop, even when it gets boring, which it might, okay? Because I’m going to use you as my gauge as to where we are in the workshop work. So does anybody feel like doing that today?
[Jonathan Bossinger (Host)] [0:03:52]
Okay, we’ve got a couple over there. Jai and the chap behind you. Why don’t you greet each other? There’s a chap behind you who’s keen as well. Shake hands, say hi. What’s his name, Jai?
[Audience] [0:04:04]
Rocky.
[Jonathan Bossinger (Host)] [0:04:04]
Rocky. I knew Jai had a loud voice, so that’s why I knew I could rely on him. So Jai and Rocky, you guys are going to be my chicks. When we’re doing things, when we’re doing steps, I’m going to go, hey, are you guys still busy? Are you ready to rock and roll? If you all aren’t as fast as Jai and Rocky, then you go and bug them, okay? But we will keep it nice and slow and relaxed. All right. And then I do recommend if you aren’t on the WordCamp US Wi-Fi, there’s a free conference center Wi-Fi, but the WordCamp US Wi-Fi is a lot faster. The details are on the back of your name badge if you haven’t got it already. Hopefully you’ve all got it by now.
Cutting-Edge Territory and Learning Objectives
- 🐉 Jonathan warns the stack is brand-new and fast-moving, with a plugin update shipping the day before the workshop.
- 🎯 Objectives cover introducing MCP, configuring a site as an MCP server, exploring the Abilities API, and exposing abilities as tools.
- ⚡ The plan is to finish setup quickly so the room can build custom abilities and review cool use cases or example code.
[Jonathan Bossinger (Host)] [0:04:37]
Alright, we are entering in the realm of dragons. We are entering into an area of WordPress that is very, very brand new, fairly cutting edge, and moving very fast every day. Literally yesterday, about 4 PM local time, An update was pushed to one of the plugins we’re going to be using in this workshop. So this morning, I was very quickly making sure everything still works. All right? So things may have changed in the last 24 hours. So we may hit some snags. I’m hoping we don’t. But the stuff that we’re going to be working with is very sort of iterating very rapidly. So bear with me if we hit something that goes wrong. I promise you this is not a way for me to just cheat and not throw anything together that I didn’t test. But things are moving very fast. Okay, our learning objectives today. I’m going to introduce MCP to you if you don’t know what MCP is. I’m going to show you how you can configure your site as an MCP server using Core AI plugin.
[Jonathan Bossinger (Host)] [0:05:39]
We’ll talk about the Abilities API, and I think it is so cool that I’m talking about the Abilities API and Justin’s in the audience, and I was at his talk about the REST API 10 years ago. And then I’m going to show you how to enable abilities as MCP tools and the kind of things you can do with it. Hopefully we’ll look at some cool use cases. I’m hoping we get through the setup pretty quickly because then we can build some cool stuff. If we don’t, I’ve got some example code that I can show you.
[Audience] [0:06:04]
All right.
[Jonathan Bossinger (Host)] [0:06:06]
That wasn’t the one that I wanted.
[Audience] [0:06:09]
There.
What Model Context Protocol Is and Why It Matters
- 🔌 MCP, developed by Anthropic, is described as a USB hub that connects software to LLMs so agents get context beyond open files.
- 📦 Without MCP, an AI editor cannot see live database state such as WooCommerce products or active plugins on a local site.
- 🧠 With MCP, tools can query MySQL, site data, and other systems so coding agents reason with real runtime context.
[Jonathan Bossinger (Host)] [0:06:11]
So let me open up this. So quick show of hands, has anybody here not heard of Model Context Protocol? Okay, couple of people. Who here was in the What Are We Building with AI talk with James and Felix a couple of days ago? Okay, so some of you might have heard of some of these things. All right, so Model Context Protocol, let me find the link here, is essentially this protocol that has been developed by a company by the name of Anthropic. They describe it as a USB connector for AI. I think about it more like the USB hub that you plug into your laptop. And it allows you to connect your HDMI and a USB stick and, you know, some external drive. It’s essentially a way of connecting any piece of software to your LLM to give your LLM context. So when you’re coding in something like VS Code or PhpStorm or whatever the case may be, and you’re using Copilot or Claude or whatever these AI tools are, the context that you give it is what it uses to build stuff.
[Jonathan Bossinger (Host)] [0:07:15]
It has, it has a whole bunch of information that it gets from the LLMs. But if you give it a file that you’re working on or you give it context of the plugin or the theme that you’re working on, It uses that to build more code and figure out what you’re trying to do and how you’re trying to work. What Model Context Protocol does is it allows you to give the AI tool context outside of the code. So let me give you a simple example. If you’re working on a plugin, let’s say an extension for WooCommerce, but you want to be able to access the products in your local copy of the database, you have no way of giving the AI context of what those products are, how they’re stored by the client, what the prices are, because you just have the code. You don’t, the database doesn’t sort of pipe straight into the code editor. Model Context Protocol MCP the, is what allows you to connect. You can connect the MySQL database, you can connect various things. Now in WordPress land, if you haven’t seen it already, let’s jump back over here.
MCP Adapter Plus Abilities API Building Blocks
- 🧱 The WordPress MCP Adapter plugin turns a site into an MCP server but does not supply useful context by itself.
- ✨ The experimental Abilities API lets developers register abilities that can be adapted into MCP tools, resources, or prompts.
- 📋 A get-site-info ability can return version, plugins, themes, and other data as JSON for natural-language queries in the editor.
[Jonathan Bossinger (Host)] [0:08:14]
There’s this thing called, Why am I in the edit view?
[Audience] [0:08:17]
Good grief.
[Jonathan Bossinger (Host)] [0:08:20]
Wrong window. There we go. There’s this package or this plugin. It’s one of the AI building blocks called the MCP Adapter. Now what the MCP Adapter does, it runs on your WordPress site. It’s currently installable as a plugin, as a Composer package, or just manually, although the manually is a bit wonky. And it essentially enables your WordPress site as an MCP server. That’s all it does. So it still can’t give any kind of context to your AI tools. But there’s something else that’s being worked on called the Abilities API. Let’s go down over here. And one of the things that the Abilities API does is it allows you to build abilities that you can then turn into MCP tools to be able to give context to your AI code editor. So let me give you another good example. Simple one. Let’s say I want to know, I want, I’ve just taken over a client site. I’ve downloaded whatever backup version I use, whatever Jetpack or MigrateDB Pro, whatever I’m using.
[Jonathan Bossinger (Host)] [0:09:21]
And I just want to get a quick idea of what WordPress version is running, what plugins are installed, what themes are installed, some basic site data. As a developer, I’d have to start going and digging. I’d have to go and look maybe for the version number or go look in the database or go open up the dashboard and see what plugins are installed, see what themes are set up there. What I could do is I could create an Ability that says, get site info. And it goes and uses get blog name to get the name and get WP version and all of these internal functions that WordPress already has and returns them as a JSON object. And then I can adapt that Ability into a tool, an MCP tool, and I can then in my code editor say, hey, tell me about the site. Those English words, whatever language you’re using. It’ll then call the tool and return that data for me. Now that’s a very simple example, but you can also create tools that actually will do things. And one of my most favorite tools that I developed was a tool that fetches the debug log when there’s a bug, when there’s a site break or whatever the case may be, reads through the debug log and then suggests fixes for me based on what it’s seeing in the debug log.
[Jonathan Bossinger (Host)] [0:10:29]
So it allows you to enable all this kind of additional functionality. Okay.
Download and Install Abilities API and MCP Adapter
- ⬇️ Participants download ZIP builds of wordpress/abilities-api and the MCP Adapter from GitHub and install them as plugins.
- 🗓️ Abilities API is targeted for WordPress 6.9 and standardizes requesting abilities via PHP or REST.
- ⚠️ Activating MCP Adapter from source requires Composer install inside the plugin folder when the autoloader is missing.
[Jonathan Bossinger (Host)] [0:10:36]
So now I’d like you all to open up your local WordPress install. I’m gonna open Studio over here. There’s my AI experiment site. There is my WordPress dashboard. Is that big enough or do I need to make that bigger? Bigger. Bigger for the people in the back. Bigger, smaller, happy? Looking good, all right. So this is my, you can see this is default WordPress install. If I go to my plugins, the Kismet and Hello Dolly are there, but they’re disabled. So this is a regular good old WordPress install. And what I would like you to do with me is go to github.com/wordpress/abilities-api and just click on the code button and click on the download zip file option, right? That’s gonna download the Abilities API trunk plugin. This is installable as a plugin on your WordPress site. So you can go ahead and download that. While you’re downloading that, I also want you to download the MCP adapter. You can do the same thing. You can go to Code, Download ZIP File, and download it to your local machine.
[Jonathan Bossinger (Host)] [0:11:42]
Okay. Give you a few minutes to do that. Either Jai or Rocky, once you’ve done that, why don’t you pop your hand up, please?
[Audience] [0:11:52]
Okay.
[Jonathan Bossinger (Host)] [0:11:53]
Good to go. Everybody else good to go? Everybody happy? Awesome. Okay. So now we’re just going to do good old plugin install. So the first thing I’m going to install is the Abilities API plugin. Now, if you don’t know, and I don’t know if James mentioned this in his talk, but the Abilities API is something that is planned to be shipped in WordPress 6.9. It enables this MCP tooling for us. It also enables a couple of other cool things. So it creates a standardized way that you can request any ability from a WordPress site and expose that either to PHP or to JavaScript via a REST API. I’m not going to dive into all of that today, but I do recommend going and checking it out, going and reading up on the documentation. So once you’ve got it installed and active, it doesn’t really do anything to your WordPress site. It just enables the API so that you can start using it. All right. The other thing that I want you to do is install and activate the MCP adapter. So I’m going to do that now as well.
[Jonathan Bossinger (Host)] [0:12:59]
And if you try and install and activate it, it’s going to say to you the Composer autoloader was not found. If you installed the plugin from GitHub source code, make sure to run Composer install, OK? Now that was a change that happened recently. I was not expecting that. Does anybody here not have Composer installed? One gentleman. Anybody else? OK. One guy over there.
[Audience] [0:13:24]
All right.
[Jonathan Bossinger (Host)] [0:13:25]
So unfortunately, for those of you who don’t have Composer installed, if you can get it installed quickly now, that’ll be great. But if you can’t, you might have to just watch the recording and do it later.
Composer Install, Audience Fixes, and Opening the Site in VS Code
- 📦 Jonathan runs Composer install in the MCP Adapter directory and answers path questions; a first good question wins a t-shirt.
- 🆘 He attempts to share a prebuilt ZIP for attendees without Composer while continuing the main path.
- 🖥️ Everyone opens their local site in VS Code (or another MCP-capable IDE) and launches the Copilot agent panel.
[Jonathan Bossinger (Host)] [0:13:34]
So with that installed, I’m going to open up my terminal. I’m going to navigate to my AI experiment site. Can’t type today. AI experiment site inside the wp-content folder, inside the MCP adapter, no plugins. MCP adapter folder and I’m just gonna run Composer install. Okay, that’s gonna install all the dependencies and we are off to the races.
[Audience] [0:14:02]
All right.
[Jonathan Bossinger (Host)] [0:14:06]
Everybody happy with that? Anybody having any problems with that?
[Audience] [0:14:09]
All good.
[Jonathan Bossinger (Host)] [0:14:09]
Yes.
[Audience] [0:14:10]
Do you have to be running this in that project’s folder?
[Jonathan Bossinger (Host)] [0:14:13]
Inside of the MCP adapter folder. So change directory to the MCP adapter folder, run Composer install there, and it will install all the dependencies. Thank you. Does that count as a good question?
[Audience] [0:14:24]
It’s a question.
[Jonathan Bossinger (Host)] [0:14:25]
It’s a question. Does it count as— Audience, what do we think?
[Audience] [0:14:28]
Yes.
[Jonathan Bossinger (Host)] [0:14:31]
First question gets a t-shirt. I like that. So, should I get the t-shirt? Large, medium, small?
[Audience] [0:14:35]
Medium. Medium. Doc Fragan, stop it.
[Jonathan Bossinger (Host)] [0:14:57]
Yes, you got a question?
[Audience] [0:14:58]
I use WPML for that, and you know how I put an insert instead of WordPress slash the name of the MCP and save it?
[Jonathan Bossinger (Host)] [0:15:10]
Sorry, I didn’t catch that. Let me take the mic over to you.
[Audience] [0:15:12]
There is a mic here.
[Jonathan Bossinger (Host)] [0:15:17]
I tried to make it happen like so, and that would normally work, I guess, but maybe there’s also a link for a repository. So the question’s being asked there, you’re using WPENV, right? And he’s trying to set up the plugins in the WPENV. I honestly don’t know, I’ve never tried. So I’m sorry, it probably is possible, but I’ve never tried, so I can’t say. That’s why I’m going this route, the simple plugin install.
[Audience] [0:15:50]
OK.
[Jonathan Bossinger (Host)] [0:15:50]
So does everybody have the plugins installed in some way or another at least, except for the folks that have questions? OK. Good to go. Great.
[Audience] [0:15:56]
Thank you.
[Jonathan Bossinger (Host)] [0:15:58]
Not yet.
[Audience] [0:15:58]
But you— I can’t get the MCP exactly installed.
[Jonathan Bossinger (Host)] [0:16:02]
Because you don’t have Composer, right? No, I do not. Yeah. So that’s going to be— even with downloading it from Git, you need Composer installed to install the dependencies. Unfortunately. So what I can do— actually, let’s see if I can quickly zip it for you and stick it somewhere. Give me one second.
[Audience] [0:16:22]
Uh, let me be— this— no, not that one.
[Jonathan Bossinger (Host)] [0:16:33]
That’s the wrong one. No, it’s not, unfortunately. It’s a WordPress core repo. Yeah, that’s what I was thinking. Ah, wrong one. I’m going to try this once and see if this works. And if it doesn’t work, then unfortunately we’re going to have to move on. Let’s see how big this thing is. OK, let’s see how big this is. So let’s go to— My site. Let’s go to media. See if I can add this to media. Will I be able to add a zip file to media?
[Audience] [0:17:15]
Maybe.
[Jonathan Bossinger (Host)] [0:17:19]
The content. Plugins. Let’s try that. It’s 28 megs. Let’s see if it’ll handle 28 megs. That was pretty quick. So, oh, good grief. I just uploaded it locally. Stupid. Let’s try it here. Add media files, select files. AI experiments. WP content.
[Audience] [0:17:55]
Come on.
[Jonathan Bossinger (Host)] [0:17:57]
Plugins. All right, and then what we’ll do is we’ll add it to this page. And hopefully folks can download it from there. Well, this could take a while. OK, so while that’s uploading, I’m going to carry on. For the gentleman in the corner, I’m going to carry on with the workshop salon, and we’ll move on from there.
[Audience] [0:18:16]
All right.
[Jonathan Bossinger (Host)] [0:18:18]
I want you to open up the VS Code IDE if you have it installed, or whichever IDE you’re choosing to use. It needs to be able to support—.
[Audience] [0:18:24]
MCP.
[Jonathan Bossinger (Host)] [0:18:25]
It needs to have an AI agent of some kind. I’m using VS Code. I’m going to make this a little bit bigger.
[Audience] [0:18:34]
So let’s go.
[Jonathan Bossinger (Host)] [0:18:35]
No, not zoom. Appearance. Zoom in.
[Audience] [0:18:45]
That one. OK. All right.
[Jonathan Bossinger (Host)] [0:18:48]
And I’m going to open up the local site that I have. So find wherever you have your local site and open that up in your VS Code.
[Audience] [0:18:59]
All right?
[Jonathan Bossinger (Host)] [0:19:01]
Everybody there?
[Audience] [0:19:03]
Cool.
Why the Agent Cannot See Active Plugins Without MCP
- ❓ Asking Copilot which plugins are active fails because the agent only sees files, not options table or database state.
- 🔗 MCP is introduced as the bridge that can expose that runtime context through registered abilities.
- 📖 Jonathan points to MCP Adapter README basic usage for the server registration hook and create-server API.
[Jonathan Bossinger (Host)] [0:19:04]
So now what I want you to do is in the Copilot window, open that up please. If you don’t know how to open it, there’s a little Copilot icon over there. So this is just the code of the site. The site is running. The site is a local WordPress site. So it is running. It’s connected to a database. And we’re going to ask the agent and we’re going to say, can you tell me what active plugins are installed? And what’s it going to do? To determine, I need you to do some things for me. It has no context besides the files that are available. It has no context of the plugins that are installed and active because that requires database connection. That requires access to the, I think it’s an options record. That stores the active plugins. So with MCP, what we can do is we can build an ability that’ll do it for us. So the first thing we need to do is we need to set up the MCP adapter server. So if you go back to your MCP adapter GitHub code and you scroll down a little bit, quite a bit actually, the documentation needs a little bit of a cleanup.
[Jonathan Bossinger (Host)] [0:20:10]
You’ll see it talks about installation, We did it as a plugin. And then below that, there’s some checking availability. We’re not going to worry about that today. But right over here, it just talks about basic usage. I’m going to make this a little bit bigger. That, that, okay, talks about basic usage. Everybody see that?
[Audience] [0:20:26]
Okay.
[Jonathan Bossinger (Host)] [0:20:27]
So what it does is it exposes an MCP adapter init action hook that we need to hook into. We set up a callback function. The callback function receives an instance of the MCP adapter. We then use the MCP adapter to create a server. The server has an ID, a namespace, sorry, a REST API namespace, a REST API route, a name, a description, a version number, and then some classes for various different functionality within the server. So what’s great about this is we can just copy this code as is and set this up in a new plugin. So that’s what I’m going to do. So I’m going to copy that code out. I’m going to go back to VS Code. Open up my plugins. I’m gonna check on that upload quickly. It is done, so please give me a second. I’m gonna pop this right at the top of the window here. That’s gonna try and embed. Okay, so those of you, so if you don’t have Composer installed, you can try and download this version of the plugin and see if it works. Gentleman in the corner over there.
[Jonathan Bossinger (Host)] [0:21:29]
If you go to the, the jonathanbossinger.com/wpcus page. It’s the first link at the top there. Can you see that?
[Audience] [0:21:37]
Yes.
[Jonathan Bossinger (Host)] [0:21:38]
Okay.
Scaffold an AI Experiments Plugin and Register the MCP Server
- 📁 A new ai-experiments plugin is created with a header, ABSPATH guard, and the Adapter init callback copied from docs.
- 🌐 Server ID, REST namespace, route, name, description, and version define the endpoint the editor will call for tools.
- 🧰 Tools, resources, and prompts are explained: tools are dynamic, resources are cacheable reads, prompts template multi-step workflows.
[Jonathan Bossinger (Host)] [0:21:40]
So let’s go back to the code. All right. Who here has built a plugin in their life? Awesome. You’re all plugin devs. I love it. Okay. My people. So if you know how to build a plugin, please go ahead and create an example plugin. Give it a plugin header. And install the code that we just saw. I’m gonna start doing that now, so you’re welcome to do that along with me. So I’m gonna create a directory, ’cause all plugins need to go in directories. Is that not right, Andy?
[Audience] [0:22:07]
I’ve heard that.
[Jonathan Bossinger (Host)] [0:22:08]
And I’m just gonna call my plugin ai-experiments, and I, every time I do this, I spell experiments incorrectly. And I’m gonna create my new PHP file, ai-experiments.php. All right, and I’m going to open up my PHP tags. I’m going to just close the chat window so we can see the code. Copilot gives me some lovely autocomplete, which I’m going to accept. And then I’m going to start writing my code. Now, the code we’re going to write today is not well planned. It’s not going to be pretty. It might not follow coding standards. It might not be good architectural practices. Please don’t use code like this in production. Okay, I’m not here today to teach you how to use production code. Today we’re here to have fun and experiment. So we probably should do the if defined apps_path thing. That’s probably a good idea, so we’ll do that. And then we can take that code, as I said, from the basic usage section.
[Jonathan Bossinger (Host)] [0:23:08]
We can just copy it as is. And we can pop that down over here in our plugin file. Now if you’re somebody who doesn’t like using anonymous functions or closures for your callbacks, I totally understand that. We all know there’s a good reason reason to use name functions so that you can unhook them if you need to. For the purposes of today, I’m just going to stick with the example code, but hopefully you all understand what it means to have the function right there in the callback. So for my ID, this is very basic stuff today, folks. This is copy, paste, replace. I’m going to just call it AI experiments. The namespace, I’m going to call AI experiments as well. So what the MCP adapter does is it exposes a REST API endpoint that the coding editor can make a request to, to check which tools are available. So that’s why this REST namespace and REST route are set up. Okay, so it’s AI experiments. I’m going to leave mine as MCP. And then I’m not going to change my server name and my description for this example. You’re welcome to do the same. Then you’ll see right down at the bottom here, there are 3 arrays of lists of abilities, resources, and prompts that you can set up as MCP— sorry, a list of abilities that you can expose as either tools or resources or prompts.
[Jonathan Bossinger (Host)] [0:24:21]
I’m not going to dive too deeply into what tools, resources, and prompts are, but essentially tools are things that you send data to and receive data from, so they’re more dynamic. Resources are things that you just receive data from, so like Get Site Info is a good example. So you can cache that data, so therefore you can speed up reaction times. And prompts are like a templating system. So a good example for a prompt might be, tell me how my products are performing last week. And then it might have a resource that gets all the products and then it might have a tool that you send the products to and it gets some analytics and merges that together. But the prompt is the sort of template that puts all that together for you. So what I want you to do for now is just take out the example ability that’s there and that’s all we’re going to do for now. With that in place, if I go back to my local environment, which is over here, and I go back to my list of plugins, I should see my AI experiments plugin there.
Permalinks, Activation, and Verifying the REST Endpoint
- 🔗 Plain permalinks break the Adapter; settings must use pretty permalinks so the MCP REST route works.
- ✅ After activating the plugin, /wp-json/{namespace}/mcp is checked in the browser to confirm the server endpoint exists.
- 🐢 Spelling slips and forgotten activation provide comic relief while the room catches up with Jai and Rocky.
[Jonathan Bossinger (Host)] [0:25:21]
But before I activate it, there’s one small thing I need to change. If you are using a local development environment like I am in, in the case of Studio, that doesn’t set a default permalink setting, your REST API endpoint for the MCP server will fail because for whatever reason, The MCP adapter doesn’t support the sort of old school query URL version of the REST API endpoints. It’s an issue that I’m going to log very soon and submit a PR for. But right now it needs to be permalinked endpoints. So go to your settings, go to your permalinks. I mean, how old is this problem, hey, in WordPress? Tailors oldest time. And just set it to anything other than plain. If you’re using a local environment that does this already, you should be fine. All right. So with that in place, what I can now do to check that this is working is I can go and copy out, I’m not gonna copy it out ’cause I know what it is. I can copy out this ai-experiments and MCP and I can check that REST API endpoint. So that on my local environment, here is my site. So it’s ai-experiments.wplocal. I’m going to append wp-json to it and then the REST API endpoint.
[Jonathan Bossinger (Host)] [0:26:28]
And it’s not working. Oh, ’cause I haven’t activated the plugin. I set the permalinks and didn’t activate the plugin. Typical. Okay, so let’s activate that. Could have done that on the CLI, but chose not to. All right, let’s open up the site. You know, you do these things over and over and over again, you think you have it waxed, and then you still forget stuff.
[Audience] [0:26:51]
Could you make that text bigger?
[Jonathan Bossinger (Host)] [0:26:52]
I’ll do my best. I think you spelled it wrong. I think you— did I spell it wrong again? What do you mean? I did. I do it every time. It’s like a blocker in my head. It’s wild. I’ve never been able to see if it’s possible to make the address bar bigger. Does anybody know how to make the address bar bigger? I’ve never been able to do it. But basically, it’s the URL of your local environment, your local site. /Wp-json, J-S-O-N, slash whatever you have set for your REST API namespace. So that will be your URL to check whether this endpoint exists.
[Audience] [0:27:33]
I’m sorry, I’m a rather slow person.
[Jonathan Bossinger (Host)] [0:27:37]
No, you’re not. You’re just very patient and meticulous. That’s what it is. You’re patient and meticulous. Where did you get that code snippet from? The code snippet. So the code snippet is inside of the MCP adapter plugin under basic usage. Yeah, so if you scroll down in the README under basic usage, it’s over there.
[Audience] [0:27:54]
And what changes were we making?
[Jonathan Bossinger (Host)] [0:27:56]
Change— the only changes I made were the server ID and the namespace. Those are the only two you have to make for this test to work. OK, so now is a good time to pause and check. Is anybody struggling with this? Has everybody got theirs working? Is anybody not seeing it? Jai’s good. Rocky’s good. I’m going to wait for the patient and meticulous and careful gentleman in the front here.
[Audience] [0:28:13]
I love it.
[Jonathan Bossinger (Host)] [0:28:15]
Okay, so now we know it’s working, we know the endpoint is there. Now we need to give the server some tools. We need to give it some context. We need to be able to do something with this, all right?
Register a Get Site Info Ability with Schemas
- 📝 The Abilities API intro docs supply a site-info registration example using wp_register_ability with label and description.
- 📐 Input and output JSON schemas document expected data so MCP clients understand arguments and return shapes without separate docs.
- 🔐 A permission callback (current_user_can style) is recommended; security concerns are why the workshop stays on local installs.
[Jonathan Bossinger (Host)] [0:28:27]
To do that, we use the Abilities API. Now as I mentioned before, the Abilities API, the goal for the AI team is to get the Abilities API shipped in core in WordPress version 6.9. So right now it’s installable at a, yeah, yeah, yeah. My brain. It’s installable as a plugin. So you can start setting it up and you can start playing with it, but eventually it will be available in WordPress core. For this one again, there’s a great little example. I think it’s in the README. No, it’s under the docs. So in that GitHub repository, if you go to docs and if you go to intro, there’s a quick introduction about how this will work. And then there is an example Ability being registered. And oh look, it’s a site info Ability. Who saw that coming? It’s like I planned this. All right, so all we need to do there again is copy that code snippet out. So it’s in the GitHub Abilities, sorry, in the Abilities API GitHub repo, click on docs, click on intro.md and copy that out. And what we can do is we can place that in our plugin. What I’m going to do is I’m gonna place it above the MCP adapter registration.
[Jonathan Bossinger (Host)] [0:29:31]
It’s quite a bit long, but I wanna go through the code with you all so we can understand what we’re doing here. Okay, what I’m also going to do is I’m gonna quickly change the namespace of my callbacks. I’m gonna take it AI, I did it again. I did it again. It’s like a mind thing with me. I don’t know. Maybe I should say to myself, if I get it right, I’ll give myself a t-shirt. Okay, so I’m just gonna change the callback function from my plugin, whatever it was, to AI experiments registerability, then I’ve got the function set up. Then we call the wp_registerability function, okay? So when you register ability, you call the wp_registerability function. It has a series of things you need to set. You need to give it a label and you need to give it a description. Now, who here knows, who here has worked with REST API endpoints building Frontends. Okay, cool, awesome. So we know that when we have a list of REST API endpoints, we want to use them to build some kind of JavaScript application or PHP application or whatever, and we want to know what the endpoints are, what data they receive, and what data they return, what do we do?
[Jonathan Bossinger (Host)] [0:30:45]
Where do we go? Say again?
[Audience] [0:30:48]
/Documentation.
[Jonathan Bossinger (Host)] [0:30:49]
/Documentation, but if you want to know what data is being sent and received, like what arguments it receives and what it’ll give you back, where do you go? You read the docs. You go and read the docs because it’s not available in the REST API endpoints, right? You don’t know what it’s doing, what it does underneath, what data it sends and receives. You go read the docs. The cool thing about MCP is you give it a label, a description, and a schema, and then it knows what it does. So when you query it the first time, it gets all that information, which is why giving it a good label and giving it a good description are very important. Okay, those of you who’ve worked with AI for a while, what is the most important thing when we work with AI? Very good prompting, right? Very descriptive, detailed prompts. Because we’ve all one-shotted really bad code, right? I have— if you want to have a good laugh, go to my GitHub profile. There is a 3D shooter game that I one-shotted. It is the most funny piece of JavaScript animation.
[Jonathan Bossinger (Host)] [0:31:49]
It literally just loads up and eventually just fries my browser. And it does nothing. It’s like a red oval and a bunch of blobs, and it just keeps looping through the game loop and fries my browser. It’s the funniest thing. So you give it a label, you give it a description. You need to give it an input schema. Now, because this is going to be a resource, as I said earlier, resources, we generally receive data, we don’t worry about the input schema. But if you’re creating a tool, you give it an input schema. What is the input schema? Well, what is the data it expects to receive? So it might just be a string that it receives, it might be an array of data or an object of data, so you got to specify that. Then you specify an output schema. And as you can see in this instance, the output schema, it is an object type and it has some properties. The properties are site name, site URL, active theme, active plugins, PHP version, and WordPress version. You’ll also notice that every single property has a type, and a description for the same reason that the tool has a label and a description to give context.
[Audience] [0:32:49]
Yes, Jai.
[Jonathan Bossinger (Host)] [0:32:51]
If you have a question, there’s a mic there if you want to be on mic. I forgot to mention that earlier, sorry.
[Audience] [0:32:55]
A question came up. People were wondering where did they get that code from?
[Jonathan Bossinger (Host)] [0:33:01]
Okay, where did they get that code from? If you go to the github.com/WordPress MCP adapter and— let me scroll up here, and you click on docs, no, it wasn’t docs, I’m talking nonsense. Sorry, it wasn’t MCP Adapter, it was Abilities. So if you go to WordPress, github.com/wordpress/abilities-api, it is linked in my workshop posts right down here, there, Abilities API, so that’ll take you straight there. And you go to docs and you go to number 1, intro.md. And you scroll down a little bit. The code example is there. The registration example is there. Everybody happy with that? Yes. Where’s your post at?
[Audience] [0:33:49]
Say again? What’s the URL for your post?
[Jonathan Bossinger (Host)] [0:33:52]
Oh, the URL for my post? My name, jonathanbossinger.com/wcus2025.
[Audience] [0:33:58]
Okay.
[Jonathan Bossinger (Host)] [0:34:01]
So what this registration of this ability does is it sets up what the ability does, it sets up what we expect it to do, it sets up what the inputs are, what the outputs are. Then it has an execute callback. It’s a callback function, right? It’s the function that’s going to do whatever it needs to do underneath to get this data back. So in this instance, I’m going to change this one to AI_experiments. I did it again. This is like a rolling joke. So I’m just gonna call that AI experiments get site info. That’s just a standard WordPress callback. That’s gonna do the core WordPress stuff that it needs to do underneath to get this information. And then you can also set a permission callback. Now if you wanna read a really good article about MCP and security, go and search. Unfortunately it’s on Medium, but the article is called, “The S in MCP Stands for Security.” Right? There are some concerns around security and MCP, which is why I’m teaching you to do this on a local environment today and not some production site.
[Jonathan Bossinger (Host)] [0:35:02]
And we can chat about that in a second, and we will. But it is a good idea to use the permission callback that is configured just like a REST API endpoint and use some version of current user can, whichever you prefer. Generally, an admin, depending on the functionality. In this case, an admin doesn’t maybe need to get the site info, but we’re going to go with it for today.
[Audience] [0:35:23]
All right.
Implement the Ability Callback and Match Output Schema
- ⚙️ The execute callback returns site name, URL, active theme, plugins, PHP version, and WordPress version.
- 🎯 Returned keys must match the declared output schema so the MCP tool can consume the payload correctly.
- 📚 Jonathan notes full example code will be shared in a repository after the workshop.
[Jonathan Bossinger (Host)] [0:35:25]
So we’ve registered the ability. The ability does nothing. It has no context. So now we have to actually create the ability’s callback function. So underneath the registration, I’m going to create the function, getSiteInfo. And now I’m going to get the site info. So what’s nice is that, again, Copilot has given me some example code. I didn’t prompt it this. This is what it’s given me. So I’m just going to return an array with the site name, site URL, active theme, active plugins, PHP version, and WordPress version. All right? And you will see that those properties match the properties of the output schema that I’ve configured. So it needs to match those things directly so that when the MCP tool receives it, it knows what to do with it. Okay, I’ll leave that on the screen for a second if anybody needs to see that. Everybody happy with that? Anybody still coding?
[Jonathan Bossinger (Host)] [0:36:25]
All good? Okay, this code, by the way, this code is all in a repository which I will share with you at the end of the workshop. So if you want to get hold of all this code, you will be able to.
MCP Transports and the WordPress Remote Proxy
- 🚌 MCP transports include STDIO for local servers and streamable HTTP; many clients rely on JS proxies between them.
- 📦 Automattic’s MCP WordPress Remote package is run via NPX to bridge the editor to the WordPress MCP HTTP endpoint.
- 🗂️ Configuration lives in an mcp.json file; VS Code uses a services key rather than Anthropic’s mcpServers naming.
[Jonathan Bossinger (Host)] [0:36:36]
So now the moment of truth. Now we need to set all this up to be configured with GitHub CoPilot. So if you go back, I think I’ve got it in the blog post, or we can just search it. Let me just see here. No, I didn’t. Oh wait. Yes.
[Audience] [0:36:54]
Okay.
[Jonathan Bossinger (Host)] [0:36:58]
If you go back to the blog post, you will see under code repositories, there is something called MCP-WordPress-Remote. I would like you to open that up, please. So let me tell you a story about standard input/output in JavaScript. In MCP, if you go and read on the MCP documentation, there are, at the moment, there are two transport layers, two ways that the data can be sent back and forth between your application and your MCP server. The one is standard input/output or STDIO. That’s essentially like just passing data you know, on your terminal, whatever the case may be. And that’s usually for servers that are running on your machine, MCP servers that are running on your machine. My favorite personal MCP server is the File System MCP server. Once a week, after I’ve created a whole bunch of links and shortcuts and downloads and whatever other cruft on my desktop, I fire up Claude and I say, clean my desktop. And Claude knows that when I say that, it must take all of those extra files and move them into the Documents folder on my desktop and just make it all look pretty, okay?
[Jonathan Bossinger (Host)] [0:38:01]
So it can connect to my file system and based on a previous rule that I had saved, when I tell it clean up, it knows take all the files on the desktop and move them into the documents folder. So that’s local. The other one is a streamable HTTP transport protocol. And I don’t understand, I haven’t read into the technicalities of it, but for whatever reason it’s difficult to implement security as one of the concerns, not everybody supports it. So what a clever bunch of devs started doing was they started developing these JavaScript proxies. So it’s basically a JavaScript file that takes the standard input/output transport and allows you to then transport that over HTTP back and forth, all right? And so most of these MCP servers are using this method. So they have a JavaScript package that runs, that’s why we need MPX ’cause we’re gonna run it with MPX. That’ll handle the transport layer part, okay? The one that we’re going to use is something that, folks at Automattic developed. So if you go to this URL, it’s github.com/automattic/MCPWordPressRemote.
[Jonathan Bossinger (Host)] [0:39:04]
And if you scroll down to the configuration, you’ll see the way it works is you create an MCP.json file in your Cloud Code or in your Cursor or whatever the case may be with the right pieces of information, and it then allows you to connect. So if we scroll, I think it’s on this page, if we scroll down a little bit further, and go down to WordPress Application Passwords, right?
Application Passwords and mcp.json Wiring
- 🔑 WordPress Application Passwords authenticate local MCP calls; OAuth is preferred for production but out of scope today.
- 🧾 mcp.json sets the NPX command, API URL ending in the MCP route, username, password, and an optional log file path.
- 🏷️ Naming the server after the local site helps multi-server setups route prompts to the correct WordPress instance.
[Jonathan Bossinger (Host)] [0:39:27]
Who here has never heard of WordPress Application Passwords? Okay, so a number of versions of WordPress ago, they shipped something to the user setup where you can create separate application passwords per user. It’s great for when the REST API came out ’cause people were building applications using the REST API, but we wanted a way of authentication, authenticating people without giving out admin passwords. It is not recommended for production. Production environments, you’re going to want to use something like OAuth, which is supported on MCP. This is not that talk, that’s a whole other conversation. What I do think will happen one day is that hosting environments will start implementing this on a hosting level with their own OAuth setup. But for local, application password is fine. So what we do in VS Code, we’re going to create an mcp.json file inside of a .vscode folder. You can read up about this in the VS Code documentation. But in the root of this project, I’m going to create a directory. No, that’s not the root of the project. Let’s try that again.
[Jonathan Bossinger (Host)] [0:40:29]
It’s creating it in wp-content. That’s not where I want it. I know. I don’t use VS Code every day, so that’s why it bothers me sometimes. I’m going to create my folder .vscode, and inside of that folder, I’m going to create file called mcp.json, right? Inside of that, I’m gonna copy out this WordPress application password code. I’m gonna grab that and I’m gonna pop that into the mcp.json. Now a quick note, depending on what coding environment or AI desktop tool or whatever you might be using, how you configure this might be slightly different. In Anthropic-based products, so Claude Code or Claude Desktop or whatever, they use this MCP servers.
[Audience] [0:41:13]
Keyword.
[Jonathan Bossinger (Host)] [0:41:14]
In VS Code, they just use the word service. Service. So you’re going to have to change yours to service for now. Then you’ll see it’s got a name essentially. And what I like to do with the name is I like to give it the same sort of logical name as my— let’s see if I can spell it right. Hey, GitHub’s telling me to spell it right.
[Audience] [0:41:34]
Yay.
[Jonathan Bossinger (Host)] [0:41:36]
Okay. And what I found is if you give it a name that is tied to like the local URL of the site, When you make queries of it and you refer to that name, if you have multiple MCP servers installed, it actually knows which one to work with. So the first time I tested this, I just left it as WordPress. And then I said, give me all of the site info from my AI experiment site, and it didn’t know what to do. So it’s a good idea to name the server in your MCP config the same as whatever you’re connecting it to. You’ll see it runs the npx command with some arguments. In this case, it’s just the, the flag to just use the package and the link to the package on npm.js. The API URL is the same URL that you used earlier to test the endpoint. So I think I still have it open over here. Here we go. So I’ll copy this out and pop it in here. The only difference here is you append the MCP root at the end, because what it does, it creates a POST request to that root. Hang on.
[Jonathan Bossinger (Host)] [0:42:36]
MCP. So this is the same one we configured in the plugin. Let me show you here quickly. So AI experiments was the namespace and MCP was the root. So that ties into AI experiments MCP. Then you give it your username and password. I’m going to do this locally. Somebody was in a workshop yesterday and said, don’t use admin for your username. But we’re going to go with admin today because this is local. It’s fine. And then to create your application password, what you’re going to do is you’re going to go into, let me check if this is the right place. No, that’s not the right place. That’s not the right place. Where is it? There it is. You’re gonna go into your user, list of users. You’ve probably got one local user. If yours is not admin, please make sure you use your username. You’re going to click on it and then scroll right to the bottom and you’re gonna find this area called application passwords. Everybody got that?
[Audience] [0:43:26]
Cool.
[Jonathan Bossinger (Host)] [0:43:26]
You’re going to give the password a name. It doesn’t matter too much what you name it, but I like to name it to whatever I’m using it to. So I’m gonna say MCP server, and then you’re going to add an application password that’ll give you a password that you can use. The other nice thing about the application password is you can revoke them. So you can use it for testing and then disable it. So I’m going to copy that password out and I’m gonna pop it in there.
[Audience] [0:43:49]
All right.
[Jonathan Bossinger (Host)] [0:43:50]
You don’t need the OAuth enabled stuff, so I’m gonna remove that. There is also a log, yes?
[Audience] [0:43:57]
I got a critical error whenever I was trying to create my admin password for that.
[Jonathan Bossinger (Host)] [0:44:02]
Got a critical error, okay, that’s awesome. Can you just put, let me finish this. No, no, I love critical errors. Let me finish this and then I’ll come over to you, okay? There’s also, as I was saying, if you have a look, I’m gonna find it here quickly, go back to, WordPress Remote, where was it? There we go. If you scroll down to the bottom of the README file for the MCP WordPress Remote, you’ll see there’s a couple of environment variables. And one of them is you can specify a log file. Now this is very handy when things go wrong, when it doesn’t connect or whatever the case may be. So I always suggest setting up a log file. I have, you can tell I’ve been playing with this, I have an MCP logs, directory in my home folder. I’m just gonna check, do I have anything here for now? I think I might do, yes, I’m gonna just remove those quickly.
[Audience] [0:44:54]
Star.log, here we go.
[Jonathan Bossinger (Host)] [0:44:56]
And I’m just gonna use that path as my log file. You can have yours wherever you want to, but it’s a good idea to set this up so that when you’re setting this up for the first time and testing it out and you wanna know why it’s not working, you can take a look at the log file.
Start the Server, SSL Gotchas, and First Tool Failures
- ▶️ VS Code shows a Start control when the configured URL responds; NPX downloads and runs the remote package without a manual npm install.
- 🔒 Local SSL cert verification errors are fixed by setting NODE_TLS_REJECT_UNAUTHORIZED as documented in troubleshooting.
- 🐛 Even after start, site-info prompts do nothing until the ability is listed for adaptation—and log paths must point to files, not folders.
[Jonathan Bossinger (Host)] [0:45:10]
You will see that when I configure this, there’s a little Start button that comes up. Now what happens in the background is VS Code actually tries to sort of pre-make the request to the API or the WP API URL that we’ve configured. And if it gets a response, it goes, okay, cool, this is a server, I can start the server. And this is one of the things I like about VS Code’s implementation.
[Audience] [0:45:33]
Yes.
[Jonathan Bossinger (Host)] [0:45:33]
Do you need to npm install this? Is that your question? No, you just need npx. So if you have Node installed, you probably have npx installed. That’s all you need. It’ll handle everything else for you. Okay, if you wanna check if you have npx installed.
[Audience] [0:45:48]
I’m currently not installed.
[Jonathan Bossinger (Host)] [0:45:53]
No, okay, so if you’re worried about installing the Automatic WordPress Remote package, the npx will actually download, install it, run it, and then clear it for you. So it does all of that for you. Yeah, excellent question. That’s a good question, right? Size?
[Audience] [0:46:05]
Small? Medium? Large?
[Jonathan Bossinger (Host)] [0:46:22]
There’s a fellow speaker in Cape Town who throws sweets at people when they start falling asleep. I don’t think that would work at a WordCamp. All right, so the fact that that little start button shows up tells me that I’m doing something correctly. So does anybody here not have the little start button showing up? Nobody, are we all ready to click start and see what happens? Let’s do it. I haven’t forgotten my critical error friend, I’ll get to you in a second. So when I click start, it starts doing some things. Now I’m getting an error. Who else is getting an error? One, anybody else? Everybody else is working. Some of you might be seeing running a number of tools. Gentleman who’s getting the error, are you using a locally signed SSL cert?
[Audience] [0:47:05]
I’m not using SSL at all.
[Jonathan Bossinger (Host)] [0:47:07]
You’re not using SSL at all. Not the critical error, the person who said they were getting an error when they ran the server.
[Audience] [0:47:10]
I believe so.
[Jonathan Bossinger (Host)] [0:47:11]
You believe you’re using a local, that’s the error, okay? So if you have a look at, and this is why I’m getting the same error, If you have a look in the WordPress Remote package and you go to docs, there is a troubleshooting section. There’s issues with different versions of Node.js if you have NVM installed. And then there’s an issue with local development environments and SSL. Node.js can’t verify the locally signed SSL cert. So all you have to do is just turn it off basically. So you copy this node TLS reject unauthorized bit, and you pop that at the top of your .env. Yes, Jai.
[Audience] [0:47:50]
I was just a step behind.
[Jonathan Bossinger (Host)] [0:47:52]
What are we supposed to do after putting in the log file? What was the step you mentioned? Click Start.
[Audience] [0:47:56]
Okay. Click Start on where?
[Jonathan Bossinger (Host)] [0:47:59]
So you should get, I’m gonna restart mine quickly and then I’m gonna stop it. You should get this little, why is it errored again? What? So basically, I’ll fix it now. Basically, it’s above where you specified AI experiments. You should see a little Start button. Are you not seeing that? Okay, all right. If you’re not seeing that, I think I might know what the problem is. I’ll come and help you debug in a second, okay? Has everybody else started their MCP server?
[Audience] [0:48:25]
No, I got the same error.
[Jonathan Bossinger (Host)] [0:48:26]
You got the same error as Jai’s getting? Yeah. Okay. You don’t see Start, okay, cool. Anybody else working? Everybody else got tools running? Those of you who’ve got tools running, Open up your GitHub CoPilot while I’m walking around helping folks and just do the question I just asked. Ask it to get you the site info and see what happens.
[Audience] [0:48:44]
Okay.
[Jonathan Bossinger (Host)] [0:48:45]
Let’s have a look at the front photos.
[Audience] [0:48:53]
Okay. So the problem is in your experience. Good luck using Composer. Thank you.
Expose the Ability as a Tool and Query Site Info Successfully
- 🧩 Adding the ability name to the server’s tools (or resources) array finally registers one tool with the running MCP server.
- 🗣️ A natural-language prompt like “get the site info from my AI experiments site” triggers tool detection and a permission prompt.
- 📊 After approval, the agent returns live site metadata, proving the local WordPress install is now an AI coding assistant.
[Jonathan Bossinger (Host)] [0:51:51]
Okay, so I managed to finish, I managed to fix one of three problems. I’m still going to get back to the folks who are having problems, but those of you who had it installed, did anything happen? Did it do anything interesting? Yes, no? No, it shouldn’t have, all right? I did that on purpose, I wanted you to figure it out. Who can tell me why it didn’t do anything? Who can take a guess? We set up our MCP adapter, we registered our ability, why is it not working? Yes, say again? Line 84, exactly. We haven’t told the MCP adapter to adapt any abilities. So it still doesn’t have any tools, right? So what we need to do is we need to take the ability’s name, which is the one, let me close this. We take the ability’s name, which is there, and, no, what did I just do? Fat fingers. And we add it to that array of abilities that need to be turned into tools or resources or whatever the case may be.
[Jonathan Bossinger (Host)] [0:52:55]
I’m just adding it into the tools list by now, but I should actually add it into resources. So now if this all works, if I go back and I, let’s say, go here and I open up Copilot and I say, get the site info from my AI experiments site. Can everybody see the agent mode on the side there? Can we see what’s happening? Let’s see what that does. So it’s still not happy. Oh, there’s an error, that’s why. Let me fix this error.
[Audience] [0:53:35]
Your error log is to a folder, not a file.
[Jonathan Bossinger (Host)] [0:53:40]
Ooh, who spotted that? Well done. That’s a t-shirt right there. That’s a t-shirt. I did it again. Okay, let’s try this one. Ah, who is that? Who said the error log?
[Audience] [0:53:56]
That’s medium, large? Large.
[Jonathan Bossinger (Host)] [0:54:04]
If you debug my code, I’ll give you a t-shirt.
[Audience] [0:54:08]
There you go.
[Jonathan Bossinger (Host)] [0:54:11]
Okay, so when that’s running, when it’s all working, and those of you who were having trouble earlier, we’ll come and sort you out. Maybe we’ll do it towards the end or something. But when it’s running, you’ll see it says running and there’s one tool. So that’s the tool that we set up from the ability. So now if we run that same code, or that same prompt, should I say, look at that. It detects that there’s a tool that can run site info. Now what’s happened here? In the background, I prompted, I sent the request to the code agent. It used the LLM to go, what is this person asking? Well, not really, it’s not thinking, but doing its thing. What is this person asking? Do I have any available tools on the server that could fulfill that request? It detects that it’s site info. Notice how I use the word site info. So when you’re registering your abilities and setting up your tools, make sure they make logical sense in terms of how you would call them in English. Don’t call them my plugin ability XYZ1. If it’s getting site info, call it get site info. And then it says, can I run this tool? Now you can obviously just continue. You could set it for every session, whatever the case may be. So I run that. It then makes the request, gets the data back, and says, hey, this is what’s running on your site.
[Jonathan Bossinger (Host)] [0:55:15]
OK, is anybody not getting that right now once they’ve added their ability to the list? One person not getting it. Who? Hands up if you are getting it, if it’s working. Nobody’s working. Damn it. Mine’s working. Works on my machine. So what happens? Is it still giving you the can’t— like, is it not running the tool? Is the server— those of you it’s not working for, is the server running? And it’s showing one tool. It’s not showing one tool. OK, so we’ve got a bunch of people with similar problems. We have to figure that one out.
[Audience] [0:55:49]
I have one tool, but it says the JSON schema is invalid.
[Jonathan Bossinger (Host)] [0:55:54]
It says the JSON schema is invalid. OK, so that might be— that’s weird because we all use the same code. So what I will say, are you using VS Code?
[Audience] [0:56:02]
I’m using VS Code and I grabbed it from the GitHub docs, but it is a little different than what you have. I don’t know if the docs got updated since this example.
[Jonathan Bossinger (Host)] [0:56:12]
It’s possible, it’s possible. Okay, we’ll have a look. So has anybody got it working? Anyone? One chap, okay, we’ll call it a win. All right, we’ve got another 30 minutes, so I’m gonna see if we can figure out some of these bugs. But what I’m hoping you’ll start to see now, and I want to basically, I want to disable this and I want to show you kind of some of the cool things that you can do.
Advanced Abilities: Debug Log, Plugin Check, and Content Tools
- 🧪 Jonathan’s sample MCP server ships get site info, get plugins, create post, debug-log fetch, and Plugin Check security runs.
- 🔍 Debug-log and plugin-check abilities feed errors and audit results into chat so the agent can propose and apply fixes.
- 🚀 These patterns unlock chat-driven workflows far beyond reading files—content ops, QA, and theme automation included.
[Jonathan Bossinger (Host)] [0:56:35]
So let me go over here. And down in the bottom of resources here, I’ve got this AI experiments MCP server that I built as an example for this workshop. So you’re welcome to have a look at this code. It has 4 abilities inside of it. The one ability is the get site info ability, the one we just built. Then I built a get plugins ability, which just gets the list of active plugins. Then there’s my favorite, the debug log one. So what that does is if debugging is enabled, it’ll pull the debug log in, it’ll show it on my site, I can then use it. There’s just a simple create post one. So you can use it to create posts, you can use it to update posts, you can use it to do whatever you want on your site. But my favorite is this one. So if you are a plugin developer, you will know that when you submit a plugin, you need to install a bunch of, you need to run a bunch of plugin checks. So you’ve probably heard of the Plugin Check plugin, right? So what this ability does is it allows you to run the security checks on your plugins while you’re coding in the AI code editor.
[Jonathan Bossinger (Host)] [0:57:38]
It’ll run those checks and then return the results to you in your chat. And then you can say, right, based on that, let’s fix them. And you can point at the files and the code and the whatever case may be. So what it starts doing is it starts opening up a different world of how you can use your WordPress sites and use the context that you give it and drive your AI coding. The last thing that I want to leave with you before we start helping folks debug some of these issues.
Abilities API Roadmap and a Call to Build
- 🧭 Core may ship the Abilities API in 6.9 as an empty canvas—no default abilities—so community-built abilities are essential.
- 💡 Ideas include newsletter assembly, WooCommerce sales summaries, multi-site plugin updates, and auto-saving block theme edits.
- 🏁 Attendees are challenged to invent abilities that make developer and customer workflows easier, not just clone CLI one-liners.
[Jonathan Bossinger (Host)] [0:58:04]
Abilities API is coming to WordPress, hopefully 6.9. That means just the API. No abilities. So by the time it launches, we can’t do anything with it. So if this was something that was interesting to you and you can see some use to this, what I would like to encourage you to do is to start building abilities for yourself, for your plugins, for your themes, for your websites. Think about how people could use this to use AI to power their content creation. Simple examples that I’ve had before. I’ve never, I’ve never managed a newsletter myself. But my understanding of managing newsletters, you need to pull posts in, you need to format it in a certain way. Imagine if you had an ability that just said create newsletter and it knew to get the last 3 posts on your site and 2 posts from those sites over there and put them together in a certain format. Maybe you’re using MailPoet or any other, what’s the one that Leslie did, the mail newsletter one plugin? Newsletter Glue, thank you Justin. And it just does it all for you. The other one that I’m really hoping to kind of work on, and Ryan’s experimented with this a little bit, is I want to build a couple of abilities that while you’re building a block theme, it’s automatically writing your save changes to the theme files.
[Jonathan Bossinger (Host)] [0:59:20]
Instead of having to use something like Create Block Theme, which has to pull it out for you and save it and do all that kind of stuff. So it just starts unlocking some automations, some sort of chat-enabled automations that I think are really, really cool. But right now it’s a blank slate. It’s an empty canvas. So if this is something that interests you and it’s something you want to play with and you want to check out, I do recommend installing those two plugins. Think about some abilities you can use. Some other examples I had was like, again, running a WooCommerce store. Give me an update on today’s worth of sales and then optimize for whatever, whatever the case may be. It’s just going to— it opens up so many things. Okay. We’ve got about 42 minutes left. Is there anybody here who would like to build their own custom Ability today?
[Audience] [1:00:04]
Anyone? No one?
[Jonathan Bossinger (Host)] [1:00:06]
You guys want to build one? Build a custom one? Any ideas? Everybody’s bored. It’s Friday. We want you to go have lunch and go home. Jonathan, shut up. Cool. Say it again? But what? But what? That’s the question.
[Audience] [1:00:20]
But what?
[Jonathan Bossinger (Host)] [1:00:22]
So my challenge to you is to go home and think about, but what? What do I want? What would make my job as a developer easier? And build it. Okay. Any other questions around all of this? Anybody?
[Audience] [1:00:39]
No.
[Jonathan Bossinger (Host)] [1:00:39]
Yes. Do you want to use the mic so they can— cool. Is this thing on?
[Audience] [1:00:47]
Okay.
Q&A: CLI vs MCP, Collaboration, and Closing Takeaways
- ⚖️ Prefer MCP for multi-step context (plugin checks, debug logs, cross-source content) rather than abilities that only wrap simple CLI commands.
- 💬 Join the Core AI Slack for ideas, biweekly meetings, and a hoped-for public abilities repo similar to Playground Blueprints.
- 🎉 Main takeaway: prepare now—MCP plus Abilities will unlock AI-powered WordPress automation; hang around for debugging help.
[Jonathan Bossinger (Host)] [1:00:49]
So when I first asked about plugins in my little assistant, for whatever reason, it just called the command line and it got a list of plugins, which is very performant. What has been your experience in the performance between just letting your Copilot or whatever use command lines versus, you know, an MCP server? Great question. So I will say this. I use, at the moment, I use Claude Code to vibe code, if you want for a better word. So I’m in the command line anyway. I would not build Abilities that just replicate command line things. So my site info Ability, my plugin list Ability, those aren’t Abilities that I would build. They’re just examples. What I would build is things like the plugin checks one. Now there is a, when you install the plugin check plugin, there is a command line that you can run, but then you have to go and get the results and then you have to pass through them.
[Jonathan Bossinger (Host)] [1:01:51]
That to me is something useful ’cause I can choose any, I can run it and then give that context directly to the AI and it starts fixing issues. So that’s the one that I, and I, here’s a fun story. When I was building, the plugin check, the plugin security checkability. It, the AI agent coded a bug, well, coded a bug. There was a bug in the code. So I needed to fix that bug. So that’s why I created the debug log ability, ’cause I wanted to just get that debug log to come in. And so that actually helped me fix the bug. I could then tell the agent, oh, this is the error that you’ve made, silly agent, go and fix it. And off it went and it fixed it. So just those kind of things that I would look at, stuff that doesn’t easily exist I mean, another good example is I work on a Linux workstation most days, and I have a one-liner command for setting up a new site. I’m not going to go and create an Ability for that, an MCP tool for that, because it’s one line. I’m not going to do something like that.
[Jonathan Bossinger (Host)] [1:02:52]
But for example, when I am preparing content, I’m often needing to pull information from a number of different sources. Some of it might be text-based. Some of it might be things on GitHub that I want to pull in. So something that I’ve thought about, there’s an MCP server for GitHub that you can install and set up. Something I’ve thought about is how do I use a WordPress server to give me access to WordPress? How do I use the GitHub server to give me access to code repositories, my code repositories on GitHub? And then pull those together to help me create the content. So it uses the code that I’ve built on my GitHub repos as opposed to some AI-generated code. It uses the access in my Word, so for my personal WordPress blog. It uses the blogs that I, ’cause I’ll often write a blog post and it’ll be linked to something else that’s happened and I want to pull some information in from there, whatever the case may be. Those are the kind of things that I would use this for. Yeah, any other questions?
[Jonathan Bossinger (Host)] [1:03:52]
Okay, does anybody want to, so we’ve got, yes, we’ve got one question over there, go for it.
[Audience] [1:04:01]
Yeah.
[Jonathan Bossinger (Host)] [1:04:02]
Hi, I’m really interested specifically around the debug log and WordPress upgrades. I see a lot of potential use for that and performance increases. Hmm.
[Audience] [1:04:12]
When we have other use cases, what’s the best way to reach out to you? I see you have a lot of repositories. How should we reach out to you and maybe ask questions or come up with new use cases and collaborate with you on that? Cool.
[Jonathan Bossinger (Host)] [1:04:25]
So I would say reaching out to me is probably not the best thing to do because I’ll do my best to point you in the right direction. But if you didn’t know, there is a Core AI team in the WordPress Slack that you can join. We’re very friendly. We’re looking for people to come up with ideas and abilities and that kind of thing. So that would be the best place to start. So join the— I think it’s just Core AI. Join the Core AI team in Slack. And in fact, last week we have biweekly meetings every 2 weeks. I have to say that for myself to remind myself. But last week, the week before we came to WordCamp US, people were saying, hey, is anybody building anything interesting with this stuff? And I shared my repository of Abilities. What I would like to start seeing is as a project, and I’m gonna propose this in a future meeting, we actually create a public GitHub repo under the WordPress organization where folks can submit Abilities. Those of you who will know Playground will know that when Blueprints came out, you could submit Blueprints. And I would like to see a similar environment because I feel like getting that kind of feedback from the community about what abilities they would like to see, what abilities they would like to be able to use, we can then look at which of those abilities can come to core and which need to stay in maybe canonical plugin environment or whatever the case may be.
[Jonathan Bossinger (Host)] [1:05:38]
So start with the core AI Slack channel. I’ll probably be there anyway, because that’s where I’m hanging out a lot lately. And I’ll point you in the right direction if need be. That’s the best place. Awesome. Thank you. That deserves a t-shirt.
[Audience] [1:05:50]
Medium, large, small, large, large. That’s a lot.
[Jonathan Bossinger (Host)] [1:06:09]
OK. Any other questions? So I’m going to be honest. I didn’t expect us to get— get this far this quickly. So I didn’t have anything, anything else prepared. So what I’m going to suggest is this. If you would like to hang around for a bit and chat about this and come up to me or whatever the case may be, maybe help, help some of the folks who are having struggles here, please do so. Otherwise, I’m going to give you a little bit extra time off and you can go and hang out in the, in the sponsor hall. If you have any other questions, you’re welcome to come and give me a shout. But the main takeaway that I would like to give to you today is this is coming. Start getting yourself ready for it because it’s going to unlock and open up a whole bunch of things for AI and WordPress. Think about those use cases. Think about the stuff that isn’t solved already or could be solved in a better way or could be solved in a more streamlined way. Think about the prompts. Think about the workflows. What are the things that I need to automate to make my life easier, my customers’ lives easier? Simple things like something else that I’ve thought about is like if you’re managing multiple WordPress sites, the ability to be able to go, hey, update. I mean, maybe you wouldn’t do this, but update all the plugins across these 10 sites.
[Jonathan Bossinger (Host)] [1:07:11]
Go off and do it. Those are the kind of things that this unlocks. So thank you so much for coming. I hope this was interesting and useful. If you were having any problems or critical issues, please do hang around. I’ll come around and help you. But otherwise, thank you very much for your time and enjoy the rest of your day.
