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.
README
WordPress MCP Server v2.7 - Elementor Control Plane
š What's New in v2.7
- šļø Reliable Elementor writes ā every tool that writes
_elementor_datanow routes through a privilegedagency-os/v1/elementor-dataendpoint that does a directupdate_post_metabehind anedit_postcapability check. This sidesteps core REST's refusal to write the protected_elementor_datapostmeta (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_apiget it for free (run it again, or withforce: true, to upgrade an older install). wp_check_file_apireports whether the Elementor write route is present (elementor_write_route).
- Recommended install (no mu-plugin): run
- āļø Page excerpt support ā
wp_update_pageandwp_create_pagenow acceptexcerpt. Passingexcerpt: ""towp_update_pagecleanly 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_snippetwrap 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, anddry_runpreview. 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_databyte-length on restore. - š§± Curated block library ā
wp_elementor_list_blocks/wp_elementor_get_block/wp_elementor_insert_blocklet 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_pluginby slug - š„ Install from ZIP URL -
wp_install_plugin_zipfrom any URL - ā
Activate/Deactivate -
wp_activate_plugin,wp_deactivate_plugin - šļø Delete Plugins -
wp_delete_plugin(must be deactivated first) - š Update Plugins -
wp_update_pluginto latest version - š List Plugins -
wp_list_pluginswith status/search filters
v2.2 Features:
- ⨠Special Pages API -
wp_get_special_pagesendpoint for homepage, blog, and privacy policy pages - ⨠Enhanced Site Info -
wp_get_site_infonow 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/findendpoint 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 filterswp_get_post- Get single postwp_create_post- Create new postwp_update_post- Update existing postwp_delete_post- Delete post
Pages (5 endpoints)
wp_get_pages- List pageswp_get_page- Get single pagewp_create_page- Create new page (supportsexcerpt)wp_update_page- Update existing page (supportsexcerpt; passexcerpt: ""to clear it)wp_delete_page- Delete page
Media (5 endpoints) āØ
wp_get_media- List media fileswp_get_media_item- Get single media itemwp_upload_media- Upload new mediawp_update_mediaā NEW!wp_delete_mediaā NEW!
Comments (5 endpoints) ⨠ALL NEW!
wp_get_comments- List commentswp_get_comment- Get single commentwp_create_comment- Create new commentwp_update_comment- Update commentwp_delete_comment- Delete comment
Users (3 endpoints) ⨠ALL NEW!
wp_get_users- List all userswp_get_user- Get user detailswp_get_current_user- Get current user
Custom Post Types (3 endpoints)
wp_get_custom_posts- List custom postswp_get_custom_post- Get single custom postwp_create_custom_post- Create custom post
Taxonomy (6 endpoints) ⨠4 NEW!
wp_get_categories- List categorieswp_get_tags- List tagswp_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 IDswp_get_special_pages- Get homepage, blog page, privacy policy page IDswp_get_post_types- Available post types
Plugins (8 endpoints) ⨠ALL NEW in v2.3!
wp_list_plugins- List all plugins with status/search filterswp_install_plugin- Install from WordPress.org by slugwp_install_plugin_zip- Install from ZIP URLwp_activate_plugin- Activate an installed pluginwp_deactivate_plugin- Deactivate an active pluginwp_delete_plugin- Delete a plugin (must be deactivated)wp_update_plugin- Update to latest versionwp_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) ā recommendedwp_create_file- Write a file to allowed dirs (mu-plugins, uploads) via the Agency OS File APIwp_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 installedwp_list_snippets- List Code Snippets (id, name, scope, active state, tags)wp_get_snippet- Get a single snippet with its full code bodywp_create_snippet- Create a snippet (PHP code without the<?phptag)wp_update_snippet- Update an existing snippetwp_activate_snippet/wp_deactivate_snippet- Toggle a snippet on/offwp_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 detailswc_create_product- Create new product with images, pricing, stockwc_update_product- Update product details, images, pricingwc_delete_product- Delete or trash a product
WooCommerce Categories (4 endpoints) ⨠NEW in v2.5!
wc_list_categories- List product categorieswc_create_category- Create new category with imagewc_update_category- Update category detailswc_delete_category- Delete a category
WooCommerce Variations (4 endpoints) ⨠NEW in v2.5!
wc_list_variations- List variations for a variable productwc_create_variation- Create new variation with attributeswc_update_variation- Update variation price, stock, imagewc_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 detailswc_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 idwp_elementor_create_page- Create a page with Elementor data in one callwp_elementor_update_page- Update a page's Elementor datawp_elementor_delete_page- Delete an Elementor pagewp_elementor_download_page- Export Elementor data to diskwp_elementor_update_from_file- Apply a saved Elementor JSON file to a pagewp_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 sitewp_elementor_get_template- Read a single Elementor templatewp_elementor_list_blocks- List curated, vetted block presets (hero, features, CTA, testimonial, etc.) the agent can pick from instead of building Elementor JSON from scratchwp_elementor_get_block- Get the JSON for one curated block (drop-in forwp_elementor_insert_block)wp_elementor_insert_block- Insert a curated block at a given position in a target pagewp_elementor_guidelines- Return the site's design tokens (typography scale, color palette, spacing rules) ā feed this to the agent before it composes a pagewp_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"). Passpage_id:0to revert to "Your latest posts". Optionally set the blog listing page too. Returnsprevious_statefor 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 heavysettings)wp_elementor_get_widget_settings- Full settings of one element by idwp_elementor_update_widget- Shallow-merge patch on one element's settings (or full replace viareplace_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 eachwp_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. Returnsprevious_statefor rollback.wp_replace_text- Bulk find/replace across post_content + Elementor widget text. Supports regex, case-insensitive,dry_run. Skips__dynamic__fields. Returnsprevious_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 withprevious_statefrom a destructive op, or with the output ofwp_get_page_state.
ā ļø Rollback note: WordPress's REST revision endpoint does not return the
metafield, so_elementor_datais not preserved in REST-visible revisions ā verified on multiple live sites. Do NOT rely onwp_elementor_list_revisionsfor Elementor rollback. Useprevious_state/wp_restore_page_stateinstead.
š 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:
- Go to WooCommerce ā Settings ā Advanced ā REST API
- Click "Add key"
- Enter description:
MCP Server - Set Permissions: Read/Write
- Click "Generate API key"
- Copy the Consumer Key (starts with
ck_) and Consumer Secret (starts withcs_)
ā ļø 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=client1for 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 ifshow_on_frontis"posts")page_for_posts: Blog listing page IDposts_per_page: Number of posts per pagedefault_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:
- You send a request with a full URL:
?url=https://site1.com/about - System extracts the domain:
site1.com - Compares domain against all configured clients:
WP_API_URL(default)CLIENT1_WP_API_URLCLIENT2_WP_API_URL- etc.
- 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
- Auto-Detects Client (if URL provided and no manual client)
- Searches Posts First - Checks all published posts for matching slug
- Then Searches Pages - If not found in posts, checks pages
- Returns First Match - Returns immediately when content is found
- Type Indicator - Response includes
"type": "post"or"type": "page" - Meta Information - Response includes
_meta.autoDetected: true/false
Security
The HTTP API uses a shared API key for authentication:
- Set
API_KEYin your.envfile - Send the key in request headers as
X-API-KeyorAuthorization: Bearer <key> - 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
- Complete Content Management - Full CRUD operations on all WordPress content types
- Media Workflow - Now you can update media metadata without re-uploading
- Comment Moderation - Manage comments programmatically
- User Management - Query and manage WordPress users
- Taxonomy Control - Create and organize categories/tags dynamically
- 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; returnsprevious_statefor rollbackwp_replace_textā bulk find/replace acrosspost_contentand every Elementor widget text field (heading, button, editor HTML, captions, tabs, testimonials, etc.); supports regex, case-insensitive, anddry_run; skips__dynamic__fields; returnsprevious_statewp_get_page_stateā capture a normalized restore-able state objectwp_restore_page_stateā write a state object back onto a page; verifies_elementor_databyte-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_filewp_elementor_list_templates/wp_elementor_get_templatewp_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_tagandwp_delete_tagā close the gap with categories (which had full CRUD)
Removed
- ā
wp_revisions_restoreā WP REST does not exposemeta(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 statelessprevious_state+wp_restore_page_stateflow. - ā
wp_get_schema,wp_set_schema,wp_list_schemas,wp_preview_schemaā required the customstrudel-schemaplugin 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 thestrudel-schemaplugin. Robots/noindex flags can still be written via the existing_yoast_wpseo_meta-robots-noindex/rank_math_robotspostmeta keys throughwp_update_pageif 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 detailswc_create_product- Create products with images, pricing, stock, attributeswc_update_product- Update any product field including imageswc_delete_product- Delete or trash products
- š Product Categories
wc_list_categories- List product categorieswc_create_category- Create category with imagewc_update_category- Update category detailswc_delete_category- Delete categories
- š Product Variations (for variable products)
wc_list_variations- List all variations for a productwc_create_variation- Create variation with attributeswc_update_variation- Update variation price, stock, imagewc_delete_variation- Delete variations
- š¦ Orders Management
wc_list_orders- List orders with status/date filterswc_get_order- Get full order detailswc_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 filterswp_install_plugin- Install plugins from WordPress.org by slugwp_install_plugin_zip- Install plugins from any ZIP URLwp_activate_plugin- Activate installed pluginswp_deactivate_plugin- Deactivate active pluginswp_delete_plugin- Delete plugins (must be deactivated first)wp_update_plugin- Update plugins to latest versionwp_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-dataendpoint (RECOMMENDED)- Get site info + special pages in one optimized call
- Parallel fetching for maximum performance
- Includes timestamp for cache management
- š Universal Search - Enhanced
/api/findendpoint- 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
isSpecialPageandspecialTypefor special pages
- š HTTP API for Special Pages - New
GET /api/special-pagesendpoint - š HTTP API for Site Info - New
GET /api/site-infoendpoint - š Special Pages Retrieval - New
wp_get_special_pagesMCP 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_infonow includesshow_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/findendpoint 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
clientparameter - š Flexible Search Options - Find by slug, URL, or text search
- š Response Metadata - Includes
_metaobject with client info and auto-detection status - š Comprehensive Documentation - Full HTTP API usage examples
Improved
- Updated server version to 2.1.0
- Enhanced
.env.examplewith API key configuration - Better multi-client configuration documentation
- Improved startup logging with emoji indicators
- Smart fallback: manual
clientparameter 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
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.