WordPress MCP Server

WordPress MCP Server

An MCP server that enables AI agents to manage WordPress sites, including Elementor page building, content CRUD, plugin management, and site configuration via the WordPress REST API.

Category
Visit Server

README

WordPress MCP Server v2.7 - Elementor Control Plane

šŸŽ‰ What's New in v2.7

  • šŸ–‹ļø Reliable Elementor writes — every tool that writes _elementor_data now routes through a privileged agency-os/v1/elementor-data endpoint that does a direct update_post_meta behind an edit_post capability check. This sidesteps core REST's refusal to write the protected _elementor_data postmeta (reads always worked; writes used to fail). If the route isn't installed, writes transparently fall back to the core meta write.
    • Recommended install (no mu-plugin): run wp_bootstrap_elementor_writer — it registers the route inside an active Code Snippet, so there's no file written to disk and no mu-plugin. Idempotent; re-running just refreshes the snippet.
    • The same route is also bundled into the Agency OS File API mu-plugin, so sites that already ran wp_bootstrap_file_api get it for free (run it again, or with force: true, to upgrade an older install).
    • wp_check_file_api reports whether the Elementor write route is present (elementor_write_route).
  • āœ‚ļø Page excerpt support — wp_update_page and wp_create_page now accept excerpt. Passing excerpt: "" to wp_update_page cleanly clears an existing excerpt (previously there was no way to delete a page excerpt via MCP).
  • 🧩 Code Snippets management — new wp_list_snippets / wp_get_snippet / wp_create_snippet / wp_update_snippet / wp_activate_snippet / wp_deactivate_snippet / wp_delete_snippet wrap the Code Snippets plugin REST API, so agents can install a guard snippet (or any PHP/JS/CSS snippet) without shipping an mu-plugin.

šŸŽ‰ What's New in v2.6

NEW: Pure-REST Control Plane for Elementor — agents can ship redesigns and bulk-edit text across any client's Elementor pages without installing a single line of PHP on the target site. Stateless, REST-only, and verified byte-for-byte on every write.

v2.6 Features:

  • šŸŽÆ wp_publish_draft_over — promote a draft on top of a live page: copies title, content, _elementor_data, page settings, featured image, Yoast/RankMath SEO, excerpt, template, menu_order (and optionally taxonomies) into the target. Live URL/ID are preserved. Draft is deleted on verified write.
  • šŸ” wp_replace_text — find/replace across post_content AND every Elementor widget text field (headings, buttons, editor HTML, captions, tab titles, testimonials, etc.). Supports regex, case-insensitive, and dry_run preview. Skips dynamic-tag fields.
  • šŸ“¦ wp_get_page_state — capture a normalized, restore-able state object before a multi-step edit.
  • ā†©ļø wp_restore_page_state — write a previously-captured state back onto a page. Verifies _elementor_data byte-length on restore.
  • 🧱 Curated block library — wp_elementor_list_blocks / wp_elementor_get_block / wp_elementor_insert_block let agents compose pages from vetted Elementor sections instead of hand-rolling JSON.
  • šŸ“ wp_elementor_guidelines — surfaces the site's design tokens (typography, colors, spacing) so generated content matches the brand.
  • šŸ” Hardened transport — bearer-auth, body-size caps, log redaction, fetch timeout + retry with exponential backoff.

Why this matters: rollback no longer relies on WordPress revisions. Empirical tests on multiple live sites confirmed that the WP REST revision endpoint does not expose _elementor_data — so revisions can't restore Elementor pages, full stop. v2.6 sidesteps this by returning the full pre-write previous_state in every destructive op. The caller keeps it, the caller restores when needed. Zero state at the MCP server, zero state at the WP site.

v2.5 Features:

  • šŸ›’ WooCommerce Products - Full CRUD for products with images, stock, pricing
  • šŸ“‚ Product Categories - Create, update, delete product categories
  • šŸ”€ Product Variations - Manage variable products and their variations
  • šŸ“¦ Orders Management - List, view, and update order status
  • šŸ–¼ļø Product Images - Add/update product images via URL or media ID

v2.3 Features:

  • šŸ”Œ Plugin Management - Complete CRUD for WordPress plugins
  • šŸ“¦ Install from WordPress.org - wp_install_plugin by slug
  • šŸ“„ Install from ZIP URL - wp_install_plugin_zip from any URL
  • āœ… Activate/Deactivate - wp_activate_plugin, wp_deactivate_plugin
  • šŸ—‘ļø Delete Plugins - wp_delete_plugin (must be deactivated first)
  • šŸ”„ Update Plugins - wp_update_plugin to latest version
  • šŸ“‹ List Plugins - wp_list_plugins with status/search filters

v2.2 Features:

  • ✨ Special Pages API - wp_get_special_pages endpoint for homepage, blog, and privacy policy pages
  • ✨ Enhanced Site Info - wp_get_site_info now includes special page IDs and reading settings
  • šŸ  Homepage Detection - Automatically detects static homepage or posts listing
  • šŸ“ Blog Page ID - Get the blog listing page when using static homepage
  • šŸ”’ Privacy Policy Page - Direct access to privacy policy page details

v2.1 Features:

  • ✨ HTTP REST API - GET /api/find endpoint for direct queries
  • ✨ Unified Search - Automatically searches both posts AND pages in one call
  • ✨ Multi-Client Support - Query different WordPress sites using client parameter
  • šŸ¤– Auto-Detection - Automatically detects client from URL domain (no manual client parameter needed!)
  • ✨ API Key Authentication - Secure your endpoint with shared API key
  • ✨ Flexible Search - Find content by slug, full URL, or text search

v2.0 Features:

36 Total Endpoints (up from 18) - 100% increase in functionality!

New Features Added:

