WP MCP Server
Exposes WordPress as an MCP server for Claude Desktop and other MCP clients.
by Generated · github.com/bhavik-dreamz/wordpress-mcp-server · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/bhavik-dreamz/wordpress-mcp-server/archive/refs/heads/main.zipExposes a WordPress site as an MCP (Model Context Protocol) server so MCP clients like Claude Desktop can call tools over HTTP (JSON-RPC). This plugin implements REST endpoints and a set of tools for WordPress and WooCommerce data access.
Features
- Exposes
/wp-json/wp-mcp/v1/info(public) and/wp-json/wp-mcp/v1/mcp(JSON-RPC entrypoint) - Authentication via WordPress Application Passwords (Basic auth header)
- Tools: search_posts, search_pages, search_post_categories, search_tags, create_post, create_page, create_category, search_custom_post_types, create_custom_post_type, search_products, create_product, search_product_categories, create_order, get_orders, get_order_details, create_user, recommend_products
- Admin settings page to configure site URL, enabled tools, CPT whitelist, and test credentials
- WooCommerce-aware: product/order tools only active when WooCommerce is present
Installation
- Copy the
wp-mcp-serverfolder into your WordPresswp-content/plugins/directory (or use this repo as the plugin folder). - From the plugin folder, install Composer dependencies:
cd e:\path\to\wp-mcp-server
composer install
- Activate the plugin in WordPress (Plugins → Installed Plugins).
- Go to Settings → WP MCP Server to configure the Site URL, enable tools, and whitelist CPTs.
- Create an Application Password for a user (Users → Profile → Application Passwords) and use those credentials for MCP clients.
Endpoints
-
GET {site_url}/wp-json/wp-mcp/v1/info
- Public: returns plugin version, site name, available tools.
-
POST {site_url}/wp-json/wp-mcp/v1/mcp
- Protected: requires header
Authorization: Basic base64(username:application_password) - Accepts JSON-RPC 2.0 requests. Supported methods:
tools/listandtools/call.
- Protected: requires header
Example JSON-RPC request (tools/list):
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
Example JSON-RPC request (call a tool):
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search_posts",
"arguments": { "query": "hello", "per_page": 5 }
}
}
MCP Tool Reference
Use tools/list to discover currently available tools for your site/user context. The list depends on:
- which tools are enabled in Settings → WP MCP Server
- whether WooCommerce is active
- current user capability (for order tools)
Content tools (WordPress core)
These tools let MCP clients work with WordPress content data (posts, pages, and custom post types), not only WooCommerce.
-
search_posts- Purpose: Search public posts (or another valid post type).
- Arguments:
query(string, optional)post_type(string, optional, defaultpost)per_page(integer, optional, default10)page(integer, optional, default1)
- Returns:
{ "results": [...], "total": <number> }
-
search_pages- Purpose: Search WordPress pages.
- Arguments:
query(string, optional)per_page(integer, optional, default10)page(integer, optional, default1)
- Returns: same structure as
search_posts.
-
search_custom_post_types- Purpose: Search a custom post type that is whitelisted in plugin settings.
- Arguments:
post_type(string, required)query(string, optional)meta_filters(array, optional) e.g.[{"key":"city","value":"London"}]per_page(integer, optional, default10)page(integer, optional, default1)
- Returns:
{ "results": [...], "total": <number> }
-
search_post_categories- Purpose: Search WordPress blog categories.
- Arguments:
query(string, optional)parent_id(integer, optional)per_page(integer, optional, default20)
- Returns:
{ "results": [...] }
-
search_tags- Purpose: Search WordPress blog tags.
- Arguments:
query(string, optional)per_page(integer, optional, default20)
- Returns:
{ "results": [...] }
-
create_post
- Purpose: Create a new WordPress post.
- Arguments:
title(string, required)content(string, optional)excerpt(string, optional)status(string, optional, defaultdraft)slug(string, optional)author_id(integer, optional)
- Returns: created post object with
id,post_type,status,url.
create_page
- Purpose: Create a new WordPress page.
- Arguments: same as
create_post. - Returns: created page object.
create_category
- Purpose: Create a WordPress blog category.
- Arguments:
name(string, required)slug(string, optional)parent_id(integer, optional)description(string, optional)
- Returns: created category object with
id,taxonomy,name,url.
Category and order tools
- WordPress category and tag tools are available as
search_post_categoriesandsearch_tags. - WooCommerce product category search is available as
search_product_categories. - Order details are available via
get_order_details(WooCommerce + proper capability required).
WooCommerce tools (only when WooCommerce is installed)
-
search_products- Purpose: Search products with optional category, stock, and price filtering.
- Arguments:
query(string, optional)category_id(integer, optional)min_price(number, optional)max_price(number, optional)in_stock(boolean, optional)per_page(integer, optional, default10)page(integer, optional, default1)
- Returns:
{ "results": [...] }
-
create_custom_post_type- Purpose: Create a CPT item (CPT must be allowed in plugin settings).
- Arguments:
post_type(string, required)title(string, required)content(string, optional)excerpt(string, optional)status(string, optional, defaultdraft)slug(string, optional)author_id(integer, optional)
- Returns: created item object with
id,post_type,status,url.
-
search_product_categories- Purpose: Search/list product categories.
- Arguments:
query(string, optional)parent_id(integer, optional)per_page(integer, optional, default20)
- Returns:
{ "results": [...] }
-
create_product- Purpose: Create a WooCommerce product.
- Access: requires a user with
manage_woocommercecapability. - Arguments:
name(string, required)description(string, optional)short_description(string, optional)status(string, optional, defaultdraft)regular_price(number, optional)sale_price(number, optional)sku(string, optional)manage_stock(boolean, optional)stock_quantity(integer, optional)category_ids(array, optional)
- Returns: created product object.
-
create_order- Purpose: Create a WooCommerce order with line items.
- Access: requires a user with
manage_woocommercecapability. - Arguments:
line_items(array, required) e.g.[{"product_id":123,"quantity":2}]customer_id(integer, optional)billing(object, optional)shipping(object, optional)status(string, optional)
- Returns: created order summary (
id,status,total,currency).
-
get_orders- Purpose: List orders with filters.
- Access: requires a user with
manage_woocommercecapability. - Arguments:
status(string, optional)customer_id(integer, optional)date_from(string, optional,YYYY-MM-DD)date_to(string, optional,YYYY-MM-DD)per_page(integer, optional, default10)page(integer, optional, default1)
- Returns:
{ "results": [...] }
-
get_order_details- Purpose: Fetch full order details (billing/shipping, line items, totals, notes).
- Access: requires a user with
manage_woocommercecapability. - Arguments:
order_id(integer, required)
- Returns: order object (not wrapped in
results).
-
create_user- Purpose: Create a WordPress user.
- Access: requires a user with
create_userscapability. - Arguments:
username(string, required)email(string, required)password(string, optional)display_name(string, optional)role(string, optional, defaultsubscriber)
- Returns: created user object.
-
recommend_products- Purpose: Return product recommendations.
- Arguments:
strategy(string, optional):related,upsell,crosssell,bestseller,new_arrivalsproduct_id(integer, required forrelated,upsell,crosssell)category_id(integer, optional)limit(integer, optional, default5)
- Returns:
{ "results": [...] }
How to use tools (copy/paste flow)
- Call
tools/list
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
-
Pick a tool name from
tools[].name -
Call
tools/callwithparams.nameandparams.arguments
Example: search products in-stock under price 50
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search_products",
"arguments": {
"query": "shirt",
"in_stock": true,
"max_price": 50,
"per_page": 5
}
}
}
Example: get a single order detail
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_order_details",
"arguments": {
"order_id": 1234
}
}
}
More examples (post + page + CPT + categories/tags + order)
Example: search blog posts
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "search_posts",
"arguments": {
"query": "shipping policy",
"post_type": "post",
"per_page": 5,
"page": 1
}
}
}
Example: search pages
{
"jsonrpc": "2.0",
"id": 11,
"method": "tools/call",
"params": {
"name": "search_pages",
"arguments": {
"query": "returns",
"per_page": 5
}
}
}
Example: search custom post type (CPT)
{
"jsonrpc": "2.0",
"id": 12,
"method": "tools/call",
"params": {
"name": "search_custom_post_types",
"arguments": {
"post_type": "event",
"query": "summer",
"meta_filters": [
{ "key": "city", "value": "London" }
],
"per_page": 10
}
}
}
Example: search WordPress post categories
{
"jsonrpc": "2.0",
"id": 13,
"method": "tools/call",
"params": {
"name": "search_post_categories",
"arguments": {
"query": "news",
"per_page": 20
}
}
}
Example: search WordPress tags
{
"jsonrpc": "2.0",
"id": 14,
"method": "tools/call",
"params": {
"name": "search_tags",
"arguments": {
"query": "featured",
"per_page": 20
}
}
}
Example: create a post
{
"jsonrpc": "2.0",
"id": 15,
"method": "tools/call",
"params": {
"name": "create_post",
"arguments": {
"title": "New Shipping Update",
"content": "We now support express shipping.",
"status": "publish"
}
}
}
Example: create a category
{
"jsonrpc": "2.0",
"id": 16,
"method": "tools/call",
"params": {
"name": "create_category",
"arguments": {
"name": "Announcements",
"slug": "announcements"
}
}
}
Example: create a product
{
"jsonrpc": "2.0",
"id": 17,
"method": "tools/call",
"params": {
"name": "create_product",
"arguments": {
"name": "Classic Hoodie",
"regular_price": 49.99,
"status": "publish",
"manage_stock": true,
"stock_quantity": 25
}
}
}
Example: create an order
{
"jsonrpc": "2.0",
"id": 18,
"method": "tools/call",
"params": {
"name": "create_order",
"arguments": {
"customer_id": 12,
"line_items": [
{ "product_id": 101, "quantity": 2 }
],
"status": "processing"
}
}
}
Example: create a user
{
"jsonrpc": "2.0",
"id": 19,
"method": "tools/call",
"params": {
"name": "create_user",
"arguments": {
"username": "new_customer",
"email": "new_customer@example.com",
"role": "customer"
}
}
}
Example: search product categories
{
"jsonrpc": "2.0",
"id": 20,
"method": "tools/call",
"params": {
"name": "search_product_categories",
"arguments": {
"query": "hoodie",
"per_page": 20
}
}
}
Example: get order details
{
"jsonrpc": "2.0",
"id": 21,
"method": "tools/call",
"params": {
"name": "get_order_details",
"arguments": {
"order_id": 1234
}
}
}
Common errors you may see
woocommerce_missing: WooCommerce is not installed/active for Woo tools.insufficient_capability: user lacks permission for order tools.invalid_post_type: invalid post type value.invalid_taxonomy: taxonomy must becategoryorpost_tagfor WP taxonomy tools.post_type not allowed: CPT not whitelisted in plugin settings.name parameter required/Unknown tool: wrongtools/callpayload.
Claude Desktop config (example)
{
"mcpServers": {
"wordpress-site": {
"command": "curl",
"args": [
"-X", "POST",
"-H", "Content-Type: application/json",
"-H", "Authorization: Basic {base64_credentials}",
"-d", "@-",
"{site_url}/wp-json/wp-mcp/v1/mcp"
]
}
}
}
Replace {base64_credentials} with base64 of username:application_password and {site_url} with your configured site URL.
Security
- Uses WordPress Application Passwords for all
/mcprequests. - Admin AJAX uses nonces and capability checks.
- Inputs are sanitized using WordPress helpers.
Notes
- If WooCommerce is not active, WooCommerce-specific tools will be hidden and unavailable.
- The plugin will use
logiscape/mcp-sdk-phpif present (installed via Composer). If the SDK is missing the plugin falls back to a minimal JSON-RPC router that still supports tools/list and tools/call.
Contributing
- Please follow WordPress coding standards and use the built-in APIs for data access (no direct DB queries).
License
- MIT (add or change as needed)