Skip to main content
Glama
pravin157

WordPress MCP Server

by pravin157
README.md
# WordPress Model Context Protocol (MCP) Server

A production-quality Model Context Protocol (MCP) server that gives AI assistants (like Claude Desktop) full control over a WordPress website via the WordPress REST API. Built in Python 3.10+ using FastMCP and HTTPX.

---

## Features (MCP Tools)

This server exposes a wide range of tools for managing WordPress resources:
1. **Posts**: List, get, create, update, and delete (trash/force) posts. Sanitizes HTML excerpts for list views to save token context.
2. **Pages**: CRUD operations on pages including hierarchy support via parent page IDs.
3. **Media Library**: Upload media via local file paths or base64 payloads (specifying filename and mime types), view attachment metadata, edit alt text/captions, and delete media.
4. **Taxonomies**: Manage Categories & Tags (list, create, update, delete, and assign to posts).
5. **Comments**: List, fetch, moderate (approve/hold/spam/trash), reply (threaded), and delete comments.
6. **Users**: List, fetch profile, create, update roles, and delete users (with optional reassignment of posts).
7. **Custom Post Types & Fields**: Dynamic custom post type detection, and generic meta-fields (ACF) updates.
8. **Site Settings**: Read and write basic site details (title, tagline, timezone, formats).
9. **Search**: Full-site unified search across posts, pages, and media.
10. **Plugins & Themes**: List installed plugins and themes (conditional on admin permissions).

---

## WordPress Side Setup

### 1. Requirements
* WordPress version 5.6+ (which natively supports Application Passwords).
* SSL enabled (HTTPS) on your site. If developing locally without HTTPS, you must configure `ALLOW_INSECURE_HTTP=true`.
* User account with appropriate capabilities:
  * **Administrator** is required for site settings, plugins, themes, and users management.
  * **Editor** or **Author** is sufficient for posts, pages, media, and comment moderation.

### 2. Generating Application Password
1. Log into your WordPress dashboard (`yoursite.com/wp-admin`).
2. Navigate to **Users** -> **Profile** (or **Users** -> **All Users** -> Edit your user).
3. Scroll down to the **Application Passwords** section.
4. Enter an application name (e.g., `Claude MCP Server`) and click **Add New Application Password**.
5. Copy the generated password (formatted like `xxxx xxxx xxxx xxxx xxxx xxxx`). **It is only displayed once.**

---

## Configuration & Run

### Environment Variables
Configure the server using a `.env` file (see `.env.example` as a template):

```bash
# Target site URL (without trailing slash)
WP_SITE_URL=https://yoursite.com

# WordPress Username
WP_USERNAME=admin

# Generated Application Password (space-separated or compressed)
WP_APP_PASSWORD=abcd 1234 efgh 5678 ijkl 9012

# Optional settings
ALLOW_INSECURE_HTTP=false   # Set to true for local http:// development
DRY_RUN=false               # Set to true to simulate writes without calling API
```

### Installation
Ensure you have Python 3.10+ installed:
```bash
pip install -r requirements.txt
```

### Running Locally
To run the server in development mode:
```bash
python src/wordpress_mcp/server.py
```
*(Communication happens over standard input/output).*

To run using FastMCP dev client:
```bash
fastmcp dev src/wordpress_mcp/server.py
```

---

## Cloud Deployment (Render & OAuth)

You can host this MCP server on **Render** as a web service to connect it remotely with custom clients like Claude's custom connectors.

### 1. Deploy on Render
1. Create a new **Web Service** on Render.
2. Connect this repository.
3. Configure the environment settings:
   * **Runtime**: `Python`
   * **Start Command**: `uvicorn wordpress_mcp.server:app --host 0.0.0.0 --port $PORT`
4. Define the Environment Variables:
   * `WP_SITE_URL`: The root URL of your public WordPress site (e.g. `https://intoaec.ai`).
   * `WP_OAUTH_AUTHORIZE_URL` (optional): Defaults to `{WP_SITE_URL}/oauth/authorize`
   * `WP_OAUTH_TOKEN_URL` (optional): Defaults to `{WP_SITE_URL}/oauth/token`
   * `ALLOW_INSECURE_HTTP`: `false`

### 2. WordPress OAuth Setup
Ensure you have an OAuth 2.0 Provider plugin installed on your WordPress site (e.g., *WP OAuth Server* or *OAuth2 Provider for WordPress*).
1. Register a new OAuth Client in your WordPress dashboard.
2. Save the generated **Client ID** and **Client Secret**.

### 3. Add Custom Connector to Claude
1. Go to Claude's Settings -> **Connectors**.
2. Click **Add custom connector**.
3. Fill in the connector options:
   * **Name**: `WordPress`
   * **Remote MCP server URL**: `https://your-render-app.onrender.com/sse`
   * **OAuth Client ID**: Enter the Client ID from WordPress.
   * **OAuth Client Secret**: Enter the Client Secret from WordPress.
   * **Individual sign-in**: Enabled (each user signs in using their WordPress credentials).