šŸ“ Media Management - COMPLETE

  • āœ… wp_get_media - List all media files
  • āœ… wp_get_media_item - Get specific media item
  • āœ… wp_upload_media - Upload new media
  • ✨ NEW wp_update_media - Update metadata (title, alt text, caption, description)
  • ✨ NEW wp_delete_media - Delete media files

šŸ’¬ Comments - FULL CRUD

  • ✨ NEW wp_get_comments - List comments with filters
  • ✨ NEW wp_get_comment - Get specific comment
  • ✨ NEW wp_create_comment - Create new comments
  • ✨ NEW wp_update_comment - Update comment content/status
  • ✨ NEW wp_delete_comment - Delete comments

šŸ‘„ Users

  • ✨ NEW wp_get_users - List all users
  • ✨ NEW wp_get_user - Get specific user details
  • ✨ NEW wp_get_current_user - Get authenticated user info

šŸ·ļø Taxonomy - FULL CRUD

  • āœ… wp_get_categories - List categories
  • āœ… wp_get_tags - List tags
  • ✨ NEW wp_create_category - Create new categories
  • ✨ NEW wp_create_tag - Create new tags
  • ✨ NEW wp_update_category - Update category details
  • ✨ NEW wp_delete_category - Delete categories

āš™ļø Site Information

  • ✨ NEW wp_get_site_info - Get site settings and configuration
  • ✨ NEW wp_get_post_types - List all available post types

šŸ“Š Complete Endpoint Coverage

Posts (5 endpoints)

  • wp_get_posts - List posts with filters
  • wp_get_post - Get single post
  • wp_create_post - Create new post
  • wp_update_post - Update existing post
  • wp_delete_post - Delete post

Pages (5 endpoints)

  • wp_get_pages - List pages
  • wp_get_page - Get single page
  • wp_create_page - Create new page (supports excerpt)
  • wp_update_page - Update existing page (supports excerpt; pass excerpt: "" to clear it)
  • wp_delete_page - Delete page

Media (5 endpoints) ✨

  • wp_get_media - List media files
  • wp_get_media_item - Get single media item
  • wp_upload_media - Upload new media
  • wp_update_media ← NEW!
  • wp_delete_media ← NEW!

Comments (5 endpoints) ✨ ALL NEW!

  • wp_get_comments - List comments
  • wp_get_comment - Get single comment
  • wp_create_comment - Create new comment
  • wp_update_comment - Update comment
  • wp_delete_comment - Delete comment

Users (3 endpoints) ✨ ALL NEW!

  • wp_get_users - List all users
  • wp_get_user - Get user details
  • wp_get_current_user - Get current user

Custom Post Types (3 endpoints)

  • wp_get_custom_posts - List custom posts
  • wp_get_custom_post - Get single custom post
  • wp_create_custom_post - Create custom post

Taxonomy (6 endpoints) ✨ 4 NEW!

  • wp_get_categories - List categories
  • wp_get_tags - List tags
  • wp_create_category ← NEW!
  • wp_create_tag ← NEW!
  • wp_update_category ← NEW!
  • wp_delete_category ← NEW!

Site Info (3 endpoints) ✨ ALL NEW!

  • wp_get_site_info - Site settings including special page IDs
  • wp_get_special_pages - Get homepage, blog page, privacy policy page IDs
  • wp_get_post_types - Available post types

Plugins (8 endpoints) ✨ ALL NEW in v2.3!

  • wp_list_plugins - List all plugins with status/search filters
  • wp_install_plugin - Install from WordPress.org by slug
  • wp_install_plugin_zip - Install from ZIP URL
  • wp_activate_plugin - Activate an installed plugin
  • wp_deactivate_plugin - Deactivate an active plugin
  • wp_delete_plugin - Delete a plugin (must be deactivated)
  • wp_update_plugin - Update to latest version
  • wp_bootstrap_plugin_installer - Setup ZIP installer API

File API & Code Snippets ✨ v2.7

  • wp_bootstrap_elementor_writer - Install the privileged Elementor write route as an active Code Snippet (no mu-plugin, no file write) — recommended
  • wp_create_file - Write a file to allowed dirs (mu-plugins, uploads) via the Agency OS File API
  • wp_bootstrap_file_api - Auto-install/upgrade the Agency OS mu-plugin (File API + privileged Elementor write route)
  • wp_check_file_api - Report whether the File API and Elementor write route are installed
  • wp_list_snippets - List Code Snippets (id, name, scope, active state, tags)
  • wp_get_snippet - Get a single snippet with its full code body
  • wp_create_snippet - Create a snippet (PHP code without the <?php tag)
  • wp_update_snippet - Update an existing snippet
  • wp_activate_snippet / wp_deactivate_snippet - Toggle a snippet on/off
  • wp_delete_snippet - Permanently delete a snippet

WooCommerce Products (5 endpoints) ✨ NEW in v2.5!

  • wc_list_products - List products with filters (category, status, SKU, on_sale)
  • wc_get_product - Get single product with full details
  • wc_create_product - Create new product with images, pricing, stock
  • wc_update_product - Update product details, images, pricing
  • wc_delete_product - Delete or trash a product

WooCommerce Categories (4 endpoints) ✨ NEW in v2.5!

  • wc_list_categories - List product categories
  • wc_create_category - Create new category with image
  • wc_update_category - Update category details
  • wc_delete_category - Delete a category

WooCommerce Variations (4 endpoints) ✨ NEW in v2.5!

  • wc_list_variations - List variations for a variable product
  • wc_create_variation - Create new variation with attributes
  • wc_update_variation - Update variation price, stock, image
  • wc_delete_variation - Delete a variation

WooCommerce Orders (3 endpoints) ✨ NEW in v2.5!

  • wc_list_orders - List orders with filters (status, customer, date)
  • wc_get_order - Get full order details
  • wc_update_order - Update order status

