WordPress MCP Server
Production-oriented Model Context Protocol server for AI agents that need to manage WordPress websites through the official WordPress REST API and REST-exposed plugin resources.
What It Provides
- MCP tools with typed input schemas for posts, pages, custom post types, media, terms, users, settings, Elementor data, menus, widgets, and guarded raw REST calls.
- MCP resources for site overview, REST route discovery, settings, content items, and Elementor layouts.
- Conservative policy gates for publishing, destructive actions, settings writes, user management, and raw REST mutations.
- WordPress authentication through Application Passwords, bearer/JWT tokens, basic auth, or no auth for read-only public testing.
- Stdio transport for local AI agents and optional Streamable HTTP transport for remote/deployed clients.
Setup
npm install
cp .env.example .env
npm run build
Configure .env:
WP_SITE_URL=https://example.com
WP_AUTH_METHOD=application_password
[email protected]
WP_APPLICATION_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
Use a WordPress user with the narrowest role that can perform the tasks you want the agent to perform. For production, use HTTPS and WordPress Application Passwords or a hardened OAuth/JWT plugin.
Connect From an MCP Client
Stdio is the default transport:
{
"mcpServers": {
"wordpress": {
"command": "node",
"args": ["C:/Users/Ahmed/Desktop/wp-mcp/dist/index.js"],
"env": {
"WP_SITE_URL": "https://example.com",
"WP_AUTH_METHOD": "application_password",
"WP_USERNAME": "[email protected]",
"WP_APPLICATION_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
}
}
}
}
For HTTP:
MCP_TRANSPORT=http MCP_HTTP_BEARER_TOKEN=replace-me npm run start:http
Then connect the client to:
http://localhost:3333/mcp
Include Authorization: Bearer replace-me when MCP_HTTP_BEARER_TOKEN is set.
Safety Policy
The server starts with write operations available but sensitive changes blocked unless explicitly enabled:
| Environment flag | Allows |
|---|---|
WP_ALLOW_PUBLISH=true |
Publishing/private/future statuses and content-changing admin resources |
WP_ALLOW_DESTRUCTIVE=true |
Permanent deletes and destructive operations |
WP_ALLOW_SETTINGS_WRITE=true |
/wp/v2/settings updates |
WP_ALLOW_USER_MANAGEMENT=true |
Creating, updating, and deleting users |
WP_ALLOW_RAW_REST=true |
Non-GET calls through wp_rest_request |
WP_REQUIRE_CONFIRMATION=true |
Requires confirmation tokens for gated actions |
Confirmation tokens:
CONFIRM_PUBLISHCONFIRM_DESTRUCTIVECONFIRM_SETTINGS_WRITECONFIRM_USER_MANAGEMENTCONFIRM_RAW_REST
This lets an AI agent inspect freely while requiring deliberate approval for high-impact actions.
Core Tools
wp_discover: Inspect REST routes, current user, post types, taxonomies, and policy.wp_get_settings,wp_update_settings: Read and update core site settings.wp_list_content,wp_get_content,wp_create_content,wp_update_content,wp_delete_content: Manage posts, pages, attachments, templates, and REST-exposed custom post types.wp_upload_media: Upload local files to the media library.wp_manage_terms: Manage categories, tags, and custom taxonomies.wp_manage_users: Manage users when policy and WordPress permissions allow it.wp_get_elementor_data,wp_update_elementor_data: Read/replace Elementor layout metadata.wp_manage_navigation: Manage REST-exposed menus, locations, and menu items.wp_manage_widgets: Manage REST-exposed widgets, sidebars, and widget types.wp_rest_request: Guarded escape hatch for plugin endpoints discovered bywp_discover.
Elementor Notes
Elementor stores layout data as JSON in WordPress post metadata. This server reads Elementor data from the REST response meta object and updates _elementor_data, _elementor_edit_mode, and optional template metadata. Your site must expose the relevant meta keys to the REST API or provide a custom secure endpoint. If your site blocks private Elementor meta through core REST responses, use wp_rest_request against a custom endpoint with a proper WordPress permission_callback.
Custom Post Types and Plugin Resources
Custom post types and taxonomies must be registered with REST support in WordPress. Discover the REST base with wp_discover, then pass that base as type or taxonomy.
For plugin-specific resources, prefer purpose-built tools. Use wp_rest_request only when a route has been discovered and the action is understood.
Development
npm run dev
npm run dev:http
npm run typecheck
npm run build
Production Hardening Checklist
- Use HTTPS for WordPress and remote MCP HTTP.
- Use a least-privilege WordPress account.
- Keep destructive and admin flags disabled unless needed.
- Keep
MCP_HTTP_BEARER_TOKENset for HTTP mode and rotate it regularly. - Put HTTP mode behind trusted infrastructure with TLS, request logging, and rate limiting.
- Review tool calls before allowing publish, settings, user, raw REST, or destructive confirmations.