A single FastMCP server that proxies tool calls to any number of WordPress sites configured in sites.json. Each tool takes a `site` parameter to identify the target WordPress installation.
WordPress MCP server demonstrates solid engineering with 25 well-structured tools covering comprehensive site management. All tools have descriptions (10 - 140 chars, averaging ~80 chars, below the 194-char baseline but acceptable for action-oriented tools). Input schemas are present and properly typed for all tools. Parameters use Pydantic Field annotations with descriptions, and most include sensible defaults. Key strengths: consistent naming patterns (list_*, read_*, create_*, update_*, delete_*), good use of enums in status/orderby fields, comprehensive parameter coverage. Weaknesses: (1) Output schemas are NOT documented, tool descriptions mention what they return in prose but lack formal JSON Schema definitions in source, violating critical check D; (2) No error handling guidance, no recovery patterns, retry classification, or actionable error messages visible in code; (3) No pagination details in output (total count, next_cursor) despite list_posts/list_categories/list_tags/list_users accepting pagination inputs; (4) Destructive operations (delete_post, delete_category, delete_tag, delete_user) lack confirmation/dry-run patterns; (5) rank_math parameter in create_post/update_post is a free-form object, should enumerate valid SEO field names. Despite these gaps, the tool suite is production-grade for read operations and competent for mutations.
Create a new post category with optional description and Rank Math SEO.
Create a new post or page with content, SEO, categories, tags, and featured image.
Create a new post tag with optional description and Rank Math SEO.
Create a new WordPress user with email, password, and role.
Delete a category permanently or move posts to a parent/default category.
Delete a post or page permanently or move to trash.
Output schemas not documented in source code. Tool descriptions describe return values in prose (e.g., 'Read full content, metadata, categories, tags, featured image, and Rank Math SEO') but formal JSON Schema definitions are absent. LLMs cannot reliably plan downstream tool calls or extract structured data without knowing the response shape.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 75 | <=2025-11-25 | v2 |
Delete a tag permanently.
Delete a user permanently or reassign their posts to another user.
Get WordPress site information: version, theme, plugins, and settings.
Get WordPress site settings: title, tagline, homepage, timezone, language, date/time format.
List all post categories with descriptions, counts, and Rank Math SEO.
List posts or pages with filtering, pagination, and sorting.
List all configured WordPress sites with their URLs.
List all post tags with descriptions, counts, and Rank Math SEO.
List all WordPress users with roles, emails, and metadata.
Read a single category with posts count and Rank Math SEO.
Read full content, metadata, categories, tags, featured image, and Rank Math SEO.
Read a single tag with posts count and Rank Math SEO.
Read a single user's full profile, roles, and metadata.
Update an existing category (name, description, parent, Rank Math SEO).
Update an existing post or page (title, content, SEO, categories, tags, featured image).
Update WordPress site settings: title, tagline, homepage, timezone, language, date/time format.
Update an existing tag (name, description, Rank Math SEO).
Update an existing user (email, password, name, role).
Upload an image file to WordPress media library and return attachment ID.
Destructive operations lack confirmation/dry-run patterns. delete_post, delete_category, delete_tag, and delete_user accept a force parameter (true/false) but provide no confirmation step, dry-run option, or undo capability. Agents have no safeguard against accidental data loss.
Error handling lacks recovery guidance. The code calls WordPress via JSON-RPC and catches resp.raise_for_status() and ValueError, but tool definitions include no error classification, retry guidance, or actionable error messages. E.g., if a post_id is not found, the error should suggest search_posts() as a recovery path.
Pagination outputs not specified. list_posts, list_categories, list_tags, and list_users accept number, page parameters but tool descriptions do not document whether responses include total count, next_cursor, or has_more. Without this metadata, agents cannot determine if more results exist or plan pagination loops.
rank_math parameter is a free-form object in create_post, update_post, create_category, update_category, create_tag, and update_tag. Descriptions list valid subfields (title, description, focus_keyword, etc.) as prose, but no validation or enum constraints. LLMs may pass invalid SEO field names without feedback.
No idempotency guarantees. Tools that mutate state (create_post, create_user, etc.) do not document idempotency behavior. If an agent retries due to a transient error, it may create duplicate posts or users.
Batch operations not offered. Tools like add_category to a post, add_tag to a post, or add_user to a site operate one item at a time. Agents invoking these in loops waste tokens and latency. No batch variants (e.g., add_categories with an array) are present.
Response field naming not normalized. If create_post returns a post_id and update_post expects post_id, but get_site_info returns different field names (e.g., plugin IDs as raw integers), agents must infer mappings. Field names should be consistent across tools that work on the same resource.