Elementor Pages (8 endpoints) ✨ v2.6

  • wp_elementor_get_page - Read a page's _elementor_data (parsed sections + page settings)
  • wp_elementor_get_page_by_slug - Same, by slug instead of id
  • wp_elementor_create_page - Create a page with Elementor data in one call
  • wp_elementor_update_page - Update a page's Elementor data
  • wp_elementor_delete_page - Delete an Elementor page
  • wp_elementor_download_page - Export Elementor data to disk
  • wp_elementor_update_from_file - Apply a saved Elementor JSON file to a page
  • wp_elementor_list_revisions - List WP revisions for a page (read-only — see note below)

Elementor Templates & Block Library (4 endpoints) ✨ v2.6

  • wp_elementor_list_templates - List Elementor library templates on the site
  • wp_elementor_get_template - Read a single Elementor template
  • wp_elementor_list_blocks - List curated, vetted block presets (hero, features, CTA, testimonial, etc.) the agent can pick from instead of building Elementor JSON from scratch
  • wp_elementor_get_block - Get the JSON for one curated block (drop-in for wp_elementor_insert_block)
  • wp_elementor_insert_block - Insert a curated block at a given position in a target page
  • wp_elementor_guidelines - Return the site's design tokens (typography scale, color palette, spacing rules) — feed this to the agent before it composes a page
  • wp_elementor_capabilities - Discover what's available BEFORE building: Elementor version, Pro (active + version), active kit id, container-experiment heuristic, and detected popular addon packs (UAE, Essential Addons, JetEngine, Happy Addons, etc.). Lets the agent decide whether to use Pro widgets (form, price-table, slides, popup) or fall back.
  • wp_set_static_front_page - Set the WordPress homepage to a specific page (Reading Settings → "A static page"). Pass page_id:0 to revert to "Your latest posts". Optionally set the blog listing page too. Returns previous_state for rollback.

Elementor Surgical Primitives (5 endpoints) ✨ NEW

Address Elementor elements by id without touching the rest of the page. Foundational for maintenance work (e.g. "update the CTA button text on every page that has one"). All mutating tools return previous_state for rollback.

  • wp_elementor_get_page_structure - Compact navigable tree summary of a page (element ids + types + short text snippets, no heavy settings)
  • wp_elementor_get_widget_settings - Full settings of one element by id
  • wp_elementor_update_widget - Shallow-merge patch on one element's settings (or full replace via replace_settings:true)
  • wp_elementor_duplicate_widget - Clone an element within the same page (ids regenerated). For card-grid patterns: build one, duplicate N, then patch each
  • wp_elementor_insert_widget - Insert a new widget at a precise location ({ after_id } / { before_id } / { parent_id, position } / "start" / "end" / integer)

Control Plane (4 endpoints) ✨ NEW in v2.6!

Stateless, pure-REST, no plugin install on the target site.

  • wp_publish_draft_over - Promote a draft on top of a live page (preserves target id/URL/status). Copies content, Elementor data, page settings, featured media, SEO meta, taxonomies. Verifies the write, then deletes the draft. Returns previous_state for rollback.
  • wp_replace_text - Bulk find/replace across post_content + Elementor widget text. Supports regex, case-insensitive, dry_run. Skips __dynamic__ fields. Returns previous_state.
  • wp_get_page_state - Read a page and return a normalized restore-able state object (title, content, excerpt, template, menu_order, featured_media, captured meta).
  • wp_restore_page_state - Write a state object back onto a page. Pair with previous_state from a destructive op, or with the output of wp_get_page_state.

āš ļø Rollback note: WordPress's REST revision endpoint does not return the meta field, so _elementor_data is not preserved in REST-visible revisions — verified on multiple live sites. Do NOT rely on wp_elementor_list_revisions for Elementor rollback. Use previous_state / wp_restore_page_state instead.


šŸš€ Usage Examples

Bulk Text Replace with Rollback (Control Plane)

Replace text across a page's Elementor widgets and keep a rollback handle:

// 1. Preview first — see what would change without writing
{ "tool": "wp_replace_text",
  "args": { "post_id": 2719, "find": "HELLO_AAA", "replace": "GOODBYE_AAA", "dry_run": true } }
// → { applied: false, matches: 1, would_change: { post_content: false, elementor_data: true } }

// 2. Apply for real — receive previous_state
{ "tool": "wp_replace_text",
  "args": { "post_id": 2719, "find": "HELLO_AAA", "replace": "GOODBYE_AAA" } }
// → { applied: true, verified: true, matches: 1,
//     previous_state: { post_id, title, content, excerpt, template, meta: { _elementor_data: "..." } },
//     elementor_bytes: 326 }

// 3. (Optional) If something's wrong, hand previous_state back:
{ "tool": "wp_restore_page_state",
  "args": { "post_id": 2719, "state": /* the previous_state from step 2 */ } }
// → { restored: true, verified: true, elementor_bytes: 324 }

The caller (agent or workflow) decides whether to keep previous_state in memory, persist it to n8n state, or store it in its own DB. The MCP server keeps none of it.

Promote a Redesign Draft Over the Live Page

Build a redesign as a draft, verify it visually, then promote it on top of the live page in a single call — preserving the live URL, page id, and post status:

{ "tool": "wp_publish_draft_over",
  "args": {
    "draft_id": 9123,            // the redesign you've been building
    "target_id": 2715,           // the live page to overwrite
    "copy_seo": true,            // copy Yoast + RankMath meta from the draft
    "copy_featured_image": true,
    "copy_taxonomies": false     // opt-in: also sync categories/tags/custom tax
  } }
// → { published: true, deleted_draft_id: 9123, target_id: 2715,
//     verified: true, elementor_bytes: 184273,
//     copied: { featured_image: true, template: true, menu_order: true,
//               excerpt: true, meta_keys: [...], taxonomies: [] },
//     previous_state: { ... } }

