mcp-core.php
1 year ago
mcp-rest.php
1 year ago
mcp.conf
1 year ago
mcp.js
1 year ago
mcp.md
1 year ago
mcp.php
1 year ago
oauth.php
1 year ago
realtime.php
1 year ago
mcp.md
318 lines
| 1 | # Using MCP with AI Engine |
| 2 | |
| 3 | ## What's this all about? |
| 4 | |
| 5 | **Model‑Context‑Protocol (MCP)** is the open standard Claude uses to talk to external *tool servers.* When Claude detects an MCP server it can: |
| 6 | |
| 7 | 1. **list** the server's tools (`tools/list`), |
| 8 | 2. (optionally) let you pick one, then |
| 9 | 3. **call** a tool (`tools/call`) via JSON‑RPC. |
| 10 | |
| 11 | With **AI Engine** active your WordPress site publishes **30‑plus tools** that let Claude: |
| 12 | |
| 13 | - read & write posts, pages and custom post‑types, |
| 14 | - upload or generate media, |
| 15 | - manage categories, tags & any taxonomy, |
| 16 | - switch, fork and live‑edit themes, |
| 17 | - list plugins… and more. |
| 18 | |
| 19 | `mcp.js` is the Node relay that connects Claude Desktop to your WordPress site seamlessly. |
| 20 | |
| 21 | > **Heads‑up – advanced users only.** Everything here is still beta. Be ready for CLI work, PHP/FPM restarts and some detective work if hosting layers interfere. |
| 22 | |
| 23 | --- |
| 24 | |
| 25 | ## 1 · Quick Start |
| 26 | |
| 27 | ### Requirements |
| 28 | - **WordPress 6.x** with REST API enabled |
| 29 | - **AI Engine plugin** active |
| 30 | - **Claude Desktop ≥ 0.9.2** |
| 31 | - **Node ≥ 20.19.0** |
| 32 | |
| 33 | ### Setup (3 simple steps) |
| 34 | |
| 35 | 1. **Set a token in WordPress** |
| 36 | Go to **AI Engine › DevTools › MCP Settings** and set a **Bearer token** |
| 37 | |
| 38 | 2. **Add your site** |
| 39 | ```bash |
| 40 | ./mcp.js add https://yoursite.com YOUR_TOKEN |
| 41 | ``` |
| 42 | |
| 43 | 3. **Test the connection** |
| 44 | ```bash |
| 45 | ./mcp.js start |
| 46 | ``` |
| 47 | |
| 48 | That's it! Claude should now show a **plug icon** and **hammer** with ≈30 tools. |
| 49 | |
| 50 | --- |
| 51 | |
| 52 | ## 2 · Available Commands |
| 53 | |
| 54 | ```bash |
| 55 | # Add a new site (automatically sets it as Claude's target) |
| 56 | ./mcp.js add <site-url> <token> |
| 57 | |
| 58 | # List all registered sites (→ shows current Claude target) |
| 59 | ./mcp.js list |
| 60 | |
| 61 | # Interactively select which site Claude should use |
| 62 | ./mcp.js select |
| 63 | |
| 64 | # Test connection with verbose output |
| 65 | ./mcp.js start |
| 66 | |
| 67 | # Remove a site |
| 68 | ./mcp.js remove <site-url> |
| 69 | |
| 70 | # Advanced: Manual testing |
| 71 | ./mcp.js post <domain> <json> <session_id> |
| 72 | ``` |
| 73 | |
| 74 | ### Smart Defaults |
| 75 | - `start` automatically uses the site Claude is configured for |
| 76 | - `add` automatically sets the new site as Claude's target |
| 77 | - `select` shows a numbered menu when you have multiple sites |
| 78 | |
| 79 | --- |
| 80 | |
| 81 | ## 3 · Testing Your Connection |
| 82 | |
| 83 | When you run `./mcp.js start`, you'll see: |
| 84 | |
| 85 | ``` |
| 86 | /\_/\ |
| 87 | ( o.o ) |
| 88 | > ^ < Welcome to MCP by AI Engine |
| 89 | |
| 90 | ▶ Connecting to MCP server |
| 91 | https://yoursite.com/wp-json/mcp/v1/sse/ |
| 92 | |
| 93 | ✓ SSE connection established |
| 94 | ✓ MCP server connected |
| 95 | https://yoursite.com/wp-json/mcp/v1/messages?session_id=abc123... |
| 96 | |
| 97 | Test the connection in another terminal: |
| 98 | ./mcp.js post yoursite.com '{"jsonrpc":"2.0","method":"tools/list","id":1}' abc123... |
| 99 | |
| 100 | Or test with simple ping (requires Tuned Core): |
| 101 | ./mcp.js post yoursite.com '{"jsonrpc":"2.0","method":"mcp_ping","id":2}' abc123... |
| 102 | |
| 103 | Results will appear in this terminal. |
| 104 | ``` |
| 105 | |
| 106 | Just copy-paste one of the test commands to verify everything works! |
| 107 | |
| 108 | --- |
| 109 | |
| 110 | ## 4 · Multiple Sites Made Easy |
| 111 | |
| 112 | If you have multiple WordPress sites: |
| 113 | |
| 114 | ```bash |
| 115 | # Add all your sites |
| 116 | ./mcp.js add https://site1.com TOKEN1 |
| 117 | ./mcp.js add https://site2.com TOKEN2 |
| 118 | ./mcp.js add https://site3.com TOKEN3 |
| 119 | |
| 120 | # See which one Claude is using |
| 121 | ./mcp.js list |
| 122 | # Output: |
| 123 | # → https://site3.com |
| 124 | # • https://site1.com |
| 125 | # • https://site2.com |
| 126 | |
| 127 | # Switch to a different site |
| 128 | ./mcp.js select |
| 129 | # Shows interactive menu: |
| 130 | # Select a site for Claude: |
| 131 | # 1. https://site1.com |
| 132 | # 2. https://site2.com |
| 133 | # 3. https://site3.com (current) |
| 134 | # |
| 135 | # Enter selection (1-3): 1 |
| 136 | # ✓ Claude → https://site1.com |
| 137 | ``` |
| 138 | |
| 139 | --- |
| 140 | |
| 141 | ## 5 · Prompt Ideas |
| 142 | |
| 143 | | Level | Example | |
| 144 | | -------------- | ----------------------------------------------------------------------------------------------------------------------------------- | |
| 145 | | *Simple* | "List my latest 5 posts." "Create a post titled *My AI Journey* (one paragraph) and attach a media‑library image." | |
| 146 | | *Intermediate* | "Look at the 10 newest posts, then publish a logical follow‑up. Re‑use existing categories & tags. If no image fits, generate one." | |
| 147 | | *Advanced* | "Fork *Twenty Twenty‑One* into a grid‑layout theme called *Futurism* supporting post types Article & Project." | |
| 148 | |
| 149 | --- |
| 150 | |
| 151 | ## 6 · Troubleshooting |
| 152 | |
| 153 | ### Authentication Issues |
| 154 | - **Claude shows no tools**: Check your Bearer token in WordPress matches what you used with `add` |
| 155 | - **401/403 errors**: Token mismatch - re-run `./mcp.js add yoursite.com CORRECT_TOKEN` |
| 156 | |
| 157 | ### Connection Issues |
| 158 | - **Can't connect**: Check if your site's `/wp-json/mcp/v1/sse` endpoint is accessible |
| 159 | - **Stalls on managed hosting**: See hosting caveats below |
| 160 | |
| 161 | ### Quick Reset |
| 162 | ```bash |
| 163 | ./mcp.js remove yoursite.com |
| 164 | ./mcp.js add yoursite.com YOUR_TOKEN |
| 165 | ./mcp.js start # test again |
| 166 | ``` |
| 167 | |
| 168 | --- |
| 169 | |
| 170 | ## 7 · Hosting Caveats |
| 171 | |
| 172 | ### Edge Caching (Cloudflare/Kinsta) |
| 173 | Edge caching must be **bypassed** for `/wp-json/mcp/*` routes: |
| 174 | |
| 175 | *Cloudflare Dashboard › Rules › Bypass Cache* for pattern `/wp-json/mcp/*` |
| 176 | |
| 177 | ### PHP Worker Limits |
| 178 | Each SSE connection uses one PHP worker. On shared hosting (5-8 workers), multiple Claude tabs can exhaust your pool. |
| 179 | |
| 180 | ### If Site Stalls |
| 181 | ```bash |
| 182 | # Reset and restart PHP |
| 183 | sudo systemctl restart php-fpm |
| 184 | ./mcp.js start # try again |
| 185 | ``` |
| 186 | |
| 187 | --- |
| 188 | |
| 189 | ## 8 · Advanced Usage |
| 190 | |
| 191 | ### Manual JSON-RPC Testing |
| 192 | ```bash |
| 193 | # Test tools list |
| 194 | ./mcp.js post yoursite.com '{"jsonrpc":"2.0","method":"tools/list","id":1}' SESSION_ID |
| 195 | |
| 196 | # Test simple ping (requires Tuned Core) |
| 197 | ./mcp.js post yoursite.com '{"jsonrpc":"2.0","method":"mcp_ping","id":2}' SESSION_ID |
| 198 | ``` |
| 199 | |
| 200 | ### Logs Location |
| 201 | All logs are stored in `~/.mcp/`: |
| 202 | - `mcp.log` - Headers and requests |
| 203 | - `mcp-results.log` - Full responses |
| 204 | - `error.log` - Errors and crashes |
| 205 | - `sites.json` - Your registered sites |
| 206 | |
| 207 | ### Verbose PHP Logging |
| 208 | ```php |
| 209 | // wp-content/plugins/ai-engine/classes/modules/mcp.php |
| 210 | private $logging = true; |
| 211 | ``` |
| 212 | |
| 213 | Then tail `wp-content/debug.log`. |
| 214 | |
| 215 | ### Adding Custom MCP Tools |
| 216 | |
| 217 | Developers can extend MCP with custom tools using WordPress filters. Here's an example that adds a search function: |
| 218 | |
| 219 | ```php |
| 220 | // In your theme's functions.php or a custom plugin |
| 221 | |
| 222 | // Register your custom tool |
| 223 | add_filter( 'mwai_mcp_tools', function( $tools ) { |
| 224 | $tools[] = [ |
| 225 | 'name' => 'search_posts', |
| 226 | 'description' => 'Search posts by keyword and return titles with URLs', |
| 227 | 'inputSchema' => [ |
| 228 | 'type' => 'object', |
| 229 | 'properties' => [ |
| 230 | 'keyword' => [ |
| 231 | 'type' => 'string', |
| 232 | 'description' => 'The keyword to search for in post titles and content', |
| 233 | ], |
| 234 | 'limit' => [ |
| 235 | 'type' => 'number', |
| 236 | 'description' => 'Maximum number of results to return (default: 10)', |
| 237 | 'default' => 10, |
| 238 | ], |
| 239 | ], |
| 240 | 'required' => ['keyword'], |
| 241 | ], |
| 242 | ]; |
| 243 | |
| 244 | return $tools; |
| 245 | }); |
| 246 | |
| 247 | // Handle the tool execution - just return the result! |
| 248 | add_filter( 'mwai_mcp_callback', function( $result, $tool, $args, $id ) { |
| 249 | if ( $tool !== 'search_posts' ) { |
| 250 | return $result; |
| 251 | } |
| 252 | |
| 253 | $keyword = $args['keyword'] ?? ''; |
| 254 | $limit = $args['limit'] ?? 10; |
| 255 | |
| 256 | // Perform the search |
| 257 | $query = new WP_Query([ |
| 258 | 's' => $keyword, |
| 259 | 'post_type' => 'post', |
| 260 | 'post_status' => 'publish', |
| 261 | 'posts_per_page' => $limit, |
| 262 | ]); |
| 263 | |
| 264 | $results = []; |
| 265 | if ( $query->have_posts() ) { |
| 266 | while ( $query->have_posts() ) { |
| 267 | $query->the_post(); |
| 268 | $results[] = [ |
| 269 | 'title' => get_the_title(), |
| 270 | 'url' => get_permalink(), |
| 271 | 'excerpt' => get_the_excerpt(), |
| 272 | 'date' => get_the_date(), |
| 273 | ]; |
| 274 | } |
| 275 | wp_reset_postdata(); |
| 276 | } |
| 277 | |
| 278 | // Simply return the results - AI Engine handles the JSON-RPC wrapping! |
| 279 | return $results; |
| 280 | |
| 281 | // You can also return: |
| 282 | // - A string: return 'Found ' . count($results) . ' posts'; |
| 283 | // - An array with 'content' key for custom formatting: |
| 284 | // return [ |
| 285 | // 'content' => [ |
| 286 | // ['type' => 'text', 'text' => 'Search results:'], |
| 287 | // ['type' => 'text', 'text' => json_encode($results)] |
| 288 | // ] |
| 289 | // ]; |
| 290 | }, 10, 4 ); |
| 291 | ``` |
| 292 | |
| 293 | This simplified example shows: |
| 294 | - Using `mwai_mcp_tools` filter to register new tools |
| 295 | - Defining proper `inputSchema` for tool parameters |
| 296 | - Using `mwai_mcp_callback` filter to handle tool execution |
| 297 | - **Just returning your data** - AI Engine automatically handles the JSON-RPC protocol! |
| 298 | |
| 299 | The callback can return: |
| 300 | - **A string**: Simple text response |
| 301 | - **An array**: Will be JSON-encoded and sent to Claude |
| 302 | - **An array with 'content' key**: For custom formatting with multiple text blocks |
| 303 | - **Throw an Exception**: For error handling (AI Engine will format it properly) |
| 304 | |
| 305 | Claude will automatically discover your custom tool and can use it like: |
| 306 | > "Search for posts about 'artificial intelligence' and show me the top 5 results" |
| 307 | |
| 308 | --- |
| 309 | |
| 310 | ## 9 · What Happens Under the Hood |
| 311 | |
| 312 | 1. `mcp.js` opens a long‑lived **SSE** connection to `/wp-json/mcp/v1/sse` |
| 313 | 2. WordPress sends back a session URL: `/wp-json/mcp/v1/messages?session_id=...` |
| 314 | 3. The relay tunnels Claude's JSON‑RPC to that messages endpoint |
| 315 | 4. Responses stream back to Claude via stdout |
| 316 | 5. When Claude quits, the relay sends `{"method":"mwai/kill"}` and cleans up |
| 317 | |
| 318 | Simple and reliable! |