WordPress MCP Custom Server
# WordPress MCP Custom Server
WordPress MCP server with:
- capability-based versioned tools (`*.v1`)
- backward-compatible aliases (old tool names still work)
- unified error contract
- request-level observability (`requestId`, duration, status)
- retry/timeout HTTP client for WP + W3C requests
- text playbooks/checklists for repeatable execution
- A/B benchmark report generator (`benchmark-summary.md`)
- write-safety policy for generic REST writes (allowlist + approval + dry-run)
## Installation
```bash
cd /Users/yanka/dev/wp-mcp-custom
npm install
```
## Required env
- `WP_URL`
- `WP_USER`
- `WP_APP_PASS`
Optional:
- `WP_PROJECT_ROOT` for file tools
- `PROJECT_PROFILE_PATH` for custom profile location
## Project profile
Create `project.profile.json` in server working directory (or use `PROJECT_PROFILE_PATH`):
```json
{
"projectType": "wordpress",
"capabilities": ["seo", "content", "site", "validation", "files"],
"limits": {
"listFilesDefault": 200,
"listFilesMax": 2000,
"autofixDefaultMaxFiles": 500,
"autofixMaxFiles": 5000
},
"autofix": {
"defaultPaths": [
"wp-content/themes",
"wp-content/mu-plugins"
]
},
"http": {
"timeoutMs": 15000,
"retries": 2,
"retryDelayMs": 250,
"maxRetryDelayMs": 2000
},
"safety": {
"enabled": true,
"writeMethods": ["POST", "PUT", "DELETE"],
"allowedWritePathPrefixes": [
"/wp/v2/posts",
"/wp/v2/pages",
"/custom/v1/update-option",
"/custom/v1/update-yoast"
],
"requireApprovalPathPrefixes": [
"/wp/v2/settings",
"/wp/v2/users",
"/wp/v2/themes",
"/wp/v2/plugins"
]
}
}
```
## Tool naming
Canonical versioned tools:
- `content.list.v1`
- `content.publish.v1`
- `content.update_fields.v1`
- `site.request.v1`
- `site.update_option.v1`
- `seo.set_meta.v1`
- `project.files.list.v1`
- `project.files.read.v1`
- `project.files.write.v1`
- `validation.w3c.validate_urls_raw.v1`
- `validation.w3c.validate_pages.v1`
- `validation.w3c.validate_and_recheck.v1`
- `validation.w3c.autofix_safe.v1`
- `playbook.list.v1`
- `playbook.read.v1`
- `checklist.seo_landing_audit.v1`
- `checklist.w3c_validate_and_fix_plan.v1`
- `checklist.multilang_publish.v1`
- `benchmark.compare_ab.v1`
Backward-compatible aliases still supported:
- `list_posts`, `create_post_multilang`, `update_acf_fields`
- `wp_request`, `update_option`, `update_yoast`
- `list_project_files`, `read_project_file`, `write_project_file`
- `w3c_validate_live_urls_raw`, `w3c_validate_pages`, `w3c_validate_and_recheck`, `w3c_autofix_safe`
## Playbooks
Stored in `/Users/yanka/dev/wp-mcp-custom/playbooks`:
- `seo-landing-checklist-v1.md`
- `w3c-fix-checklist-v1.md`
- `multilang-publish-v1.md`
Use:
- `playbook.list.v1`
- `playbook.read.v1`
## Safety behavior for `site.request.v1`
- `GET` requests are allowed.
- Write methods are checked against `safety.allowedWritePathPrefixes`.
- Paths in `safety.requireApprovalPathPrefixes` require `require_approval=true`.
- `dry_run=true` returns preview without sending request.
## Benchmark demo report
Use `benchmark.compare_ab.v1` with:
- `runs_prompt_only`
- `runs_mcp`
- optional `output_path`
Output:
- aggregate metrics
- per-case comparisons
- generated markdown report (`mcp-benchmarks/benchmark-summary.md` by default)
## Unified error contract
Every tool error returns:
```json
{
"code": "INVALID_ARGUMENT",
"message": "...",
"details": {},
"retryable": false,
"requestId": "..."
}
```
## Tests
```bash
npm test
```
## Notes
- Logs go to stderr as JSON (`tool.start`, `tool.success`, `tool.error`, `server.started`).
- Tool schemas use stricter JSON Schema (`additionalProperties: false`) for stable contracts.
TDQS
Scored across 32 tools
The tool set has 32 tools, but many are deprecated aliases for the same underlying operations. There are also overlapping validation tools (validate_urls_raw vs validate_pages vs validate_and_recheck vs autofix_safe) that are quite similar in purpose, and overlapping checklist tools. The deprecated aliases create significant ambiguity about which tool to use.
The set mixes namespace-dotted versioned names (content.list.v1, site.request.v1) with deprecated snake_case aliases (list_posts, wp_request). Even within the main names, there's inconsistent structure: some use domain.action form (content.publish.v1) while others use flat action form (read_project_file, benchmark.compare_ab.v1).
32 tools is excessive for what is genuinely a moderate-scope WordPress automation server. Critically, roughly half of the tools (13+) are deprecated aliases that should have been removed, meaning only about 19 are real and roughly half of those are legitimate. The deprecation burden inflates the count enormously.
The core surface covers content publishing, ACF updates, project file management, site options, SEO meta, W3C validation, playbooks, and benchmarks. However, there are notable gaps: no tool to update existing posts (only list and publish new), no get single post, and no delete. Content update appears limited to ACF fields rather than general post editing.