4. Click **Add**. Claude will request the well-known OAuth configuration from your server, prompt you to log in, and establish a secure connection using OAuth Bearer tokens.

---

## Registering with MCP Clients

To use this server with Claude Desktop, add it to your configuration file:
* **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
* **macOS/Linux**: `~/Library/Application Support/Claude/claude_desktop_config.json`

### Option 1: Direct Python Call (Recommended for active workspace)
```json
{
  "mcpServers": {
    "wordpress-mcp": {
      "command": "python",
      "args": [
        "D:/SIVA/mcps/wordpress-mcp/src/wordpress_mcp/server.py"
      ],
      "env": {
        "WP_SITE_URL": "https://yoursite.com",
        "WP_USERNAME": "admin",
        "WP_APP_PASSWORD": "abcd 1234 efgh 5678 ijkl 9012"
      }
    }
  }
}
```

### Option 2: Running with UV (Fast & Isolated dependency resolution)
```json
{
  "mcpServers": {
    "wordpress-mcp": {
      "command": "uv",
      "args": [
        "run",
        "--path",
        "D:/SIVA/mcps/wordpress-mcp/src/wordpress_mcp/server.py"
      ],
      "env": {
        "WP_SITE_URL": "https://yoursite.com",
        "WP_USERNAME": "admin",
        "WP_APP_PASSWORD": "abcd 1234 efgh 5678 ijkl 9012"
      }
    }
  }
}
```

---

## MCP Tools Reference

### Posts
* `wp_list_posts(status, categories, tags, author, after, before, search_query, page, per_page)`: List posts with pagination (capped at 50 results/page) and filters.
* `wp_get_post(post_id)`: Retrieve full HTML content and details for a post.
* `wp_create_post(title, content, status, excerpt, author, categories, tags, featured_media)`: Create a new post.
* `wp_update_post(post_id, title, content, status, ...)`: Edit a post.
* `wp_delete_post(post_id, force)`: Trash or permanently delete a post.

### Pages
* `wp_list_pages(parent, status, search_query, page, per_page)`: List pages (use `parent=0` for top-level pages).
* `wp_get_page(page_id)`: Get full page details.
* `wp_create_page(title, content, status, parent, author)`: Create a page.
* `wp_update_page(page_id, ...)`: Edit a page.
* `wp_delete_page(page_id, force)`: Trash/delete a page.

### Media Library
* `wp_list_media(media_type, mime_type, page, per_page)`: View attachments.
* `wp_get_media(media_id)`: Get media metadata and urls.
* `wp_upload_media(file_path, data_base64, file_name, mime_type)`: Upload media (accepts absolute path to a file or base64 data).
* `wp_update_media_metadata(media_id, title, alt_text, caption, description)`: Update media metadata.
* `wp_delete_media(media_id, force)`: Permanently delete a media item.

### Taxonomies
* `wp_list_categories(search_query, page, per_page)` / `wp_create_category` / `wp_update_category` / `wp_delete_category`
* `wp_list_tags(search_query, page, per_page)` / `wp_create_tag` / `wp_update_tag` / `wp_delete_tag`

### Comments
* `wp_list_comments(post_id, status, page, per_page)`: List and search comments.
* `wp_get_comment(comment_id)`: Get comment details.
* `wp_create_comment(post_id, content, parent_id, author_name, author_email)`: Reply to or submit comments.
* `wp_update_comment_status(comment_id, status)`: Approve, unapprove (hold), mark spam, or trash comments.
* `wp_delete_comment(comment_id, force)`: Delete comments.

### Users
* `wp_list_users` / `wp_get_user` / `wp_create_user` / `wp_update_user` / `wp_delete_user`

### Site Settings & Custom Fields
* `wp_get_site_settings()` / `wp_update_site_settings(...)`
* `wp_list_plugins()` / `wp_list_themes()`
* `wp_detect_custom_post_types()`: Discover CPTs REST routes.
* `wp_update_post_meta(post_id, meta_key, meta_value, post_type)`: Update custom meta fields (ACF/meta boxes) exposed in REST.

### Search
* `wp_search(search_query, subtype, page, per_page)`: Global search cross-cutting all content types.

---

## Safety Features
* **Dry-Run Mode**: Write operations (POST/PUT/DELETE) are blocked and logged locally instead of executing when `DRY_RUN=true`.
* **Credential Protection**: The server automatically catches exceptions and sanitizes any reference to `WP_APP_PASSWORD` before returning errors.
* **SSL Requirement**: Enforces HTTPS connections unless `ALLOW_INSECURE_HTTP=true` is explicitly enabled.
* **Token Saving**: In list actions, the HTML tags from excerpt and content fields are stripped, and content body is removed, saving significant context tokens for LLM clients.