previous_state is the live page exactly as it was before the publish — pass it to wp_restore_page_state if the redesign needs to be rolled back.

Compose a Page from Curated Blocks

Instead of asking the agent to hand-author Elementor JSON, hand it the design system and a block library:

// 1. Get the site's design tokens (colors, typography, spacing)
{ "tool": "wp_elementor_guidelines", "args": {} }

// 2. List available block presets (hero, features, testimonial, CTA, etc.)
{ "tool": "wp_elementor_list_blocks", "args": {} }

// 3. Create the page shell, then insert blocks one by one
{ "tool": "wp_elementor_create_page", "args": { "title": "New Landing", "status": "draft" } }
{ "tool": "wp_elementor_insert_block",
  "args": { "page_id": 9123, "block_id": "hero_split", "position": 0 } }
{ "tool": "wp_elementor_insert_block",
  "args": { "page_id": 9123, "block_id": "feature_grid_3col", "position": 1 } }

Update Media Metadata

{
  "tool": "wp_update_media",
  "args": {
    "id": 123,
    "title": "Beautiful Sunset",
    "alt_text": "A stunning sunset over the ocean",
    "caption": "Taken at Santa Monica Beach",
    "description": "High-resolution sunset photograph"
  }
}

Create and Manage Comments

// Create comment
{
  "tool": "wp_create_comment",
  "args": {
    "post": 42,
    "content": "Great article!",
    "author_name": "John Doe",
    "author_email": "john@example.com"
  }
}

// Update comment status
{
  "tool": "wp_update_comment",
  "args": {
    "id": 15,
    "status": "approve"
  }
}

Manage Categories

// Create category
{
  "tool": "wp_create_category",
  "args": {
    "name": "Technology",
    "description": "Tech-related articles",
    "slug": "tech"
  }
}

// Update category
{
  "tool": "wp_update_category",
  "args": {
    "id": 5,
    "name": "Tech & Innovation",
    "parent": 2
  }
}

Get Site Information

{
  "tool": "wp_get_site_info",
  "args": {}
}
// Returns: title, description, url, timezone, language,
// show_on_front, page_on_front, page_for_posts, etc.

Plugin Management (NEW in v2.3!)

List Installed Plugins

// List all plugins
{
  "tool": "wp_list_plugins",
  "args": {}
}

// List only active plugins
{
  "tool": "wp_list_plugins",
  "args": { "status": "active" }
}

// Search for plugins
{
  "tool": "wp_list_plugins",
  "args": { "search": "seo" }
}

Install Plugin from WordPress.org

{
  "tool": "wp_install_plugin",
  "args": {
    "slug": "contact-form-7",
    "activate": true
  }
}

Install Plugin from ZIP URL

// First, setup the installer API (one-time)
{
  "tool": "wp_bootstrap_plugin_installer",
  "args": {}
}

// Then install from any ZIP URL
{
  "tool": "wp_install_plugin_zip",
  "args": {
    "url": "https://github.com/user/plugin/releases/download/v1.0/plugin.zip",
    "activate": true
  }
}

Activate/Deactivate Plugins

// Activate (supports short name or full path)
{
  "tool": "wp_activate_plugin",
  "args": { "plugin": "akismet" }
}

// Or with full path
{
  "tool": "wp_activate_plugin",
  "args": { "plugin": "akismet/akismet.php" }
}

// Deactivate
{
  "tool": "wp_deactivate_plugin",
  "args": { "plugin": "hello-dolly" }
}

Update Plugin

{
  "tool": "wp_update_plugin",
  "args": { "plugin": "akismet" }
}

Delete Plugin

// Must deactivate first!
{
  "tool": "wp_deactivate_plugin",
  "args": { "plugin": "hello-dolly" }
}

{
  "tool": "wp_delete_plugin",
  "args": { "plugin": "hello-dolly" }
}

WooCommerce (NEW in v2.5!)

Full WooCommerce support for managing products, categories, variations, and orders.

āš™ļø WooCommerce Setup (Required)

WooCommerce REST API requires separate authentication from WordPress. You need to generate API keys:

  1. Go to WooCommerce → Settings → Advanced → REST API
  2. Click "Add key"
  3. Enter description: MCP Server
  4. Set Permissions: Read/Write
  5. Click "Generate API key"
  6. Copy the Consumer Key (starts with ck_) and Consumer Secret (starts with cs_)

āš ļø Important: The secret is shown only once! Save it immediately.

Add to your .env file:

# Default client
WC_CONSUMER_KEY=ck_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
WC_CONSUMER_SECRET=cs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Or for specific clients (e.g., client9)
CLIENT9_WC_CONSUMER_KEY=ck_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
CLIENT9_WC_CONSUMER_SECRET=cs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

List Products

{
  "tool": "wc_list_products",
  "args": {
    "per_page": 20,
    "status": "publish",
    "on_sale": true
  }
}

Create Product

{
  "tool": "wc_create_product",
  "args": {
    "name": "Premium T-Shirt",
    "type": "simple",
    "regular_price": "29.99",
    "sale_price": "24.99",
    "description": "High-quality cotton t-shirt",
    "short_description": "Premium cotton tee",
    "sku": "TSHIRT-001",
    "manage_stock": true,
    "stock_quantity": 100,
    "categories": [{"id": 15}],
    "images": [
      {"src": "https://example.com/image.jpg"}
    ]
  }
}

Update Product Stock

{
  "tool": "wc_update_product",
  "args": {
    "id": 123,
    "stock_quantity": 50,
    "stock_status": "instock"
  }
}

Update Product Images

{
  "tool": "wc_update_product",
  "args": {
    "id": 123,
    "images": [
      {"src": "https://example.com/new-image.jpg"},
      {"id": 456}  // Existing media ID
    ]
  }
}

Create Variable Product with Variations

// Step 1: Create variable product with attributes
{
  "tool": "wc_create_product",
  "args": {
    "name": "Variable T-Shirt",
    "type": "variable",
    "attributes": [
      {
        "name": "Color",
        "options": ["Red", "Blue", "Green"],
        "variation": true
      },
      {
        "name": "Size",
        "options": ["S", "M", "L"],
        "variation": true
      }
    ]
  }
}

// Step 2: Create variation
{
  "tool": "wc_create_variation",
  "args": {
    "product_id": 123,
    "regular_price": "29.99",
    "attributes": [
      {"name": "Color", "option": "Red"},
      {"name": "Size", "option": "M"}
    ],
    "stock_quantity": 25
  }
}

List Orders by Status

{
  "tool": "wc_list_orders",
  "args": {
    "status": "processing",
    "per_page": 50
  }
}

Update Order Status

{
  "tool": "wc_update_order",
  "args": {
    "id": 789,
    "status": "completed"
  }
}

Get Special Pages (Homepage, Blog, Privacy Policy)

{
  "tool": "wp_get_special_pages",
  "args": {}
}
// Returns full details of special pages:
// {
//   "homepage": { id: 5, title: "Home", slug: "home", url: "...", status: "publish", type: "page" },
//   "blog_page": { id: 8, title: "Blog", slug: "blog", url: "...", status: "publish", type: "page" },
//   "privacy_policy": { id: 3, title: "Privacy Policy", slug: "privacy-policy", url: "...", status: "publish", type: "page" },
//   "_settings": { show_on_front: "page", posts_per_page: 10, default_category: 1 }
// }

šŸ“ˆ API Coverage Statistics

Content Type Before v2.0 After v2.5 Coverage
Posts 5 endpoints 5 endpoints 100% āœ…
Pages 5 endpoints 5 endpoints 100% āœ…
Media 3 endpoints 5 endpoints 100% āœ…
Comments 0 endpoints 5 endpoints 100% ✨
Users 0 endpoints 3 endpoints 75% ✨
Taxonomy 2 endpoints 6 endpoints 100% ✨
Custom Posts 3 endpoints 3 endpoints 100% āœ…
Site Info 0 endpoints 3 endpoints 100% ✨
Plugins 0 endpoints 8 endpoints ✨
Taxonomy (tags) 2 endpoints 4 endpoints 100% ✨
WooCommerce 0 endpoints 16 endpoints NEW ✨
Elementor 0 endpoints 14 endpoints NEW ✨ v2.6
Control Plane 0 endpoints 4 endpoints NEW ✨ v2.6

🌐 HTTP API Usage (Enhanced in v2.2!)

Available Endpoints

The HTTP API provides 4 powerful endpoints:

Endpoint Description Parameters Recommended
GET /api/site-data Get everything in one call - site info + special pages client (optional) ⭐ YES
GET /api/find Universal search - Find ANY content by ID, slug, URL, or text id, slug, url, search, client ⭐ YES
GET /api/special-pages Get special pages only (homepage, blog, privacy) client (optional)
GET /api/site-info Get site settings only client (optional)

Quick Start

⭐ Recommended: Get Everything in One Call

# Get site info + special pages in a single request
curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/site-data"

Response includes:

  • Complete site settings (title, url, timezone, reading settings, etc.)
  • All special pages (homepage, blog page, privacy policy)
  • Returned in one optimized call

1. Find Posts/Pages

# Basic search by slug
curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/find?slug=about-us"

2. Get Special Pages Only

# Get homepage, blog page, and privacy policy page IDs
curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/special-pages"

3. Get Site Information Only

# Get site settings including special page IDs
curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/site-info"

Multi-Client Requests

# Query specific WordPress site
curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/site-data?client=client1"

Search Parameters

You can search using any of these parameters - the API will find your content regardless of type:

Parameter Description Example Finds
id Find by WordPress ID (direct lookup) ?id=42 Posts, Pages
slug Find by WordPress slug ?slug=about-us Posts, Pages, Special Pages
url Find by full URL (slug extracted) ?url=https://site.com/about-us Posts, Pages, Special Pages
search Text search in title/content ?search=contact Posts, Pages
client Specify which WordPress site &client=client1 Multi-site selection

Special Pages Detection: The API automatically detects special WordPress pages:

  • Homepage (by slug match or keywords: home, homepage)
  • Blog page (by slug match or keyword: blog)
  • Privacy policy (by slug match or keywords: privacy, privacy-policy)

Response Format

Success Response (Found - Regular Content)

{
  "found": true,
  "type": "page",
  "id": 42,
  "title": "About Us",
  "slug": "about-us",
  "content": "<p>Welcome to our site...</p>",
  "url": "https://yoursite.com/about-us",
  "date": "2024-01-15T10:30:00",
  "status": "publish",
  "_meta": {
    "client": "client1",
    "autoDetected": true
  }
}

Success Response (Found - Special Page)

{
  "found": true,
  "type": "page",
  "specialType": "homepage",
  "id": 5,
  "title": "Home",
  "slug": "home",
  "content": "<p>Welcome to our homepage...</p>",
  "url": "https://yoursite.com/",
  "date": "2024-01-15T10:30:00",
  "status": "publish",
  "isSpecialPage": true,
  "_meta": {
    "client": "default",
    "autoDetected": false
  }
}

Special page types:

  • "homepage" - Static homepage
  • "blog_page" - Blog listing page
  • "privacy_policy" - Privacy policy page

Note: _meta.autoDetected will be true if the client was detected from the URL domain, or false if manually specified via &client= parameter.

Not Found Response

{
  "found": false,
  "message": "Content not found in posts or pages",
  "searchParams": {
    "slug": "non-existent-page"
  }
}

Error Response (Missing API Key)

{
  "error": "Unauthorized: Invalid API Key"
}

