@adsim/wordpress-mcp-server 3.1.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +543 -176
- package/dxt/manifest.json +86 -9
- package/index.js +3156 -36
- package/package.json +1 -1
- package/src/confirmationToken.js +64 -0
- package/src/contentAnalyzer.js +476 -0
- package/src/htmlParser.js +80 -0
- package/src/linkUtils.js +158 -0
- package/src/utils/contentCompressor.js +116 -0
- package/src/woocommerceClient.js +88 -0
- package/tests/unit/contentAnalyzer.test.js +397 -0
- package/tests/unit/tools/analyzeEeatSignals.test.js +192 -0
- package/tests/unit/tools/approval.test.js +251 -0
- package/tests/unit/tools/auditCanonicals.test.js +149 -0
- package/tests/unit/tools/auditHeadingStructure.test.js +150 -0
- package/tests/unit/tools/auditMediaSeo.test.js +123 -0
- package/tests/unit/tools/auditOutboundLinks.test.js +175 -0
- package/tests/unit/tools/auditTaxonomies.test.js +173 -0
- package/tests/unit/tools/contentCompressor.test.js +320 -0
- package/tests/unit/tools/contentIntelligence.test.js +2168 -0
- package/tests/unit/tools/destructive.test.js +246 -0
- package/tests/unit/tools/findBrokenInternalLinks.test.js +222 -0
- package/tests/unit/tools/findKeywordCannibalization.test.js +183 -0
- package/tests/unit/tools/findOrphanPages.test.js +145 -0
- package/tests/unit/tools/findThinContent.test.js +145 -0
- package/tests/unit/tools/internalLinks.test.js +283 -0
- package/tests/unit/tools/perTargetControls.test.js +228 -0
- package/tests/unit/tools/site.test.js +6 -1
- package/tests/unit/tools/woocommerce.test.js +344 -0
- package/tests/unit/tools/woocommerceIntelligence.test.js +341 -0
- package/tests/unit/tools/woocommerceWrite.test.js +323 -0
package/README.md
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
# WordPress MCP Server
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
|
-
[](https://nodejs.org/)
|
|
5
|
+
[](https://github.com/anthropics/mcp)
|
|
6
|
+
[](https://github.com/GeorgesAdSim/wordpress-mcp-server/actions)
|
|
7
|
+
[](https://www.npmjs.com/package/@adsim/wordpress-mcp-server)
|
|
7
8
|
|
|
8
|
-
Enterprise Governance · Audit Trail · Multi-Site · Plugin-Free
|
|
9
|
+
**Enterprise Governance · Audit Trail · Multi-Site · Plugin-Free**
|
|
9
10
|
|
|
10
11
|
The enterprise governance layer for Claude-to-WordPress integrations — secure, auditable, and multi-site.
|
|
11
12
|
|
|
12
|
-
**
|
|
13
|
+
**v4.4.0 Enterprise** · 79 tools · 613 Vitest tests · GitHub Actions CI · HTTP Streamable transport · MCPB bundle · SEO metadata · SEO audit suite · Content intelligence · Plugin & theme management · Revision control · Editorial approval workflow · Destructive confirmation · Internal link analysis · WooCommerce (read + intelligence + write) · Execution controls · JSON audit trail · Multi-site targeting
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
## Architecture
|
|
17
|
-
|
|
18
18
|
```
|
|
19
19
|
┌─────────────────────────┐
|
|
20
20
|
│ Claude Client │ Claude Desktop · Claude Code · Any MCP client
|
|
21
21
|
└────────────┬────────────┘
|
|
22
|
-
│ MCP Protocol (stdio)
|
|
22
|
+
│ MCP Protocol (stdio or HTTP Streamable)
|
|
23
23
|
┌────────────▼────────────┐
|
|
24
24
|
│ WordPress MCP Server │ Node.js · Standalone · No WordPress plugin
|
|
25
25
|
├─────────────────────────┤
|
|
26
26
|
│ Execution Controls │ Read-only · Draft-only · Plugin mgmt · Type/status allowlists
|
|
27
27
|
├─────────────────────────┤
|
|
28
|
-
│ Audit Logging │ JSON on stderr ·
|
|
28
|
+
│ Audit Logging │ JSON on stderr · 79 instrumentation points
|
|
29
29
|
├─────────────────────────┤
|
|
30
30
|
│ Rate Limiting │ Client-side · Configurable per-minute cap
|
|
31
|
+
├─────────────────────────┤
|
|
32
|
+
│ HTTP Transport │ Bearer auth · Session management · Origin validation
|
|
31
33
|
└────────────┬────────────┘
|
|
32
34
|
│ HTTPS + WordPress Application Password (Basic Auth over TLS)
|
|
33
35
|
┌────────────▼────────────┐
|
|
@@ -37,7 +39,7 @@ The enterprise governance layer for Claude-to-WordPress integrations — secure,
|
|
|
37
39
|
|
|
38
40
|
## Why This Server
|
|
39
41
|
|
|
40
|
-
Most WordPress MCP servers focus on what you
|
|
42
|
+
Most WordPress MCP servers focus on what you can do. This one focuses on what you **should be allowed to do** — and who can verify it happened.
|
|
41
43
|
|
|
42
44
|
In regulated environments — financial services, healthcare, legal, government — AI-powered content operations need guardrails. This server provides them out of the box: read-only mode for monitoring, draft-only mode for review workflows, structured audit logs for compliance, and multi-site management for agencies operating across client portfolios.
|
|
43
45
|
|
|
@@ -56,7 +58,7 @@ This server is designed for safe operation in production environments:
|
|
|
56
58
|
|
|
57
59
|
## Data Retention
|
|
58
60
|
|
|
59
|
-
The server does not store or persist WordPress content. All processing is stateless — content flows through the server and is never cached, written to disk, or retained in memory beyond the scope of a single tool invocation. Audit logs are emitted to stderr in real-time and can be disabled (WP_AUDIT_LOG=off) or redirected to any logging pipeline based on deployment requirements. Zero data retention by design.
|
|
61
|
+
The server does not store or persist WordPress content. All processing is stateless — content flows through the server and is never cached, written to disk, or retained in memory beyond the scope of a single tool invocation. Audit logs are emitted to stderr in real-time and can be disabled (`WP_AUDIT_LOG=off`) or redirected to any logging pipeline based on deployment requirements. Zero data retention by design.
|
|
60
62
|
|
|
61
63
|
---
|
|
62
64
|
|
|
@@ -68,9 +70,18 @@ The server does not store or persist WordPress content. All processing is statel
|
|
|
68
70
|
- WordPress site with REST API enabled (default since WP 4.7)
|
|
69
71
|
- WordPress Application Password (WP 5.6+)
|
|
70
72
|
- HTTPS endpoint (required for production)
|
|
73
|
+
- WooCommerce 3.5+ (optional, for WooCommerce tools)
|
|
74
|
+
|
|
75
|
+
### Install from npm (recommended)
|
|
76
|
+
```bash
|
|
77
|
+
# Run directly — no install needed
|
|
78
|
+
npx -y @adsim/wordpress-mcp-server
|
|
71
79
|
|
|
72
|
-
|
|
80
|
+
# Or install globally
|
|
81
|
+
npm install -g @adsim/wordpress-mcp-server
|
|
82
|
+
```
|
|
73
83
|
|
|
84
|
+
### Install from GitHub
|
|
74
85
|
```bash
|
|
75
86
|
git clone https://github.com/GeorgesAdSim/wordpress-mcp-server.git
|
|
76
87
|
cd wordpress-mcp-server
|
|
@@ -80,11 +91,14 @@ npm install
|
|
|
80
91
|
### Configure
|
|
81
92
|
|
|
82
93
|
Create a `.env` file:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
94
|
+
```env
|
|
85
95
|
WP_API_URL=https://yoursite.com
|
|
86
96
|
WP_API_USERNAME=your-username
|
|
87
97
|
WP_API_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
|
|
98
|
+
|
|
99
|
+
# Optional: WooCommerce (generate at WooCommerce → Settings → Advanced → REST API)
|
|
100
|
+
WC_CONSUMER_KEY=ck_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
101
|
+
WC_CONSUMER_SECRET=cs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
88
102
|
```
|
|
89
103
|
|
|
90
104
|
To generate an Application Password: WordPress Admin → Users → Profile → Application Passwords → Add New.
|
|
@@ -93,15 +107,14 @@ To generate an Application Password: WordPress Admin → Users → Profile → A
|
|
|
93
107
|
|
|
94
108
|
Add to `claude_desktop_config.json`:
|
|
95
109
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
110
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
111
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
99
112
|
```json
|
|
100
113
|
{
|
|
101
114
|
"mcpServers": {
|
|
102
115
|
"wordpress": {
|
|
103
|
-
"command": "
|
|
104
|
-
"args": ["/
|
|
116
|
+
"command": "npx",
|
|
117
|
+
"args": ["-y", "@adsim/wordpress-mcp-server"],
|
|
105
118
|
"env": {
|
|
106
119
|
"WP_API_URL": "https://yoursite.com",
|
|
107
120
|
"WP_API_USERNAME": "your-username",
|
|
@@ -113,139 +126,319 @@ Add to `claude_desktop_config.json`:
|
|
|
113
126
|
```
|
|
114
127
|
|
|
115
128
|
### Connect to Claude Code
|
|
116
|
-
|
|
117
129
|
```bash
|
|
118
130
|
claude mcp add wordpress \
|
|
119
131
|
-e WP_API_URL=https://yoursite.com \
|
|
120
132
|
-e WP_API_USERNAME=your-username \
|
|
121
133
|
-e WP_API_PASSWORD="xxxx xxxx xxxx xxxx xxxx xxxx" \
|
|
122
|
-
--
|
|
134
|
+
-- npx -y @adsim/wordpress-mcp-server
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## HTTP Streamable Transport
|
|
140
|
+
|
|
141
|
+
> **New in v3.0.0** — Run the server over HTTP instead of (or alongside) stdio, following the MCP spec 2025-03-26.
|
|
142
|
+
|
|
143
|
+
### Start in HTTP mode
|
|
144
|
+
```bash
|
|
145
|
+
MCP_TRANSPORT=http \
|
|
146
|
+
MCP_HTTP_PORT=3000 \
|
|
147
|
+
MCP_AUTH_TOKEN=your-secret-token \
|
|
148
|
+
WP_API_URL=https://yoursite.com \
|
|
149
|
+
WP_API_USERNAME=your-username \
|
|
150
|
+
WP_API_PASSWORD="xxxx xxxx xxxx xxxx" \
|
|
151
|
+
npx -y @adsim/wordpress-mcp-server
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Dual mode (stdio + HTTP simultaneously)
|
|
155
|
+
```bash
|
|
156
|
+
MCP_TRANSPORT=http \
|
|
157
|
+
MCP_DUAL_MODE=true \
|
|
158
|
+
MCP_AUTH_TOKEN=your-secret-token \
|
|
159
|
+
npx -y @adsim/wordpress-mcp-server
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### HTTP environment variables
|
|
163
|
+
|
|
164
|
+
| Variable | Default | Description |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| `MCP_TRANSPORT` | `stdio` | Set to `http` to enable HTTP Streamable transport |
|
|
167
|
+
| `MCP_HTTP_PORT` | `3000` | HTTP server port |
|
|
168
|
+
| `MCP_HTTP_HOST` | `127.0.0.1` | Bind address |
|
|
169
|
+
| `MCP_AUTH_TOKEN` | _(none)_ | Bearer token for authentication (required in HTTP mode) |
|
|
170
|
+
| `MCP_ALLOWED_ORIGINS` | _(none)_ | Comma-separated allowed origins (anti-DNS-rebinding) |
|
|
171
|
+
| `MCP_SESSION_TIMEOUT_MS` | `3600000` | Session TTL in milliseconds (1 hour) |
|
|
172
|
+
| `MCP_DUAL_MODE` | `false` | Run stdio and HTTP transports simultaneously |
|
|
173
|
+
|
|
174
|
+
### Health check
|
|
175
|
+
```bash
|
|
176
|
+
curl http://localhost:3000/health
|
|
177
|
+
# → { "status": "ok", "version": "4.4.0", "transport": "http" }
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Connect an MCP client via HTTP
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"mcpServers": {
|
|
184
|
+
"wordpress-http": {
|
|
185
|
+
"url": "http://localhost:3000/mcp",
|
|
186
|
+
"headers": {
|
|
187
|
+
"Authorization": "Bearer your-secret-token"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## MCPB Bundle — Claude Desktop One-Click Install
|
|
197
|
+
|
|
198
|
+
> **New in v3.1.0** — Package the server as a `.mcpb` bundle for Claude Desktop distribution.
|
|
199
|
+
|
|
200
|
+
The bundle stores WordPress credentials securely in the OS keychain (`sensitive: true`) — no manual JSON editing required.
|
|
201
|
+
|
|
202
|
+
### Build the bundle
|
|
203
|
+
```bash
|
|
204
|
+
npm run build:mcpb
|
|
205
|
+
# → wordpress-mcp-server.mcpb
|
|
123
206
|
```
|
|
124
207
|
|
|
208
|
+
### Install in Claude Desktop
|
|
209
|
+
|
|
210
|
+
Double-click `wordpress-mcp-server.mcpb` — Claude Desktop will prompt for:
|
|
211
|
+
- WordPress Site URL
|
|
212
|
+
- WordPress Username
|
|
213
|
+
- WordPress Application Password _(stored in OS keychain)_
|
|
214
|
+
|
|
125
215
|
---
|
|
126
216
|
|
|
127
|
-
## Available Tools (
|
|
217
|
+
## Available Tools (79)
|
|
128
218
|
|
|
129
219
|
### Content Management
|
|
130
220
|
|
|
131
221
|
| Tool | Description |
|
|
132
|
-
|
|
133
|
-
| wp_list_posts | List posts with pagination, filtering by status/category/tag/author, and search |
|
|
134
|
-
| wp_get_post | Get a post by ID with full content, meta fields, and taxonomy info |
|
|
135
|
-
| wp_create_post | Create a post (defaults to draft). Supports HTML, categories, tags, featured image, meta |
|
|
136
|
-
| wp_update_post | Update any post field. Only provided fields are modified |
|
|
137
|
-
| wp_delete_post | Move to trash by default. Permanent deletion requires force=true |
|
|
138
|
-
| wp_search | Full-text search across all content types |
|
|
139
|
-
| wp_list_pages | List pages with hierarchy (parent/child), templates, and menu order |
|
|
140
|
-
| wp_get_page | Get page content, template, and hierarchy info |
|
|
141
|
-
| wp_create_page | Create a page with parent, template, and menu_order support |
|
|
142
|
-
| wp_update_page | Update any page field |
|
|
222
|
+
|---|---|
|
|
223
|
+
| `wp_list_posts` | List posts with pagination, filtering by status/category/tag/author, and search |
|
|
224
|
+
| `wp_get_post` | Get a post by ID with full content, meta fields, and taxonomy info |
|
|
225
|
+
| `wp_create_post` | Create a post (defaults to draft). Supports HTML, categories, tags, featured image, meta |
|
|
226
|
+
| `wp_update_post` | Update any post field. Only provided fields are modified |
|
|
227
|
+
| `wp_delete_post` | Move to trash by default. Permanent deletion requires `force=true`. Returns confirmation token when `WP_CONFIRM_DESTRUCTIVE=true` |
|
|
228
|
+
| `wp_search` | Full-text search across all content types |
|
|
229
|
+
| `wp_list_pages` | List pages with hierarchy (parent/child), templates, and menu order |
|
|
230
|
+
| `wp_get_page` | Get page content, template, and hierarchy info |
|
|
231
|
+
| `wp_create_page` | Create a page with parent, template, and menu_order support |
|
|
232
|
+
| `wp_update_page` | Update any page field |
|
|
143
233
|
|
|
144
234
|
### Media Library
|
|
145
235
|
|
|
146
236
|
| Tool | Description |
|
|
147
|
-
|
|
148
|
-
| wp_list_media | Browse media with type filtering (image/video/audio/document) |
|
|
149
|
-
| wp_get_media | Get URL, dimensions, alt text, caption, and all available sizes |
|
|
150
|
-
| wp_upload_media | Upload a file from a public URL to the WordPress media library |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `wp_list_media` | Browse media with type filtering (image/video/audio/document) |
|
|
239
|
+
| `wp_get_media` | Get URL, dimensions, alt text, caption, and all available sizes |
|
|
240
|
+
| `wp_upload_media` | Upload a file from a public URL to the WordPress media library |
|
|
151
241
|
|
|
152
242
|
### Taxonomies & Structure
|
|
153
243
|
|
|
154
244
|
| Tool | Description |
|
|
155
|
-
|
|
156
|
-
| wp_list_categories | List categories with hierarchy, post count, and descriptions |
|
|
157
|
-
| wp_list_tags | List tags with post count |
|
|
158
|
-
| wp_create_taxonomy_term | Create a new category or tag |
|
|
159
|
-
| wp_list_post_types | Discover all registered post types (including custom ones) |
|
|
160
|
-
| wp_list_custom_posts | List content from any custom post type (products, portfolio, events) |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `wp_list_categories` | List categories with hierarchy, post count, and descriptions |
|
|
247
|
+
| `wp_list_tags` | List tags with post count |
|
|
248
|
+
| `wp_create_taxonomy_term` | Create a new category or tag |
|
|
249
|
+
| `wp_list_post_types` | Discover all registered post types (including custom ones) |
|
|
250
|
+
| `wp_list_custom_posts` | List content from any custom post type (products, portfolio, events) |
|
|
161
251
|
|
|
162
252
|
### Engagement
|
|
163
253
|
|
|
164
254
|
| Tool | Description |
|
|
165
|
-
|
|
166
|
-
| wp_list_comments | List comments with filtering by post, status, and author |
|
|
167
|
-
| wp_create_comment | Create a comment or reply on any post |
|
|
168
|
-
| wp_list_users | List users with roles (read-only) |
|
|
255
|
+
|---|---|
|
|
256
|
+
| `wp_list_comments` | List comments with filtering by post, status, and author |
|
|
257
|
+
| `wp_create_comment` | Create a comment or reply on any post |
|
|
258
|
+
| `wp_list_users` | List users with roles (read-only) |
|
|
169
259
|
|
|
170
260
|
### SEO Metadata
|
|
171
261
|
|
|
172
262
|
| Tool | Description |
|
|
173
|
-
|
|
174
|
-
| wp_get_seo_meta | Read SEO title, description, focus keyword, canonical, robots, Open Graph. Auto-detects Yoast, RankMath, SEOPress, All in One SEO |
|
|
175
|
-
| wp_update_seo_meta | Update SEO metadata with automatic plugin detection |
|
|
176
|
-
| wp_audit_seo | Bulk audit SEO across posts/pages with quality scoring (0-100), missing fields detection, and length checks |
|
|
263
|
+
|---|---|
|
|
264
|
+
| `wp_get_seo_meta` | Read SEO title, description, focus keyword, canonical, robots, Open Graph. Auto-detects Yoast, RankMath, SEOPress, All in One SEO |
|
|
265
|
+
| `wp_update_seo_meta` | Update SEO metadata with automatic plugin detection |
|
|
266
|
+
| `wp_audit_seo` | Bulk audit SEO across posts/pages with quality scoring (0-100), missing fields detection, and length checks |
|
|
177
267
|
|
|
178
268
|
SEO metadata updates are subject to the same enterprise controls and execution policies as all other write operations.
|
|
179
269
|
|
|
270
|
+
### SEO Audit Suite
|
|
271
|
+
|
|
272
|
+
> **New in v4.0–v4.2** — Deep technical SEO analysis without requiring any WordPress plugin.
|
|
273
|
+
|
|
274
|
+
| Tool | Description |
|
|
275
|
+
|---|---|
|
|
276
|
+
| `wp_audit_media_seo` | Audit media library for missing alt text, short alt text, and unoptimized filenames. Returns per-image scores and prioritized fix list |
|
|
277
|
+
| `wp_find_orphan_pages` | Identify posts with no internal links pointing to them, sorted by word count. Configurable minimum word threshold and exclusion list |
|
|
278
|
+
| `wp_audit_heading_structure` | Analyze H1/H2/H3 hierarchy in post content. Detects H1 in body, heading level skips, empty headings, focus keyword absent from H2 |
|
|
279
|
+
| `wp_find_thin_content` | Surface posts below a configurable word count threshold. Scores content quality by word count, heading density, and paragraph structure |
|
|
280
|
+
| `wp_audit_canonicals` | Validate canonical URLs across posts and pages. Detects missing canonicals, self-referencing mismatches, and cross-domain canonicals. Auto-detects RankMath/Yoast/SEOPress/AIOSEO |
|
|
281
|
+
| `wp_analyze_eeat_signals` | Score E-E-A-T signals per post: author bio presence, publication/update dates, outbound citations, word count, structured data markers. Returns a 0-100 score with a breakdown by dimension |
|
|
282
|
+
| `wp_find_broken_internal_links` | Check all internal links in a post via HEAD requests. Returns broken (4xx/5xx), redirected (3xx), and slow links. Configurable batch size and timeout |
|
|
283
|
+
| `wp_find_keyword_cannibalization` | Detect posts sharing the same RankMath/Yoast/SEOPress/AIOSEO focus keyword. Groups conflicts by keyword and flags the weakest post by word count |
|
|
284
|
+
| `wp_audit_taxonomies` | Identify taxonomy bloat: unused categories/tags, near-duplicate terms via Levenshtein distance, single-post terms, and over-tagged posts |
|
|
285
|
+
| `wp_audit_outbound_links` | Analyze external link profile per post. Detects links to low-authority domains, missing rel="nofollow" on sponsored links, and broken external URLs |
|
|
286
|
+
|
|
287
|
+
All SEO audit tools are read-only and always allowed regardless of governance flags.
|
|
288
|
+
|
|
289
|
+
### Content Intelligence
|
|
290
|
+
|
|
291
|
+
> **New in v4.4.0** — Deep content analysis and editorial intelligence without any WordPress plugin.
|
|
292
|
+
|
|
293
|
+
| Tool | Description |
|
|
294
|
+
|---|---|
|
|
295
|
+
| `wp_get_content_brief` | Editorial brief aggregator: SEO + structure + links in 1 call |
|
|
296
|
+
| `wp_extract_post_outline` | H1-H6 outline extraction with category-level pattern analysis |
|
|
297
|
+
| `wp_audit_readability` | Bulk Flesch-Kincaid FR scoring with transition word and passive voice analysis |
|
|
298
|
+
| `wp_audit_update_frequency` | Outdated content detection cross-referenced with SEO scores |
|
|
299
|
+
| `wp_build_link_map` | Internal link matrix with simplified PageRank scoring (0-100) |
|
|
300
|
+
| `wp_audit_anchor_texts` | Anchor text diversity audit: generic, over-optimized, image link detection |
|
|
301
|
+
| `wp_audit_schema_markup` | JSON-LD schema.org detection and validation (Article, FAQ, HowTo, LocalBusiness) |
|
|
302
|
+
| `wp_audit_content_structure` | Editorial structure scoring (0-100): intro, conclusion, FAQ, TOC, lists, images |
|
|
303
|
+
| `wp_find_duplicate_content` | TF-IDF cosine similarity for near-duplicate detection with union-find clustering |
|
|
304
|
+
| `wp_find_content_gaps` | Taxonomy under-representation analysis (categories + tags) |
|
|
305
|
+
| `wp_extract_faq_blocks` | FAQ inventory: JSON-LD, Gutenberg blocks, HTML patterns |
|
|
306
|
+
| `wp_audit_cta_presence` | CTA detection (6 types) with scoring 0-100 |
|
|
307
|
+
| `wp_extract_entities` | Regex/heuristic named entity extraction (brands, locations, persons, organizations) |
|
|
308
|
+
| `wp_get_publishing_velocity` | Publication cadence by author/category with trend detection |
|
|
309
|
+
| `wp_compare_revisions_diff` | Textual diff between revisions with amplitude scoring |
|
|
310
|
+
| `wp_list_posts_by_word_count` | Posts sorted by length with 6-tier segmentation |
|
|
311
|
+
|
|
312
|
+
All Content Intelligence tools are read-only and always allowed regardless of governance flags.
|
|
313
|
+
|
|
180
314
|
### Plugins
|
|
181
315
|
|
|
182
316
|
| Tool | Description |
|
|
183
|
-
|
|
184
|
-
| wp_list_plugins | List installed plugins with status, version, author. Requires Administrator (activate_plugins capability) |
|
|
185
|
-
| wp_activate_plugin | Activate a plugin. Blocked by `WP_READ_ONLY` and `WP_DISABLE_PLUGIN_MANAGEMENT` |
|
|
186
|
-
| wp_deactivate_plugin | Deactivate a plugin. Blocked by `WP_READ_ONLY` and `WP_DISABLE_PLUGIN_MANAGEMENT` |
|
|
317
|
+
|---|---|
|
|
318
|
+
| `wp_list_plugins` | List installed plugins with status, version, author. Requires Administrator (`activate_plugins` capability) |
|
|
319
|
+
| `wp_activate_plugin` | Activate a plugin. Blocked by `WP_READ_ONLY` and `WP_DISABLE_PLUGIN_MANAGEMENT` |
|
|
320
|
+
| `wp_deactivate_plugin` | Deactivate a plugin. Blocked by `WP_READ_ONLY` and `WP_DISABLE_PLUGIN_MANAGEMENT` |
|
|
187
321
|
|
|
188
322
|
### Themes
|
|
189
323
|
|
|
190
324
|
| Tool | Description |
|
|
191
|
-
|
|
192
|
-
| wp_list_themes | List installed themes with active theme detection. Requires `switch_themes` capability |
|
|
193
|
-
| wp_get_theme | Get theme details by stylesheet slug |
|
|
325
|
+
|---|---|
|
|
326
|
+
| `wp_list_themes` | List installed themes with active theme detection. Requires `switch_themes` capability |
|
|
327
|
+
| `wp_get_theme` | Get theme details by stylesheet slug |
|
|
194
328
|
|
|
195
329
|
### Revisions
|
|
196
330
|
|
|
197
331
|
| Tool | Description |
|
|
198
|
-
|
|
199
|
-
| wp_list_revisions | List revisions of a post or page (metadata only) |
|
|
200
|
-
| wp_get_revision | Get a specific revision with full content |
|
|
201
|
-
| wp_restore_revision | Restore a post to a previous revision (plugin-free 2-step approach) |
|
|
202
|
-
| wp_delete_revision | Permanently delete a revision. Blocked by `WP_READ_ONLY` and `
|
|
332
|
+
|---|---|
|
|
333
|
+
| `wp_list_revisions` | List revisions of a post or page (metadata only) |
|
|
334
|
+
| `wp_get_revision` | Get a specific revision with full content |
|
|
335
|
+
| `wp_restore_revision` | Restore a post to a previous revision (plugin-free 2-step approach) |
|
|
336
|
+
| `wp_delete_revision` | Permanently delete a revision. Blocked by `WP_READ_ONLY`, `WP_DISABLE_DELETE`, and `WP_CONFIRM_DESTRUCTIVE` |
|
|
337
|
+
|
|
338
|
+
### Editorial Workflow
|
|
339
|
+
|
|
340
|
+
> **New in v3.2.0** — Approval workflow for regulated content operations.
|
|
341
|
+
|
|
342
|
+
| Tool | Description |
|
|
343
|
+
|---|---|
|
|
344
|
+
| `wp_submit_for_review` | Transition a draft post to pending status (author action). Blocked by `WP_READ_ONLY` |
|
|
345
|
+
| `wp_approve_post` | Transition a pending post to publish (editor/admin action). Blocked by `WP_READ_ONLY` and `WP_DRAFT_ONLY` |
|
|
346
|
+
| `wp_reject_post` | Return a pending post to draft with a mandatory rejection reason (editor/admin action). Blocked by `WP_READ_ONLY` |
|
|
347
|
+
|
|
348
|
+
The approval workflow is enforced by `WP_REQUIRE_APPROVAL=true`, which blocks direct publish via `wp_update_post` and forces the draft → pending → publish path.
|
|
349
|
+
|
|
350
|
+
### Internal Link Intelligence
|
|
351
|
+
|
|
352
|
+
> **New in v3.3.0** — Audit and improve internal linking without auto-insertion.
|
|
353
|
+
|
|
354
|
+
| Tool | Description |
|
|
355
|
+
|---|---|
|
|
356
|
+
| `wp_analyze_links` | Audit all internal and external links in a post. HEAD request verification per link (broken/warning/unknown). Configurable max checks and timeout |
|
|
357
|
+
| `wp_suggest_internal_links` | Semantic link suggestions scored by category match (+3), freshness (+3/2/1), SEO focus keyword match (+2), title match (+2). Excludes already-linked posts |
|
|
358
|
+
|
|
359
|
+
Pre-flight linking workflow: `wp_suggest_internal_links` → user validates → `wp_update_post` (never auto-insert).
|
|
360
|
+
|
|
361
|
+
### WooCommerce
|
|
362
|
+
|
|
363
|
+
> **New in v3.4.0–v3.6.0** — Full WooCommerce integration with read, intelligence, and write operations.
|
|
364
|
+
|
|
365
|
+
Requires `WC_CONSUMER_KEY` and `WC_CONSUMER_SECRET` environment variables. Generate API keys at WooCommerce → Settings → Advanced → REST API.
|
|
366
|
+
|
|
367
|
+
| Tool | Description |
|
|
368
|
+
|---|---|
|
|
369
|
+
| `wc_list_products` | List products with filtering by status, category, search, and sorting by price/popularity |
|
|
370
|
+
| `wc_get_product` | Get a product by ID with full details. Includes variations summary for variable products |
|
|
371
|
+
| `wc_list_orders` | List orders with filtering by status, customer, and date |
|
|
372
|
+
| `wc_get_order` | Get an order by ID with line items, shipping, billing, and payment details |
|
|
373
|
+
| `wc_list_customers` | List customers with search and role filtering |
|
|
374
|
+
| `wc_get_customer` | Get a customer by ID with full profile, order history summary, and lifetime value |
|
|
375
|
+
| `wc_list_coupons` | List coupons with filtering by type, expiry status, and usage |
|
|
376
|
+
| `wc_get_coupon` | Get a coupon by ID with full discount rules and usage statistics |
|
|
377
|
+
| `wc_sales_report` | Generate sales summary for a date range: revenue, orders, average order value, top products |
|
|
378
|
+
| `wc_top_products` | Rank products by revenue, quantity sold, or order count for a given period |
|
|
379
|
+
| `wc_price_guardrail` | Analyze a price change for safety (read-only). Returns safe/unsafe based on configurable threshold percentage |
|
|
380
|
+
| `wc_update_product` | Update product fields (title, description, price, stock, status). Blocked by `WP_READ_ONLY` and subject to `wc_price_guardrail` thresholds |
|
|
381
|
+
| `wc_update_order_status` | Transition order status (e.g., processing → completed). Blocked by `WP_READ_ONLY` |
|
|
382
|
+
|
|
383
|
+
All WooCommerce write tools are blocked by `WP_READ_ONLY`. `wc_price_guardrail` is always allowed — it never modifies data.
|
|
203
384
|
|
|
204
385
|
### Operations
|
|
205
386
|
|
|
206
387
|
| Tool | Description |
|
|
207
|
-
|
|
208
|
-
| wp_set_target | Switch active WordPress site in multi-target mode |
|
|
209
|
-
| wp_site_info | Site info, current user, post types, enterprise controls, and available targets |
|
|
388
|
+
|---|---|
|
|
389
|
+
| `wp_set_target` | Switch active WordPress site in multi-target mode |
|
|
390
|
+
| `wp_site_info` | Site info, current user, post types, enterprise controls, and available targets |
|
|
210
391
|
|
|
211
392
|
---
|
|
212
393
|
|
|
213
394
|
## Enterprise Controls
|
|
214
395
|
|
|
215
|
-
Configure execution policy via environment variables. All restrictions are enforced before any API call is made — including SEO metadata and
|
|
396
|
+
Configure execution policy via environment variables. All restrictions are enforced before any API call is made — including SEO metadata, plugin operations, and WooCommerce writes.
|
|
216
397
|
|
|
217
398
|
| Control | Default | Effect |
|
|
218
|
-
|
|
219
|
-
| WP_READ_ONLY | false | Blocks all write operations (create, update, delete, upload, SEO updates, plugin management) |
|
|
220
|
-
| WP_DRAFT_ONLY | false | Restricts to draft and pending statuses only |
|
|
221
|
-
| WP_DISABLE_DELETE | false | Blocks all delete operations (posts + revisions) |
|
|
222
|
-
| WP_DISABLE_PLUGIN_MANAGEMENT | false | Blocks plugin activate/deactivate (list still allowed) |
|
|
223
|
-
|
|
|
224
|
-
|
|
|
225
|
-
|
|
|
226
|
-
|
|
|
399
|
+
|---|---|---|
|
|
400
|
+
| `WP_READ_ONLY` | `false` | Blocks all write operations (create, update, delete, upload, SEO updates, plugin management, WooCommerce writes) |
|
|
401
|
+
| `WP_DRAFT_ONLY` | `false` | Restricts to draft and pending statuses only |
|
|
402
|
+
| `WP_DISABLE_DELETE` | `false` | Blocks all delete operations (posts + revisions) |
|
|
403
|
+
| `WP_DISABLE_PLUGIN_MANAGEMENT` | `false` | Blocks plugin activate/deactivate (list still allowed) |
|
|
404
|
+
| `WP_REQUIRE_APPROVAL` | `false` | Blocks direct publish via `wp_update_post`. Forces draft → pending → publish approval workflow |
|
|
405
|
+
| `WP_CONFIRM_DESTRUCTIVE` | `false` | Requires a token confirmation before `wp_delete_post` and `wp_delete_revision` execute |
|
|
406
|
+
| `WP_ALLOWED_TYPES` | `all` | Restricts to specific post types (e.g., `post,page`) |
|
|
407
|
+
| `WP_ALLOWED_STATUSES` | `all` | Restricts to specific statuses (e.g., `draft,pending`) |
|
|
408
|
+
| `WP_MAX_CALLS_PER_MINUTE` | unlimited | Client-side rate limiting |
|
|
409
|
+
| `WP_AUDIT_LOG` | `on` | Structured JSON audit trail |
|
|
410
|
+
|
|
411
|
+
### Destructive confirmation flow
|
|
412
|
+
|
|
413
|
+
When `WP_CONFIRM_DESTRUCTIVE=true`, `wp_delete_post` and `wp_delete_revision` return a stateless confirmation token on the first call instead of executing. The token is valid for 60 seconds (SHA-256, zero persistence). Pass the token back on a second call to confirm execution.
|
|
414
|
+
|
|
415
|
+
Governance priority order: `WP_READ_ONLY` → `WP_DISABLE_DELETE` → `WP_CONFIRM_DESTRUCTIVE`
|
|
227
416
|
|
|
228
417
|
### Deployment profiles
|
|
229
418
|
|
|
230
419
|
**Agency content production** — writers can create and edit, but never publish or delete:
|
|
231
|
-
|
|
232
|
-
```bash
|
|
420
|
+
```env
|
|
233
421
|
WP_DRAFT_ONLY=true
|
|
234
422
|
WP_DISABLE_DELETE=true
|
|
235
423
|
WP_ALLOWED_STATUSES=draft,pending
|
|
236
424
|
WP_MAX_CALLS_PER_MINUTE=30
|
|
237
425
|
```
|
|
238
426
|
|
|
239
|
-
**
|
|
427
|
+
**Editorial review workflow** — forces human approval before publication:
|
|
428
|
+
```env
|
|
429
|
+
WP_REQUIRE_APPROVAL=true
|
|
430
|
+
WP_DISABLE_DELETE=true
|
|
431
|
+
WP_AUDIT_LOG=on
|
|
432
|
+
```
|
|
240
433
|
|
|
241
|
-
|
|
434
|
+
**Compliance monitoring** — read-only access for auditing existing content:
|
|
435
|
+
```env
|
|
242
436
|
WP_READ_ONLY=true
|
|
243
437
|
WP_AUDIT_LOG=on
|
|
244
438
|
```
|
|
245
439
|
|
|
246
440
|
**Regulated publishing** — restrict to specific content types in a controlled environment:
|
|
247
|
-
|
|
248
|
-
```bash
|
|
441
|
+
```env
|
|
249
442
|
WP_ALLOWED_TYPES=post
|
|
250
443
|
WP_ALLOWED_STATUSES=draft,pending,publish
|
|
251
444
|
WP_DISABLE_DELETE=true
|
|
@@ -253,12 +446,18 @@ WP_AUDIT_LOG=on
|
|
|
253
446
|
```
|
|
254
447
|
|
|
255
448
|
**Locked infrastructure** — content operations allowed, but no plugin/theme changes:
|
|
256
|
-
|
|
257
|
-
```bash
|
|
449
|
+
```env
|
|
258
450
|
WP_DISABLE_PLUGIN_MANAGEMENT=true
|
|
259
451
|
WP_DISABLE_DELETE=true
|
|
260
452
|
```
|
|
261
453
|
|
|
454
|
+
**E-commerce safe mode** — WooCommerce read and intelligence, no writes:
|
|
455
|
+
```env
|
|
456
|
+
WP_READ_ONLY=true
|
|
457
|
+
WC_CONSUMER_KEY=ck_xxx
|
|
458
|
+
WC_CONSUMER_SECRET=cs_xxx
|
|
459
|
+
```
|
|
460
|
+
|
|
262
461
|
Blocked actions return a clear error message explaining which control prevented execution, and are logged in the audit trail with status `blocked`.
|
|
263
462
|
|
|
264
463
|
---
|
|
@@ -269,17 +468,17 @@ The SEO tools auto-detect which SEO plugin is installed on your WordPress site a
|
|
|
269
468
|
|
|
270
469
|
Supported plugins:
|
|
271
470
|
|
|
272
|
-
- **Yoast SEO** — _yoast_wpseo_title
|
|
273
|
-
- **RankMath** — rank_math_title
|
|
274
|
-
- **SEOPress** — _seopress_titles_title
|
|
275
|
-
- **All in One SEO** — _aioseo_title
|
|
471
|
+
- **Yoast SEO** — `_yoast_wpseo_title`, `_yoast_wpseo_metadesc`, `_yoast_wpseo_focuskw`, plus `yoast_head_json` REST API extension
|
|
472
|
+
- **RankMath** — `rank_math_title`, `rank_math_description`, `rank_math_focus_keyword`
|
|
473
|
+
- **SEOPress** — `_seopress_titles_title`, `_seopress_titles_desc`, `_seopress_analysis_target_kw`
|
|
474
|
+
- **All in One SEO** — `_aioseo_title`, `_aioseo_description`, `_aioseo_keywords`
|
|
276
475
|
|
|
277
476
|
### SEO Audit Scoring
|
|
278
477
|
|
|
279
478
|
`wp_audit_seo` scores each post on a 100-point scale:
|
|
280
479
|
|
|
281
480
|
| Check | Penalty |
|
|
282
|
-
|
|
481
|
+
|---|---|
|
|
283
482
|
| Missing SEO title | -30 |
|
|
284
483
|
| SEO title too short (< 30 chars) or too long (> 60 chars) | -10 |
|
|
285
484
|
| Missing meta description | -30 |
|
|
@@ -289,14 +488,13 @@ Supported plugins:
|
|
|
289
488
|
|
|
290
489
|
### Exposing SEO Meta Fields (Required)
|
|
291
490
|
|
|
292
|
-
Most SEO plugins store their data in WordPress post meta fields that are
|
|
491
|
+
Most SEO plugins store their data in WordPress post meta fields that are not exposed via the REST API by default. Without this step, `wp_get_seo_meta` and `wp_audit_seo` will return empty results even though your SEO data exists in the database.
|
|
293
492
|
|
|
294
493
|
Add the following code to your theme's `functions.php` (Appearance → Theme File Editor → functions.php) or — preferably — create a custom mini-plugin (see below).
|
|
295
494
|
|
|
296
|
-
> **
|
|
495
|
+
> ⚠️ **Important:** When pasting code into `functions.php`, make sure the file starts with exactly `<?php` — no extra characters before it. A stray character (like `<<?php`) will break the WordPress REST API by injecting invalid output before JSON responses, causing `Unexpected token '<'` errors in MCP.
|
|
297
496
|
|
|
298
497
|
**RankMath:**
|
|
299
|
-
|
|
300
498
|
```php
|
|
301
499
|
add_action( 'init', function() {
|
|
302
500
|
$fields = array(
|
|
@@ -325,7 +523,6 @@ add_action( 'init', function() {
|
|
|
325
523
|
```
|
|
326
524
|
|
|
327
525
|
**Yoast SEO:**
|
|
328
|
-
|
|
329
526
|
```php
|
|
330
527
|
add_action( 'init', function() {
|
|
331
528
|
$fields = array(
|
|
@@ -355,7 +552,6 @@ add_action( 'init', function() {
|
|
|
355
552
|
```
|
|
356
553
|
|
|
357
554
|
**SEOPress:**
|
|
358
|
-
|
|
359
555
|
```php
|
|
360
556
|
add_action( 'init', function() {
|
|
361
557
|
$fields = array(
|
|
@@ -384,7 +580,6 @@ add_action( 'init', function() {
|
|
|
384
580
|
```
|
|
385
581
|
|
|
386
582
|
**All in One SEO:**
|
|
387
|
-
|
|
388
583
|
```php
|
|
389
584
|
add_action( 'init', function() {
|
|
390
585
|
$fields = array(
|
|
@@ -412,12 +607,11 @@ add_action( 'init', function() {
|
|
|
412
607
|
|
|
413
608
|
### Alternative: MCP SEO Bridge Plugin (Recommended)
|
|
414
609
|
|
|
415
|
-
>
|
|
610
|
+
> Note: Core content operations require no WordPress plugin. SEO metadata tools may require exposing meta fields via the REST API using either a theme snippet or this optional micro-plugin.
|
|
416
611
|
|
|
417
612
|
Instead of modifying your theme's `functions.php` (which gets overwritten on theme updates), create a standalone micro-plugin.
|
|
418
613
|
|
|
419
614
|
Create the file `wp-content/plugins/mcp-seo-bridge.php`:
|
|
420
|
-
|
|
421
615
|
```php
|
|
422
616
|
<?php
|
|
423
617
|
/**
|
|
@@ -431,7 +625,6 @@ Create the file `wp-content/plugins/mcp-seo-bridge.php`:
|
|
|
431
625
|
if ( ! defined( 'ABSPATH' ) ) exit;
|
|
432
626
|
|
|
433
627
|
add_action( 'init', function() {
|
|
434
|
-
// Auto-detect SEO plugin and register appropriate fields
|
|
435
628
|
$fields = array();
|
|
436
629
|
|
|
437
630
|
if ( defined( 'RANK_MATH_VERSION' ) ) {
|
|
@@ -479,30 +672,51 @@ Activate it from WordPress Admin → Plugins. This approach auto-detects your SE
|
|
|
479
672
|
### Verifying SEO Fields Are Exposed
|
|
480
673
|
|
|
481
674
|
After adding the code, verify the fields are accessible:
|
|
482
|
-
|
|
483
675
|
```bash
|
|
484
676
|
curl -s -u "username:application-password" \
|
|
485
677
|
"https://yoursite.com/wp-json/wp/v2/posts?per_page=1" | python3 -m json.tool | grep -E "rank_math|yoast|seopress|aioseo"
|
|
486
678
|
```
|
|
487
679
|
|
|
488
|
-
If you see your SEO fields in the meta object, the configuration is working.
|
|
680
|
+
If you see your SEO fields in the `meta` object, the configuration is working.
|
|
489
681
|
|
|
490
682
|
### Troubleshooting SEO Fields
|
|
491
683
|
|
|
492
684
|
| Symptom | Cause | Fix |
|
|
493
|
-
|
|
494
|
-
| wp_audit_seo returns empty SEO data | Meta fields not exposed via REST API | Add register_post_meta() code above |
|
|
495
|
-
| Unexpected token '<' on all MCP calls | Stray character before `<?php` in functions.php | Remove any characters before `<?php` |
|
|
685
|
+
|---|---|---|
|
|
686
|
+
| `wp_audit_seo` returns empty SEO data | Meta fields not exposed via REST API | Add `register_post_meta()` code above |
|
|
687
|
+
| `Unexpected token '<'` on all MCP calls | Stray character before `<?php` in `functions.php` | Remove any characters before `<?php` |
|
|
496
688
|
| SEO fields visible but all null | SEO plugin not yet configured on those posts | Set titles/descriptions in RankMath/Yoast editor |
|
|
497
689
|
| No SEO plugin detected | Plugin constant not matched | Verify your SEO plugin is active |
|
|
498
|
-
| Fields lost after theme update | Code was in functions.php | Use the MCP SEO Bridge plugin instead |
|
|
690
|
+
| Fields lost after theme update | Code was in `functions.php` | Use the MCP SEO Bridge plugin instead |
|
|
499
691
|
|
|
500
692
|
---
|
|
501
693
|
|
|
502
|
-
##
|
|
694
|
+
## WooCommerce Setup
|
|
503
695
|
|
|
504
|
-
|
|
696
|
+
### Generate API Keys
|
|
505
697
|
|
|
698
|
+
Go to WooCommerce → Settings → Advanced → REST API → Add key.
|
|
699
|
+
|
|
700
|
+
Set permissions to **Read/Write** if you plan to use `wc_update_product` or `wc_update_order_status`. Set to **Read** for a read-only WooCommerce integration.
|
|
701
|
+
```env
|
|
702
|
+
WC_CONSUMER_KEY=ck_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
703
|
+
WC_CONSUMER_SECRET=cs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### Price Guardrail
|
|
707
|
+
|
|
708
|
+
`wc_price_guardrail` analyzes proposed price changes before any write operation. It returns `safe` or `unsafe` based on a configurable threshold (default 20%). Claude should call this tool before `wc_update_product` when modifying prices.
|
|
709
|
+
```env
|
|
710
|
+
WC_PRICE_GUARDRAIL_THRESHOLD=20 # percentage — changes above this require explicit override
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
`wc_price_guardrail` is always allowed regardless of `WP_READ_ONLY`. It never modifies data.
|
|
714
|
+
|
|
715
|
+
---
|
|
716
|
+
|
|
717
|
+
## Testing
|
|
718
|
+
|
|
719
|
+
613 unit tests covering all 79 tools — zero network calls, fully mocked.
|
|
506
720
|
```bash
|
|
507
721
|
npm test # run all tests (vitest)
|
|
508
722
|
npm run test:watch # watch mode
|
|
@@ -510,20 +724,37 @@ npm run test:coverage # coverage report
|
|
|
510
724
|
```
|
|
511
725
|
|
|
512
726
|
| Test file | Scope | Tests |
|
|
513
|
-
|
|
514
|
-
| governance.test.js |
|
|
515
|
-
| posts.test.js | list, get, create, update, delete, search | 18 |
|
|
516
|
-
| pages.test.js | list, get, create, update | 12 |
|
|
517
|
-
| media.test.js | list, get, upload | 14 |
|
|
518
|
-
| taxonomies.test.js | categories, tags, create term | 16 |
|
|
519
|
-
| comments.test.js | list, create | 12 |
|
|
520
|
-
| users.test.js | list | 7 |
|
|
521
|
-
| search.test.js | search, post types, custom posts | 10 |
|
|
522
|
-
| seo.test.js | get, update, audit | 12 |
|
|
523
|
-
| plugins.test.js | list, activate, deactivate | 16 |
|
|
524
|
-
| themes.test.js | list, get | 8 |
|
|
525
|
-
| revisions.test.js | list, get, restore, delete | 17 |
|
|
526
|
-
|
|
|
727
|
+
|---|---|---|
|
|
728
|
+
| `governance.test.js` | All governance flags + combinations including `WP_REQUIRE_APPROVAL` and `WP_CONFIRM_DESTRUCTIVE` | 30 |
|
|
729
|
+
| `posts.test.js` | list, get, create, update, delete, search | 18 |
|
|
730
|
+
| `pages.test.js` | list, get, create, update | 12 |
|
|
731
|
+
| `media.test.js` | list, get, upload | 14 |
|
|
732
|
+
| `taxonomies.test.js` | categories, tags, create term | 16 |
|
|
733
|
+
| `comments.test.js` | list, create | 12 |
|
|
734
|
+
| `users.test.js` | list | 7 |
|
|
735
|
+
| `search.test.js` | search, post types, custom posts | 10 |
|
|
736
|
+
| `seo.test.js` | get, update, audit | 12 |
|
|
737
|
+
| `plugins.test.js` | list, activate, deactivate | 16 |
|
|
738
|
+
| `themes.test.js` | list, get | 8 |
|
|
739
|
+
| `revisions.test.js` | list, get, restore, delete | 17 |
|
|
740
|
+
| `editorial.test.js` | submit_for_review, approve, reject | 15 |
|
|
741
|
+
| `links.test.js` | analyze_links, suggest_internal_links | 16 |
|
|
742
|
+
| `woocommerce.test.js` | products, orders, customers, coupons, reports, write, guardrail | 40 |
|
|
743
|
+
| `auditMediaSeo.test.js` | media alt text audit, filename scoring | 12 |
|
|
744
|
+
| `findOrphanPages.test.js` | inbound link detection, exclusion list | 10 |
|
|
745
|
+
| `auditHeadingStructure.test.js` | H1/H2/H3 hierarchy, level skips, keyword detection | 12 |
|
|
746
|
+
| `findThinContent.test.js` | word count threshold, heading density | 10 |
|
|
747
|
+
| `auditCanonicals.test.js` | canonical validation, mismatch detection, multi-plugin | 12 |
|
|
748
|
+
| `analyzeEeatSignals.test.js` | E-E-A-T scoring, author bio, citations, structured data | 12 |
|
|
749
|
+
| `findBrokenInternalLinks.test.js` | HEAD request batching, 4xx/3xx detection | 12 |
|
|
750
|
+
| `findKeywordCannibalization.test.js` | focus keyword conflicts, multi-plugin detection | 10 |
|
|
751
|
+
| `auditTaxonomies.test.js` | Levenshtein duplicates, unused terms, over-tagging | 12 |
|
|
752
|
+
| `auditOutboundLinks.test.js` | external link profile, nofollow detection | 10 |
|
|
753
|
+
| `contentAnalyzer.test.js` | readability, TF-IDF, cosine similarity, entities, text diff | 44 |
|
|
754
|
+
| `contentIntelligence.test.js` | 16 content intelligence tools: brief, outline, readability, update frequency, link map, anchor texts, schema, structure, duplicates, gaps, FAQ, CTA, entities, velocity, revisions diff, word count | 125 |
|
|
755
|
+
| `site.test.js` | site info, set target | 5 |
|
|
756
|
+
| `transport/http.test.js` | HTTP transport, Bearer auth, sessions | 10 |
|
|
757
|
+
| `dxt/manifest.test.js` | MCPB manifest validation, 79 tools declared | 10 |
|
|
527
758
|
|
|
528
759
|
Each test verifies: success response shape, governance blocking (write tools), HTTP error handling (403/404), and audit log entries.
|
|
529
760
|
|
|
@@ -532,10 +763,9 @@ Each test verifies: success response shape, governance blocking (write tools), H
|
|
|
532
763
|
## Structured Audit Log
|
|
533
764
|
|
|
534
765
|
Every tool invocation is recorded as a JSON event on stderr — ready for ingestion into Datadog, Splunk, CloudWatch, Langfuse, ELK, or any JSON-compatible pipeline.
|
|
535
|
-
|
|
536
766
|
```json
|
|
537
767
|
{
|
|
538
|
-
"timestamp": "2026-02-
|
|
768
|
+
"timestamp": "2026-02-19T18:42:00.000Z",
|
|
539
769
|
"tool": "wp_create_post",
|
|
540
770
|
"target": 1234,
|
|
541
771
|
"target_type": "post",
|
|
@@ -548,20 +778,20 @@ Every tool invocation is recorded as a JSON event on stderr — ready for ingest
|
|
|
548
778
|
}
|
|
549
779
|
```
|
|
550
780
|
|
|
551
|
-
|
|
781
|
+
79 instrumentation points across all tools. Three status types: `success`, `error`, `blocked`.
|
|
552
782
|
|
|
553
783
|
| Field | Description |
|
|
554
|
-
|
|
555
|
-
| timestamp | ISO 8601 |
|
|
556
|
-
| tool | Tool name invoked |
|
|
557
|
-
| target | Resource ID when applicable |
|
|
558
|
-
| target_type | Resource type (post, page, media, comment, category, tag, plugin, theme, revision) |
|
|
559
|
-
| action | Operation: list, read, create, update, trash, permanent_delete, upload, search, switch_target, read_seo, update_seo, audit_seo, activate, deactivate, restore |
|
|
560
|
-
| status | success
|
|
561
|
-
| latency_ms | Execution time |
|
|
562
|
-
| site | Active target name |
|
|
563
|
-
| params | Sanitized parameters (content fields truncated) |
|
|
564
|
-
| error | Error detail or null |
|
|
784
|
+
|---|---|
|
|
785
|
+
| `timestamp` | ISO 8601 |
|
|
786
|
+
| `tool` | Tool name invoked |
|
|
787
|
+
| `target` | Resource ID when applicable |
|
|
788
|
+
| `target_type` | Resource type (post, page, media, comment, category, tag, plugin, theme, revision, product, order, customer, coupon) |
|
|
789
|
+
| `action` | Operation: list, read, create, update, trash, permanent_delete, upload, search, switch_target, read_seo, update_seo, audit_seo, activate, deactivate, restore, submit_review, approve, reject, analyze_links, suggest_links, guardrail, audit_media_seo, find_orphans, audit_headings, find_thin_content, audit_canonicals, analyze_eeat, find_broken_links, find_cannibalization, audit_taxonomies, audit_outbound_links, content_brief, extract_outline, audit_readability, audit_update_frequency, build_link_map, audit_anchor_texts, audit_schema, audit_content_structure, find_duplicates, find_content_gaps, extract_faq, audit_cta, extract_entities, publishing_velocity, compare_revisions, list_by_word_count |
|
|
790
|
+
| `status` | `success`, `error`, or `blocked` |
|
|
791
|
+
| `latency_ms` | Execution time |
|
|
792
|
+
| `site` | Active target name |
|
|
793
|
+
| `params` | Sanitized parameters (content fields truncated) |
|
|
794
|
+
| `error` | Error detail or null |
|
|
565
795
|
|
|
566
796
|
---
|
|
567
797
|
|
|
@@ -570,17 +800,14 @@ Every tool invocation is recorded as a JSON event on stderr — ready for ingest
|
|
|
570
800
|
Manage multiple WordPress sites from a single server instance. Designed for agencies and multi-brand organizations.
|
|
571
801
|
|
|
572
802
|
**Inline configuration:**
|
|
573
|
-
|
|
574
803
|
```bash
|
|
575
804
|
WP_TARGETS_JSON='{"production":{"url":"https://mysite.com","username":"admin","password":"xxxx"},"staging":{"url":"https://staging.mysite.com","username":"editor","password":"xxxx"}}'
|
|
576
805
|
```
|
|
577
806
|
|
|
578
807
|
**File-based configuration:**
|
|
579
|
-
|
|
580
808
|
```bash
|
|
581
809
|
WP_TARGETS_FILE=/path/to/targets.json
|
|
582
810
|
```
|
|
583
|
-
|
|
584
811
|
```json
|
|
585
812
|
{
|
|
586
813
|
"production": {
|
|
@@ -610,46 +837,55 @@ Switch targets during a session with `wp_set_target`. All available sites and th
|
|
|
610
837
|
The server performs a health check on startup: REST API connectivity, user authentication, and role verification. During operation: automatic retry with exponential backoff (configurable, default 3 attempts), request timeout (default 30s), rate limit handling (respects 429 + retry-after), and contextual error messages with diagnosis guidance.
|
|
611
838
|
|
|
612
839
|
| Setting | Default | Description |
|
|
613
|
-
|
|
614
|
-
| WP_MCP_VERBOSE | false | Debug-level logging |
|
|
615
|
-
| WP_MCP_TIMEOUT | 30000 | Request timeout (ms) |
|
|
616
|
-
| WP_MCP_MAX_RETRIES | 3 | Max retry attempts |
|
|
840
|
+
|---|---|---|
|
|
841
|
+
| `WP_MCP_VERBOSE` | `false` | Debug-level logging |
|
|
842
|
+
| `WP_MCP_TIMEOUT` | `30000` | Request timeout (ms) |
|
|
843
|
+
| `WP_MCP_MAX_RETRIES` | `3` | Max retry attempts |
|
|
617
844
|
|
|
618
845
|
---
|
|
619
846
|
|
|
620
847
|
## Security
|
|
621
848
|
|
|
622
|
-
-
|
|
623
|
-
-
|
|
624
|
-
-
|
|
625
|
-
-
|
|
626
|
-
-
|
|
627
|
-
-
|
|
849
|
+
- HTTPS required in production. HTTP only for localhost
|
|
850
|
+
- Application Passwords only — never use WordPress login credentials
|
|
851
|
+
- Credentials never logged — audit trail sanitizes all sensitive data
|
|
852
|
+
- No credentials in code — `.env` or environment variables only
|
|
853
|
+
- Instant revocation — Application Passwords can be revoked from WordPress admin
|
|
854
|
+
- Traceable requests — custom `User-Agent: WordPress-MCP-Server/4.4.0`
|
|
855
|
+
- Bearer token auth in HTTP mode — timing-safe comparison, no token in logs
|
|
856
|
+
- Origin validation in HTTP mode — anti-DNS-rebinding protection
|
|
628
857
|
|
|
629
858
|
---
|
|
630
859
|
|
|
631
860
|
## Troubleshooting
|
|
632
861
|
|
|
633
862
|
| Issue | Solution |
|
|
634
|
-
|
|
635
|
-
| 401 Unauthorized | Verify username and Application Password |
|
|
636
|
-
| 403 Forbidden | Check WordPress user role and capabilities |
|
|
637
|
-
| 404 Not Found | Verify WP_API_URL and REST API availability |
|
|
638
|
-
| Unexpected token '<' | Stray character before `<?php` in functions.php — see
|
|
639
|
-
| Blocked: READ-ONLY mode | Disable WP_READ_ONLY to allow writes |
|
|
640
|
-
| Blocked: DRAFT-ONLY mode | Only draft/pending allowed. Check WP_DRAFT_ONLY |
|
|
641
|
-
| Blocked: PLUGIN MANAGEMENT | Disable WP_DISABLE_PLUGIN_MANAGEMENT to allow activate/deactivate |
|
|
642
|
-
|
|
|
643
|
-
|
|
|
644
|
-
|
|
|
863
|
+
|---|---|
|
|
864
|
+
| `401 Unauthorized` | Verify username and Application Password |
|
|
865
|
+
| `403 Forbidden` | Check WordPress user role and capabilities |
|
|
866
|
+
| `404 Not Found` | Verify `WP_API_URL` and REST API availability |
|
|
867
|
+
| `Unexpected token '<'` | Stray character before `<?php` in `functions.php` — see SEO Troubleshooting |
|
|
868
|
+
| `Blocked: READ-ONLY mode` | Disable `WP_READ_ONLY` to allow writes |
|
|
869
|
+
| `Blocked: DRAFT-ONLY mode` | Only draft/pending allowed. Check `WP_DRAFT_ONLY` |
|
|
870
|
+
| `Blocked: PLUGIN MANAGEMENT` | Disable `WP_DISABLE_PLUGIN_MANAGEMENT` to allow activate/deactivate |
|
|
871
|
+
| `Blocked: APPROVAL REQUIRED` | `WP_REQUIRE_APPROVAL=true` — use `wp_submit_for_review` then `wp_approve_post` |
|
|
872
|
+
| Confirmation token required | `WP_CONFIRM_DESTRUCTIVE=true` — pass the returned token on a second call within 60s |
|
|
873
|
+
| `401 Unauthorized (HTTP mode)` | Set `MCP_AUTH_TOKEN` and pass `Authorization: Bearer <token>` |
|
|
874
|
+
| `403 Forbidden (HTTP mode)` | Check `MCP_ALLOWED_ORIGINS` includes your client origin |
|
|
875
|
+
| WooCommerce 401 | Verify `WC_CONSUMER_KEY` and `WC_CONSUMER_SECRET` |
|
|
876
|
+
| WooCommerce 403 | API key needs Read/Write permissions for write tools |
|
|
877
|
+
| Rate limit exceeded | Adjust `WP_MAX_CALLS_PER_MINUTE` |
|
|
878
|
+
| Timeout | Increase `WP_MCP_TIMEOUT` or check server |
|
|
879
|
+
| Site not found | Verify site key in `WP_TARGETS_JSON` or file |
|
|
645
880
|
| No SEO plugin detected | Install Yoast, RankMath, SEOPress, or AIOSEO |
|
|
646
|
-
| SEO meta fields empty | Add register_post_meta() code or install MCP SEO Bridge plugin — see
|
|
881
|
+
| SEO meta fields empty | Add `register_post_meta()` code or install MCP SEO Bridge plugin — see Exposing SEO Meta Fields |
|
|
882
|
+
| `wp_find_broken_internal_links` slow | Reduce `batchSize` parameter or increase `timeoutMs` |
|
|
883
|
+
| `wp_audit_outbound_links` empty | External HEAD requests blocked by your server firewall |
|
|
647
884
|
| Server not starting | Check Node.js 18+ is installed: `node --version` |
|
|
648
885
|
|
|
649
886
|
---
|
|
650
887
|
|
|
651
888
|
## Development
|
|
652
|
-
|
|
653
889
|
```bash
|
|
654
890
|
# Clone the repository
|
|
655
891
|
git clone https://github.com/GeorgesAdSim/wordpress-mcp-server.git
|
|
@@ -661,15 +897,25 @@ npm install
|
|
|
661
897
|
# Run tests
|
|
662
898
|
npm test
|
|
663
899
|
|
|
664
|
-
# Run locally
|
|
900
|
+
# Run locally (stdio)
|
|
665
901
|
WP_API_URL="https://your-site.com" \
|
|
666
902
|
WP_API_USERNAME="user" \
|
|
667
903
|
WP_API_PASSWORD="xxxx xxxx xxxx xxxx" \
|
|
668
904
|
node index.js
|
|
905
|
+
|
|
906
|
+
# Run locally (HTTP)
|
|
907
|
+
MCP_TRANSPORT=http \
|
|
908
|
+
MCP_AUTH_TOKEN=dev-token \
|
|
909
|
+
WP_API_URL="https://your-site.com" \
|
|
910
|
+
WP_API_USERNAME="user" \
|
|
911
|
+
WP_API_PASSWORD="xxxx xxxx xxxx xxxx" \
|
|
912
|
+
node index.js
|
|
913
|
+
|
|
914
|
+
# Build MCPB bundle
|
|
915
|
+
npm run build:mcpb
|
|
669
916
|
```
|
|
670
917
|
|
|
671
918
|
### Testing with MCP Inspector
|
|
672
|
-
|
|
673
919
|
```bash
|
|
674
920
|
npx @modelcontextprotocol/inspector node index.js
|
|
675
921
|
```
|
|
@@ -678,15 +924,137 @@ npx @modelcontextprotocol/inspector node index.js
|
|
|
678
924
|
|
|
679
925
|
## Changelog
|
|
680
926
|
|
|
927
|
+
### v4.4.0 (2026-02-21) — Content Intelligence
|
|
928
|
+
|
|
929
|
+
16 new read-only analysis tools for deep content intelligence without any WordPress plugin.
|
|
930
|
+
|
|
931
|
+
**Foundations:**
|
|
932
|
+
- `src/contentAnalyzer.js` — shared analysis engine: readability (Flesch-Kincaid FR), TF-IDF, cosine similarity, entity extraction, text diff, content structure detection
|
|
933
|
+
- `wp_get_content_brief` — editorial brief aggregator (SEO + structure + links in 1 call)
|
|
934
|
+
- `wp_extract_post_outline` — H1-H6 outline extraction with category-level pattern analysis
|
|
935
|
+
|
|
936
|
+
**SEO Advanced:**
|
|
937
|
+
- `wp_audit_readability` — bulk Flesch-Kincaid FR scoring with transition word and passive voice analysis
|
|
938
|
+
- `wp_audit_update_frequency` — outdated content detection cross-referenced with SEO scores
|
|
939
|
+
- `wp_build_link_map` — internal link matrix with simplified PageRank scoring (0-100)
|
|
940
|
+
|
|
941
|
+
**Technical Quality:**
|
|
942
|
+
- `wp_audit_anchor_texts` — anchor text diversity audit: generic, over-optimized, image link detection
|
|
943
|
+
- `wp_audit_schema_markup` — JSON-LD schema.org detection and validation (Article, FAQ, HowTo, LocalBusiness)
|
|
944
|
+
- `wp_audit_content_structure` — editorial structure scoring (0-100): intro, conclusion, FAQ, TOC, lists, images
|
|
945
|
+
|
|
946
|
+
**Intelligence Advanced:**
|
|
947
|
+
- `wp_find_duplicate_content` — TF-IDF cosine similarity for near-duplicate detection with union-find clustering
|
|
948
|
+
- `wp_find_content_gaps` — taxonomy under-representation analysis (categories + tags)
|
|
949
|
+
- `wp_extract_faq_blocks` — FAQ inventory: JSON-LD, Gutenberg blocks, HTML patterns
|
|
950
|
+
- `wp_audit_cta_presence` — CTA detection (6 types) with scoring 0-100
|
|
951
|
+
- `wp_extract_entities` — regex/heuristic named entity extraction (brands, locations, persons, organizations)
|
|
952
|
+
- `wp_get_publishing_velocity` — publication cadence by author/category with trend detection
|
|
953
|
+
- `wp_compare_revisions_diff` — textual diff between revisions with amplitude scoring
|
|
954
|
+
- `wp_list_posts_by_word_count` — posts sorted by length with 6-tier segmentation
|
|
955
|
+
|
|
956
|
+
All Content Intelligence tools are read-only and always allowed regardless of governance flags.
|
|
957
|
+
|
|
958
|
+
613 Vitest unit tests · 79 tools
|
|
959
|
+
|
|
960
|
+
### v4.2.0 (2026-02-19) — SEO Audit Suite (Sprint 3)
|
|
961
|
+
|
|
962
|
+
- `wp_find_broken_internal_links` — HEAD request link checker with configurable batch size and timeout. Returns broken (4xx/5xx), redirected (3xx), and slow links
|
|
963
|
+
- `wp_find_keyword_cannibalization` — detect posts sharing the same focus keyword. Auto-detects RankMath/Yoast/SEOPress/AIOSEO. Groups conflicts by keyword, flags weakest post by word count
|
|
964
|
+
- `wp_audit_taxonomies` — taxonomy bloat detection: unused terms, near-duplicate detection via Levenshtein distance, single-post terms, over-tagged posts
|
|
965
|
+
- `wp_audit_outbound_links` — external link profile per post: low-authority domains, missing rel="nofollow", broken external URLs
|
|
966
|
+
- `src/htmlParser.js` — shared HTML parsing service (parseImagesFromHtml, extractHeadings, extractInternalLinks, countWords)
|
|
967
|
+
- 400 Vitest unit tests · 63 tools
|
|
968
|
+
|
|
969
|
+
### v4.1.0 (2026-02-19) — SEO Audit Suite (Sprint 2)
|
|
970
|
+
|
|
971
|
+
- `wp_find_thin_content` — surface posts below configurable word count threshold. Scores content quality by word count, heading density, and paragraph structure
|
|
972
|
+
- `wp_audit_canonicals` — validate canonical URLs across posts and pages. Detects missing canonicals, self-referencing mismatches, cross-domain canonicals. Auto-detects RankMath/Yoast/SEOPress/AIOSEO
|
|
973
|
+
- `wp_analyze_eeat_signals` — E-E-A-T scoring per post (0-100): author bio presence, publication/update dates, outbound citations, word count, structured data markers
|
|
974
|
+
- 368 Vitest unit tests · 59 tools
|
|
975
|
+
|
|
976
|
+
### v4.0.0 (2026-02-19) — SEO Audit Suite (Sprint 1)
|
|
977
|
+
|
|
978
|
+
- `wp_audit_media_seo` — audit media library for missing alt text, short alt text, unoptimized filenames. Returns per-image scores and prioritized fix list
|
|
979
|
+
- `wp_find_orphan_pages` — identify posts with no internal links pointing to them, sorted by word count. Configurable minimum word threshold and exclusion list
|
|
980
|
+
- `wp_audit_heading_structure` — analyze H1/H2/H3 hierarchy in post content. Detects H1 in body, heading level skips, empty headings, focus keyword absent from H2
|
|
981
|
+
- All 10 SEO audit tools are read-only and always allowed regardless of governance flags
|
|
982
|
+
- 340 Vitest unit tests · 56 tools
|
|
983
|
+
|
|
984
|
+
### v3.6.0 (2026-02-19) — WooCommerce Write
|
|
985
|
+
|
|
986
|
+
- `wc_update_product` — update product fields (title, description, price, stock, status). Integrated with `wc_price_guardrail` threshold enforcement
|
|
987
|
+
- `wc_update_order_status` — transition order status (e.g., processing → completed)
|
|
988
|
+
- `WC_PRICE_GUARDRAIL_THRESHOLD` — configurable price change safety threshold (default 20%)
|
|
989
|
+
- All WooCommerce write tools blocked by `WP_READ_ONLY`
|
|
990
|
+
- 305 Vitest unit tests · 53 tools
|
|
991
|
+
|
|
992
|
+
### v3.5.0 (2026-02-19) — WooCommerce Intelligence
|
|
993
|
+
|
|
994
|
+
- `wc_get_customer` — customer profile with order history summary and lifetime value
|
|
995
|
+
- `wc_list_coupons` / `wc_get_coupon` — coupon management with discount rules and usage stats
|
|
996
|
+
- `wc_sales_report` — revenue, orders, and average order value for a date range
|
|
997
|
+
- `wc_top_products` — ranking by revenue, quantity sold, or order count
|
|
998
|
+
- 287 Vitest unit tests · 50 tools
|
|
999
|
+
|
|
1000
|
+
### v3.4.0 (2026-02-19) — WooCommerce Core
|
|
1001
|
+
|
|
1002
|
+
- `wc_list_products` / `wc_get_product` — product catalog with variation support
|
|
1003
|
+
- `wc_list_orders` / `wc_get_order` — order management with full line item detail
|
|
1004
|
+
- `wc_list_customers` — customer list with search and role filtering
|
|
1005
|
+
- `wc_price_guardrail` — read-only price change safety analysis
|
|
1006
|
+
- Requires `WC_CONSUMER_KEY` and `WC_CONSUMER_SECRET`
|
|
1007
|
+
- 271 Vitest unit tests · 46 tools
|
|
1008
|
+
|
|
1009
|
+
### v3.3.0 (2026-02-19) — Internal Link Intelligence
|
|
1010
|
+
|
|
1011
|
+
- `wp_analyze_links` — audit all internal/external links in a post. HEAD request verification per link (broken/warning/unknown). Max 20 checks, configurable timeout
|
|
1012
|
+
- `wp_suggest_internal_links` — semantic link suggestions scored by category match (+3), freshness (+3/2/1), SEO focus keyword match (+2), title match (+2). Excludes already-linked posts
|
|
1013
|
+
- `src/linkUtils.js` — 6 shared utilities: extractInternalLinks, extractExternalLinks, checkLinkStatus, extractFocusKeyword (auto-detects RankMath/Yoast/SEOPress/AIOSEO), calculateRelevanceScore, suggestAnchorText
|
|
1014
|
+
- Pre-flight linking workflow: suggest → user validates → `wp_update_post` (never auto-insert)
|
|
1015
|
+
- 253 Vitest unit tests · 40 tools
|
|
1016
|
+
|
|
1017
|
+
### v3.2.0 (2026-02-19) — Governance Workflows
|
|
1018
|
+
|
|
1019
|
+
- Editorial approval workflow: `wp_submit_for_review` (draft → pending), `wp_approve_post` (pending → publish), `wp_reject_post` (pending → draft + mandatory reason)
|
|
1020
|
+
- New governance flag: `WP_REQUIRE_APPROVAL` — blocks direct publish, forces approval workflow
|
|
1021
|
+
- Two-step confirmation for destructive operations: `wp_delete_post` and `wp_delete_revision` return a stateless token (60s TTL, SHA-256) when `WP_CONFIRM_DESTRUCTIVE=true`
|
|
1022
|
+
- New governance flag: `WP_CONFIRM_DESTRUCTIVE` — requires explicit token confirmation before any delete
|
|
1023
|
+
- `src/confirmationToken.js` — stateless token system, zero persistence
|
|
1024
|
+
- Governance priority: `WP_READ_ONLY` → `WP_DISABLE_DELETE` → `WP_CONFIRM_DESTRUCTIVE`
|
|
1025
|
+
- 225 Vitest unit tests · 38 tools
|
|
1026
|
+
|
|
1027
|
+
### v3.1.0 (2026-02-19) — MCPB Bundle
|
|
1028
|
+
|
|
1029
|
+
- `dxt/manifest.json` — MCPB v0.3 spec, 35 tools declared
|
|
1030
|
+
- WordPress credentials stored in OS keychain (`sensitive: true`)
|
|
1031
|
+
- `npm run build:mcpb` — build script for `.mcpb` distribution
|
|
1032
|
+
- 10 new manifest validation tests (201 total)
|
|
1033
|
+
- Published to npm: `npx -y @adsim/wordpress-mcp-server@3.1.0`
|
|
1034
|
+
|
|
1035
|
+
### v3.0.0 (2026-02-19) — HTTP Streamable Transport
|
|
1036
|
+
|
|
1037
|
+
- HTTP Streamable transport (MCP spec 2025-03-26) via `MCP_TRANSPORT=http`
|
|
1038
|
+
- Bearer token authentication with timing-safe comparison (`MCP_AUTH_TOKEN`)
|
|
1039
|
+
- Session management via `Mcp-Session-Id` header (UUID v4)
|
|
1040
|
+
- Origin header validation (anti-DNS-rebinding)
|
|
1041
|
+
- Health endpoint `GET /health`
|
|
1042
|
+
- Dual mode `MCP_DUAL_MODE=true` — stdio + HTTP simultaneously
|
|
1043
|
+
- Graceful shutdown SIGTERM/SIGINT across both transports
|
|
1044
|
+
- 10 new HTTP/auth unit tests (191 total)
|
|
1045
|
+
- Published to npm: `@adsim/wordpress-mcp-server`
|
|
1046
|
+
|
|
681
1047
|
### v2.2.0 (2026-02-19) — Enterprise Edition
|
|
682
|
-
|
|
683
|
-
-
|
|
684
|
-
-
|
|
685
|
-
-
|
|
1048
|
+
|
|
1049
|
+
- 9 new tools: plugins (list/activate/deactivate), themes (list/get), revisions (list/get/restore/delete)
|
|
1050
|
+
- New governance flag: `WP_DISABLE_PLUGIN_MANAGEMENT`
|
|
1051
|
+
- 171 Vitest unit tests covering all 35 tools (governance, success, 403/404, audit logs)
|
|
1052
|
+
- GitHub Actions CI workflow
|
|
686
1053
|
- Governance functions read env at call time for testability
|
|
687
1054
|
- Exported `handleToolCall` for direct testing
|
|
688
1055
|
|
|
689
1056
|
### v2.1.0 (2026-02-16)
|
|
1057
|
+
|
|
690
1058
|
- Enterprise governance controls (read-only, draft-only, type/status allowlists)
|
|
691
1059
|
- Structured JSON audit trail (27 instrumentation points)
|
|
692
1060
|
- Multi-target site management
|
|
@@ -695,26 +1063,25 @@ npx @modelcontextprotocol/inspector node index.js
|
|
|
695
1063
|
- Health checks, retry with backoff, rate limiting
|
|
696
1064
|
|
|
697
1065
|
### v1.0.0 (2025-10-17)
|
|
1066
|
+
|
|
698
1067
|
- Initial release — JavaScript, 5 tools (list, get, create, update, search posts)
|
|
699
1068
|
|
|
700
1069
|
---
|
|
701
1070
|
|
|
702
1071
|
## Roadmap
|
|
703
1072
|
|
|
704
|
-
###
|
|
705
|
-
-
|
|
706
|
-
-
|
|
707
|
-
-
|
|
1073
|
+
### v4.5 — GSC Integration
|
|
1074
|
+
- `wp_get_gsc_performance` — Google Search Console API (clicks, impressions, position, CTR per URL)
|
|
1075
|
+
- `wp_find_quick_win_keywords` — surface keywords ranking positions 11–20 for targeted updates
|
|
1076
|
+
- `wp_seo_content_decay` — cross-reference GSC traffic loss with content age to prioritize refresh candidates
|
|
708
1077
|
|
|
709
|
-
###
|
|
710
|
-
-
|
|
711
|
-
-
|
|
712
|
-
- Media management (bulk, transforms)
|
|
1078
|
+
### v4.6 — Redirect Intelligence
|
|
1079
|
+
- `wp_create_redirect` — create 301 redirects via Redirection plugin or RankMath/Yoast Redirects. Auto-triggered governance hook when `wp_update_post` changes a slug
|
|
1080
|
+
- `wp_list_404_errors` — surface recent 404s from Redirection plugin log
|
|
713
1081
|
|
|
714
|
-
###
|
|
715
|
-
-
|
|
1082
|
+
### v4.7 — OAuth & Registry
|
|
1083
|
+
- OAuth 2.0 / JWT authentication
|
|
716
1084
|
- MCP Registry submission
|
|
717
|
-
- TypeScript rewrite
|
|
718
1085
|
|
|
719
1086
|
---
|
|
720
1087
|
|