This connects Claude directly to your WordPress site via the REST API, exposing 30 tools across posts, pages, media, and comments. You can create drafts, schedule publishing, upload images, moderate comments, and search content without leaving your editor. It runs locally over stdio with credential validation, SSRF protection, and input sanitization baked in. Available as a Python package or container, with automated CVE monitoring through GitHub Actions. Useful if you're publishing technical articles or managing WordPress content programmatically and want Claude to handle the REST API calls instead of writing curl commands or switching to wp-admin.
Public tool metadata for what this MCP can expose to an agent.
wp_list_postsList WordPress posts with optional filters. Returns post ID, title, status, date, and categories. Use to browse existing content or find posts by keyword.3 paramsList WordPress posts with optional filters. Returns post ID, title, status, date, and categories. Use to browse existing content or find posts by keyword.
searchstringstatusstringper_pagenumberwp_get_postGet a single WordPress post with full content, metadata, categories, and tags. Use to inspect post content before editing.1 paramsGet a single WordPress post with full content, metadata, categories, and tags. Use to inspect post content before editing.
idnumberwp_create_postCreate a new WordPress post. Provide title and content (HTML). Optionally set status (draft/publish), categories, and tags.5 paramsCreate a new WordPress post. Provide title and content (HTML). Optionally set status (draft/publish), categories, and tags.
tagsarraytitlestringstatusstringcontentstringcategoriesarraywp_update_postUpdate an existing WordPress post. Change title, content, status, categories, or tags.6 paramsUpdate an existing WordPress post. Change title, content, status, categories, or tags.
idnumbertagsarraytitlestringstatusstringcontentstringcategoriesarraywp_delete_postDelete a WordPress post. Moves to trash by default.1 paramsDelete a WordPress post. Moves to trash by default.
idnumberwp_list_pagesList WordPress pages. Returns page ID, title, status, and parent page. Use to browse site page structure.2 paramsList WordPress pages. Returns page ID, title, status, and parent page. Use to browse site page structure.
statusstringper_pagenumberwp_get_pageGet a single WordPress page with full content and metadata.1 paramsGet a single WordPress page with full content and metadata.
idnumberwp_create_pageCreate a new WordPress page. Provide title and content (HTML). Optionally set parent page for hierarchy.4 paramsCreate a new WordPress page. Provide title and content (HTML). Optionally set parent page for hierarchy.
titlestringparentnumberstatusstringcontentstringwp_update_pageUpdate an existing WordPress page.4 paramsUpdate an existing WordPress page.
idnumbertitlestringstatusstringcontentstringwp_delete_pageDelete a WordPress page.1 paramsDelete a WordPress page.
idnumberwp_list_mediaList media files in the WordPress library. Returns file URLs, types, and metadata.2 paramsList media files in the WordPress library. Returns file URLs, types, and metadata.
per_pagenumbermedia_typestringwp_delete_mediaPermanently delete a media file from WordPress.1 paramsPermanently delete a media file from WordPress.
idnumberwp_list_commentsList comments on WordPress posts. Filter by post ID.2 paramsList comments on WordPress posts. Filter by post ID.
postnumberper_pagenumberwp_create_commentCreate a new comment on a WordPress post.4 paramsCreate a new comment on a WordPress post.
postnumbercontentstringauthor_namestringauthor_emailstringwp_update_commentUpdate or moderate a comment. Change content or approval status.3 paramsUpdate or moderate a comment. Change content or approval status.
idnumberstatusstringcontentstringwp_delete_commentPermanently delete a comment.1 paramsPermanently delete a comment.
idnumberwp_list_categoriesList all WordPress categories with post counts.2 paramsList all WordPress categories with post counts.
searchstringper_pagenumberwp_list_tagsList all WordPress tags with post counts.2 paramsList all WordPress tags with post counts.
searchstringper_pagenumberwp_list_usersList WordPress users with their roles.2 paramsList WordPress users with their roles.
searchstringper_pagenumberwp_get_site_infoGet WordPress site information: name, description, URL, timezone, and available features.1 paramsGet WordPress site information: name, description, URL, timezone, and available features.
_fieldsstringA secure MCP (Model Context Protocol) server for WordPress content management. Designed for developers publishing about their work.
This MCP server is designed to be:
quay.io/crunchtools/mcp-wordpress| Component | Name |
|---|---|
| GitHub repo | crunchtools/mcp-wordpress |
| Container | quay.io/crunchtools/mcp-wordpress |
| Python package (PyPI) | mcp-wordpress-crunchtools |
| CLI command | mcp-wordpress-crunchtools |
| Module import | mcp_wordpress_crunchtools |
uvx mcp-wordpress-crunchtools
pip install mcp-wordpress-crunchtools
mcp-wordpress-crunchtools
# Create a shared upload directory (required before first run)
mkdir -p ~/.local/share/mcp-uploads-downloads
podman run -v ~/.local/share/mcp-uploads-downloads:/tmp/mcp-uploads:z \
-e WORDPRESS_URL=https://example.com \
-e WORDPRESS_USERNAME=admin \
-e WORDPRESS_APP_PASSWORD='xxxx xxxx xxxx xxxx' \
quay.io/crunchtools/mcp-wordpress
SELinux note: Use
:z(lowercase, shared) instead of:Z(uppercase, private). MCP servers run as long-lived stdio processes. With:Z, files copied into the directory after container start won't have the container's private MCS label and will be invisible inside the container. The:zflag sets a sharedcontainer_file_tcontext that all containers and the host can read/write.Tip: Use the same shared directory (
~/.local/share/mcp-uploads-downloads/) across multiple MCP container servers (e.g., mcp-wordpress and mcp-gemini) so generated files are immediately available for upload without copying.
git clone https://github.com/crunchtools/mcp-wordpress.git
cd mcp-wordpress
uv sync --all-extras
uv run mcp-wordpress-crunchtools
Set these environment variables:
| Variable | Description | Example |
|---|---|---|
WORDPRESS_URL | WordPress site URL | https://example.com |
WORDPRESS_USERNAME | WordPress username | admin |
WORDPRESS_APP_PASSWORD | Application password | xxxx xxxx xxxx xxxx |
MCP_UPLOAD_DIR | Upload directory inside container (optional) | /tmp/mcp-uploads (default) |
claude mcp add mcp-wordpress-crunchtools \
--env WORDPRESS_URL=https://example.com \
--env WORDPRESS_USERNAME=admin \
--env WORDPRESS_APP_PASSWORD="xxxx xxxx xxxx xxxx" \
-- uvx mcp-wordpress-crunchtools
pip install mcp-wordpress-crunchtools
claude mcp add mcp-wordpress-crunchtools \
--env WORDPRESS_URL=https://example.com \
--env WORDPRESS_USERNAME=admin \
--env WORDPRESS_APP_PASSWORD="xxxx xxxx xxxx xxxx" \
-- mcp-wordpress-crunchtools
# Create a shared upload directory (required before first run)
mkdir -p ~/.local/share/mcp-uploads-downloads
claude mcp add mcp-wordpress-crunchtools \
--env WORDPRESS_URL=https://example.com \
--env WORDPRESS_USERNAME=admin \
--env WORDPRESS_APP_PASSWORD="xxxx xxxx xxxx xxxx" \
-- podman run -i --rm \
-v ~/.local/share/mcp-uploads-downloads:/tmp/mcp-uploads:z \
-e WORDPRESS_URL \
-e WORDPRESS_USERNAME \
-e WORDPRESS_APP_PASSWORD \
quay.io/crunchtools/mcp-wordpress
| Tool | Description |
|---|---|
wordpress_get_site_info | Get site title, description, URL, timezone |
wordpress_test_connection | Verify API credentials work |
| Tool | Description |
|---|---|
wordpress_list_posts | List posts with filtering (status, category, search) |
wordpress_get_post | Get single post by ID with full content |
wordpress_search_posts | Search posts by keyword |
wordpress_create_post | Create new post (supports scheduling) |
wordpress_update_post | Update existing post |
wordpress_delete_post | Delete/trash a post |
wordpress_list_revisions | List revisions for a post |
wordpress_get_revision | Get specific revision content |
wordpress_list_categories | List available categories |
wordpress_list_tags | List available tags |
| Tool | Description |
|---|---|
wordpress_list_pages | List pages with filtering |
wordpress_get_page | Get single page by ID |
wordpress_create_page | Create new page |
wordpress_update_page | Update existing page |
wordpress_delete_page | Delete/trash a page |
wordpress_list_page_revisions | List page revisions |
| Tool | Description |
|---|---|
wordpress_list_media | List media items |
wordpress_get_media | Get media item details |
wordpress_upload_media | Upload file from local path |
wordpress_update_media | Update media metadata |
wordpress_delete_media | Delete media item |
wordpress_get_media_url | Get public URL for media |
| Tool | Description |
|---|---|
wordpress_list_comments | List comments with filtering |
wordpress_get_comment | Get single comment |
wordpress_create_comment | Add a comment to a post |
wordpress_update_comment | Update comment content/status |
wordpress_delete_comment | Delete a comment |
wordpress_moderate_comment | Approve, hold, spam, or trash |
Create a new WordPress post titled "My Technical Article" with the content below. Keep it as a draft.
Update post ID 123 to publish on December 25, 2024 at 10:00 AM.
Upload this image to WordPress and set the alt text to "Architecture diagram".
List all comments in "hold" status and approve the legitimate ones.
SecretStr, never logged# Install dev dependencies
uv sync --all-extras
# Run tests
uv run pytest
# Run linting
uv run ruff check src tests
# Run type checking
uv run mypy src
# Format code
uv run ruff format src tests
AGPL-3.0-or-later
Built by crunchtools.com