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.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues