Skip to main content
Glama
AhmadTheTech

WordPress MCP Server

by AhmadTheTech
README.md
# 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

```bash
npm install
cp .env.example .env
npm run build
```

Configure `.env`:

```ini
WP_SITE_URL=https://example.com
WP_AUTH_METHOD=application_password
WP_USERNAME=editor@example.com
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:

```json
{
  "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": "editor@example.com",
        "WP_APPLICATION_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
      }
    }
  }
}
```

For HTTP:

```bash
MCP_TRANSPORT=http MCP_HTTP_BEARER_TOKEN=replace-me npm run start:http
```

Then connect the client to:

```text
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_PUBLISH`
- `CONFIRM_DESTRUCTIVE`
- `CONFIRM_SETTINGS_WRITE`
- `CONFIRM_USER_MANAGEMENT`
- `CONFIRM_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 by `wp_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

```bash
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_TOKEN` set 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.