Real-World Examples

Example 1: Find by ID (fastest - direct lookup)

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?id=42"
# Returns: Post or Page with ID 42 with full details

Example 2: Find homepage (special page detection)

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?slug=home"
# Returns: Homepage with specialType: "homepage", isSpecialPage: true

Example 3: Find blog page

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?slug=blog"
# Returns: Blog page with specialType: "blog_page", isSpecialPage: true

Example 4: Find privacy policy

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?slug=privacy-policy"
# Returns: Privacy policy page with specialType: "privacy_policy", isSpecialPage: true

Example 5: Find any page by slug

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?slug=about-us"
# Returns: Regular page or post matching the slug

Example 6: Find content by full URL (with auto-detection!)

# The system automatically detects the client from the domain
curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?url=https://mysite.com/blog/my-post"

# No need to specify &client=... - it's detected automatically!
# If mysite.com matches CLIENT1_WP_API_URL, it will use client1 credentials

Example 7: Text search across all content

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?search=contact%20us"
# Returns: First match in posts or pages containing "contact us"

Example 8: Query specific client

curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/find?slug=about&client=client2"

šŸ†• New Endpoints (v2.2)

⭐ GET /api/site-data (RECOMMENDED)

Get everything you need about your WordPress site in a single optimized request.

Request:

curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/site-data"

Response:

{
  "site": {
    "title": "My WordPress Site",
    "description": "Just another WordPress site",
    "url": "https://yoursite.com",
    "timezone": "America/New_York",
    "language": "en-US",
    "date_format": "F j, Y",
    "time_format": "g:i a",
    "show_on_front": "page",
    "page_on_front": 5,
    "page_for_posts": 8,
    "posts_per_page": 10,
    "default_category": 1,
    "default_post_format": "0"
  },
  "pages": {
    "homepage": {
      "id": 5,
      "title": "Home",
      "slug": "home",
      "url": "https://yoursite.com/",
      "status": "publish",
      "type": "page"
    },
    "blog_page": {
      "id": 8,
      "title": "Blog",
      "slug": "blog",
      "url": "https://yoursite.com/blog",
      "status": "publish",
      "type": "page"
    },
    "privacy_policy": {
      "id": 3,
      "title": "Privacy Policy",
      "slug": "privacy-policy",
      "url": "https://yoursite.com/privacy-policy",
      "status": "publish",
      "type": "page"
    },
    "_settings": {
      "show_on_front": "page",
      "posts_per_page": 10,
      "default_category": 1
    }
  },
  "_meta": {
    "client": "default",
    "endpoint": "/api/site-data",
    "timestamp": "2024-01-15T10:30:00.000Z"
  }
}

Why use this endpoint?

  • āœ… One request instead of two - Get site info + special pages together
  • āœ… Optimized performance - Parallel fetching under the hood
  • āœ… Complete data - Everything you need to build navigation, footers, site maps
  • āœ… Timestamp included - Track when data was fetched
  • āœ… Multi-client support - Add ?client=client1 for different sites

Use Cases:

  • Build complete site navigation in one API call
  • Initialize headless CMS with all site data
  • Create admin dashboards with full site configuration
  • Sync multiple WordPress sites efficiently

GET /api/special-pages

Get special WordPress pages only (if you don't need full site info).

Request:

curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/special-pages"

Response:

{
  "homepage": {
    "id": 5,
    "title": "Home",
    "slug": "home",
    "url": "https://yoursite.com/",
    "status": "publish",
    "type": "page"
  },
  "blog_page": {
    "id": 8,
    "title": "Blog",
    "slug": "blog",
    "url": "https://yoursite.com/blog",
    "status": "publish",
    "type": "page"
  },
  "privacy_policy": {
    "id": 3,
    "title": "Privacy Policy",
    "slug": "privacy-policy",
    "url": "https://yoursite.com/privacy-policy",
    "status": "publish",
    "type": "page"
  },
  "_settings": {
    "show_on_front": "page",
    "posts_per_page": 10,
    "default_category": 1
  },
  "_meta": {
    "client": "default",
    "endpoint": "/api/special-pages"
  }
}

Use Cases:

  • Get homepage ID for navigation menus
  • Find blog page for archive links
  • Access privacy policy page for footer links
  • Build dynamic site maps

GET /api/site-info

Get comprehensive site settings and configuration.

Request:

curl -H "X-API-Key: your-secret-key" \
     "http://localhost:8080/api/site-info"

Response:

{
  "title": "My WordPress Site",
  "description": "Just another WordPress site",
  "url": "https://yoursite.com",
  "timezone": "America/New_York",
  "language": "en-US",
  "date_format": "F j, Y",
  "time_format": "g:i a",
  "show_on_front": "page",
  "page_on_front": 5,
  "page_for_posts": 8,
  "posts_per_page": 10,
  "default_category": 1,
  "default_post_format": "0",
  "_meta": {
    "client": "default",
    "endpoint": "/api/site-info"
  }
}

Key Fields:

  • show_on_front: "page" (static homepage) or "posts" (blog listing)
  • page_on_front: Homepage page ID (0 if show_on_front is "posts")
  • page_for_posts: Blog listing page ID
  • posts_per_page: Number of posts per page
  • default_category: Default category ID for new posts

Use Cases:

  • Detect homepage type (static vs. blog)
  • Get pagination settings
  • Build site configuration dashboards
  • Sync site settings across platforms

Multi-Client Support

All HTTP endpoints support the ?client= parameter:

# Get special pages from client1
curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/special-pages?client=client1"

# Get site info from client2
curl -H "X-API-Key: abc123" \
     "http://localhost:8080/api/site-info?client=client2"

šŸ¤– Automatic Client Detection

The killer feature: When you provide a full URL, the system automatically detects which WordPress site to query!

How Auto-Detection Works:

  1. You send a request with a full URL: ?url=https://site1.com/about
  2. System extracts the domain: site1.com
  3. Compares domain against all configured clients:
    • WP_API_URL (default)
    • CLIENT1_WP_API_URL
    • CLIENT2_WP_API_URL
    • etc.
  4. Finds a match and uses those credentials automatically!

Example Configuration:

# .env file
WP_API_URL=https://mainsite.com
CLIENT1_WP_API_URL=https://blog.example.com
CLIENT2_WP_API_URL=https://shop.example.com

Now you can query any site without specifying the client:

# Automatically uses default credentials
GET /api/find?url=https://mainsite.com/privacy

# Automatically uses CLIENT1 credentials
GET /api/find?url=https://blog.example.com/my-post

# Automatically uses CLIENT2 credentials
GET /api/find?url=https://shop.example.com/product-page

No &client= parameter needed! ✨

Manual Override

You can still manually specify a client if needed:

# Force specific client (ignores auto-detection)
GET /api/find?url=https://anywhere.com/page&client=client3

How Search Works

  1. Auto-Detects Client (if URL provided and no manual client)
  2. Searches Posts First - Checks all published posts for matching slug
  3. Then Searches Pages - If not found in posts, checks pages
  4. Returns First Match - Returns immediately when content is found
  5. Type Indicator - Response includes "type": "post" or "type": "page"
  6. Meta Information - Response includes _meta.autoDetected: true/false

Security

The HTTP API uses a shared API key for authentication:

  1. Set API_KEY in your .env file
  2. Send the key in request headers as X-API-Key or Authorization: Bearer <key>
  3. Without API key: requests will be rejected with 401 Unauthorized
# Generate a secure API key
openssl rand -hex 32

Add to .env:

API_KEY=your-generated-key-here

šŸ”§ Installation

No changes to installation process - same as before:

# Clone the repo
git clone https://github.com/Davidi18/wordpress-mcp.git
cd wordpress-mcp

# Set up environment
cp .env.example .env
# Edit .env with your WordPress credentials

# Run
npm start

🌟 Why This Update Matters

  1. Complete Content Management - Full CRUD operations on all WordPress content types
  2. Media Workflow - Now you can update media metadata without re-uploading
  3. Comment Moderation - Manage comments programmatically
  4. User Management - Query and manage WordPress users
  5. Taxonomy Control - Create and organize categories/tags dynamically
  6. Site Intelligence - Get site configuration and post type information

šŸŽÆ Perfect For

  • šŸ¤– AI-powered content management systems
  • šŸ“± Headless WordPress implementations
  • šŸ”„ Content synchronization tools
  • šŸ“Š WordPress data analytics
  • šŸ› ļø Automation workflows
  • šŸ”Œ Third-party integrations

šŸ“ Changelog

v2.6.0 (Latest)

Added

  • šŸŽÆ Elementor Control Plane — pure-REST, stateless, no plugin install on target sites
    • wp_publish_draft_over — promote a draft over a live page (preserves id/URL/status); copies content, _elementor_data, page settings, featured image, Yoast + RankMath SEO, excerpt, template, menu_order, optional taxonomies; verifies the write byte-for-byte; deletes draft on success; returns previous_state for rollback
    • wp_replace_text — bulk find/replace across post_content and every Elementor widget text field (heading, button, editor HTML, captions, tabs, testimonials, etc.); supports regex, case-insensitive, and dry_run; skips __dynamic__ fields; returns previous_state
    • wp_get_page_state — capture a normalized restore-able state object
    • wp_restore_page_state — write a state object back onto a page; verifies _elementor_data byte-length
  • 🧱 Curated Elementor Block Library
    • wp_elementor_list_blocks / wp_elementor_get_block / wp_elementor_insert_block — agents pick from vetted block presets instead of authoring Elementor JSON from scratch
  • šŸ“ wp_elementor_guidelines — return the site's design tokens (typography, colors, spacing) so generated content stays on-brand
  • šŸ“„ Elementor Page Ops
    • wp_elementor_get_page / wp_elementor_get_page_by_slug / wp_elementor_create_page / wp_elementor_update_page / wp_elementor_delete_page / wp_elementor_download_page / wp_elementor_update_from_file
    • wp_elementor_list_templates / wp_elementor_get_template
    • wp_elementor_list_revisions (read-only — see note)
  • šŸ” Transport hardening — bearer auth on the HTTP API, request body size cap, secret redaction in logs, fetch timeout + retry with exponential backoff

Added (Taxonomy symmetry)

  • šŸ·ļø wp_update_tag and wp_delete_tag — close the gap with categories (which had full CRUD)

Removed

  • āŒ wp_revisions_restore — WP REST does not expose meta (and therefore _elementor_data) in revision responses; rollback via revisions is impossible without a server-side PHP plugin. Verified on multiple live sites. Replaced by the stateless previous_state + wp_restore_page_state flow.
  • āŒ wp_get_schema, wp_set_schema, wp_list_schemas, wp_preview_schema — required the custom strudel-schema plugin to be installed on every target site. Out of scope for a WP-core + Elementor focused server. Sites that need JSON-LD generation should run that flow inside their own infra.
  • āŒ wp_get_seo_robots, wp_set_seo_robots — same reason: piggybacked on the strudel-schema plugin. Robots/noindex flags can still be written via the existing _yoast_wpseo_meta-robots-noindex / rank_math_robots postmeta keys through wp_update_page if needed.

Improved

  • Centralized Elementor + SEO meta-key lists in wp-meta-keys.js (previously inlined per case handler)
  • Canonical state extractor (extractPageState) and payload builder (statePayload) shared by all four control-plane tools

v2.5.0

Added

  • šŸ›’ WooCommerce Support - Full product management via MCP
    • wc_list_products - List products with filters (category, status, SKU, on_sale, featured)
    • wc_get_product - Get single product with all details
    • wc_create_product - Create products with images, pricing, stock, attributes
    • wc_update_product - Update any product field including images
    • wc_delete_product - Delete or trash products
  • šŸ“‚ Product Categories
    • wc_list_categories - List product categories
    • wc_create_category - Create category with image
    • wc_update_category - Update category details
    • wc_delete_category - Delete categories
  • šŸ”€ Product Variations (for variable products)
    • wc_list_variations - List all variations for a product
    • wc_create_variation - Create variation with attributes
    • wc_update_variation - Update variation price, stock, image
    • wc_delete_variation - Delete variations
  • šŸ“¦ Orders Management
    • wc_list_orders - List orders with status/date filters
    • wc_get_order - Get full order details
    • wc_update_order - Update order status

Improved

  • Total MCP tools increased from 46 to 62 endpoints (244% increase from v1.0!)

v2.4.0

Added

  • šŸ” SEO Robots Control - Manage search engine indexing settings for posts and pages
    • wp_get_seo_robots - Get current robots settings (noindex, nofollow, etc.)
    • wp_set_seo_robots - Set robots directives for any post/page
    • Automatic SEO plugin detection (Yoast SEO or Rank Math)
    • Support for noindex, nofollow (both plugins)
    • Support for noarchive, nosnippet (Rank Math only)

Improved

  • Total MCP tools increased from 44 to 46 endpoints
  • Strudel Schema plugin now includes SEO robots REST endpoints

v2.3.0

Added

  • šŸ”Œ Plugin Management - Complete plugin lifecycle management via MCP
    • wp_list_plugins - List all plugins with status and search filters
    • wp_install_plugin - Install plugins from WordPress.org by slug
    • wp_install_plugin_zip - Install plugins from any ZIP URL
    • wp_activate_plugin - Activate installed plugins
    • wp_deactivate_plugin - Deactivate active plugins
    • wp_delete_plugin - Delete plugins (must be deactivated first)
    • wp_update_plugin - Update plugins to latest version
    • wp_bootstrap_plugin_installer - Setup custom REST endpoint for ZIP installation
  • šŸ“¦ ZIP Installation Support - Install plugins from GitHub releases, private repos, or any URL
  • šŸ”§ Smart Plugin Resolution - Use short names (akismet) or full paths (akismet/akismet.php)

Improved

  • Total MCP tools increased from 36 to 44 endpoints (144% increase from v1.0!)
  • Better error messages for plugin operations
  • Automatic plugin path resolution

v2.2.0

Added

  • ⭐ Unified HTTP Endpoint - New GET /api/site-data endpoint (RECOMMENDED)
    • Get site info + special pages in one optimized call
    • Parallel fetching for maximum performance
    • Includes timestamp for cache management
  • šŸ” Universal Search - Enhanced /api/find endpoint
    • Search by ID (direct lookup - fastest)
    • Search by slug (finds posts, pages, special pages)
    • Search by URL (auto-detects client from domain)
    • Search by text (full-text search)
    • Automatic special page detection - homepage, blog, privacy policy
    • Returns isSpecialPage and specialType for special pages
  • 🌐 HTTP API for Special Pages - New GET /api/special-pages endpoint
  • 🌐 HTTP API for Site Info - New GET /api/site-info endpoint
  • šŸ  Special Pages Retrieval - New wp_get_special_pages MCP tool
  • šŸ“„ Homepage ID Detection - Automatically get homepage page ID (static or posts)
  • šŸ“ Blog Page ID Detection - Get blog listing page ID when using static homepage
  • šŸ”’ Privacy Policy Page - Retrieve privacy policy page details
  • šŸ“Š Enhanced Site Info - wp_get_site_info now includes show_on_front, page_on_front, page_for_posts, posts_per_page, and more

Improved

  • HTTP API expanded from 1 endpoint to 4 endpoints
  • Universal search finds any content type - posts, pages, special pages
  • Reduced API calls: Get everything in one request with /api/site-data
  • More comprehensive site configuration data via HTTP
  • Better handling of special WordPress pages with automatic detection
  • Detailed page information with title, slug, URL, and status
  • Multi-client support for all HTTP endpoints
  • Total MCP tools increased to 36 (100% increase from v1.0!)

v2.1.0

Added

  • 🌐 HTTP GET API - New /api/find endpoint for direct HTTP queries
  • šŸ” Unified Search - Automatically searches both posts and pages
  • šŸ¤– Automatic Client Detection - System auto-detects which WordPress site to query from URL domain
  • šŸ” API Key Authentication - Secure HTTP endpoint with shared API key
  • šŸ¢ Multi-Client HTTP Support - Query different WordPress sites via client parameter
  • šŸ“– Flexible Search Options - Find by slug, URL, or text search
  • šŸ“Š Response Metadata - Includes _meta object with client info and auto-detection status
  • šŸ“š Comprehensive Documentation - Full HTTP API usage examples

Improved

  • Updated server version to 2.1.0
  • Enhanced .env.example with API key configuration
  • Better multi-client configuration documentation
  • Improved startup logging with emoji indicators
  • Smart fallback: manual client parameter overrides auto-detection

v2.0.0

Added

  • Media update and delete endpoints
  • Complete comments CRUD system
  • User management endpoints
  • Category and tag creation/update/delete
  • Site information endpoints
  • Enhanced error handling
  • Better response formatting

Improved

  • Updated server version to 2.0.0
  • Enhanced tool descriptions
  • More detailed input schemas
  • Better TypeScript compatibility

šŸ¤ Contributing

Found a bug or want to add more endpoints? PRs are welcome!

šŸ“„ License

MIT License - see LICENSE file for details


šŸ™ Credits

Enhanced by Claude & n8n-MCP tools integration Original by @Davidi18

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured