@respira/wordpress-mcp-server 8.3.18 → 8.3.19
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/CHANGELOG.md +39 -0
- package/dist/__tests__/upload-media-path-detection.test.js +35 -1
- package/dist/__tests__/upload-media-path-detection.test.js.map +1 -1
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +29 -1
- package/dist/server.js.map +1 -1
- package/dist/wordpress-client.d.ts +31 -0
- package/dist/wordpress-client.d.ts.map +1 -1
- package/dist/wordpress-client.js +82 -3
- package/dist/wordpress-client.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,45 @@ All notable changes to Respira WordPress MCP Server will be documented in this f
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [8.3.19] - 2026-09-04
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Uploading a JPEG never worked.** `upload_media` decided whether the `file`
|
|
13
|
+
argument was a filesystem path by testing whether it started with `/`. Base64 of a
|
|
14
|
+
JPEG's opening bytes is `/9j/`, so every bare base64 JPEG matched that test, was
|
|
15
|
+
treated as an absolute path, and failed with "File not found: /9j/...". Nothing
|
|
16
|
+
ever reached WordPress. The existing test missed it because its sample payload
|
|
17
|
+
happened to start with a letter.
|
|
18
|
+
- **A failed upload hung for minutes instead of retrying.** The multipart body was a
|
|
19
|
+
single-use stream, and both retry paths (the 5xx idempotency retry and the
|
|
20
|
+
`?rest_route=` fallback) re-sent the already-consumed stream with the original
|
|
21
|
+
`Content-Length`. The request promised bytes it then never wrote, so it never
|
|
22
|
+
reached the server and sat until the socket timed out. Measured at 88 seconds for
|
|
23
|
+
one call, with only the first attempt ever delivered. The body is now replayable
|
|
24
|
+
and no streaming body is re-sent.
|
|
25
|
+
- **The `?rest_route=` upload fallback had never worked.** It inherited the same
|
|
26
|
+
exhausted stream, so the fallback reported that the host "also returned HTML"
|
|
27
|
+
without having sent anything.
|
|
28
|
+
- **One bad upload could take the whole server down.** Error responses skipped the
|
|
29
|
+
size cap that success responses go through, so a failed upload echoed the entire
|
|
30
|
+
base64 payload back inside the error message. A 900 KB image produced a 1.2 MB
|
|
31
|
+
JSON-RPC frame against a 100 KiB cap, and an oversized frame makes MCP hosts kill
|
|
32
|
+
the subprocess, which is why every later tool call timed out until a restart. Error
|
|
33
|
+
messages are now truncated.
|
|
34
|
+
- The tool description advertised a 120 second upload timeout; the actual default has
|
|
35
|
+
been 90 seconds since 6.18.4. Corrected.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- `mcp-bundle/build.sh` now packs the local `mcp-server` when its version matches the
|
|
40
|
+
bundle's pin, instead of always resolving from the npm registry. The registry path
|
|
41
|
+
remains as the fallback. The bundle could previously only be built after publishing,
|
|
42
|
+
while the release workflow's parity gate runs before publishing and requires the
|
|
43
|
+
built bundle to already carry the version being released, so a release was
|
|
44
|
+
unsatisfiable on the first attempt at any version. It also means the bundle is now
|
|
45
|
+
reproducible from the tag rather than dependent on registry state.
|
|
46
|
+
|
|
8
47
|
## [8.3.18] - 2026-09-03
|
|
9
48
|
|
|
10
49
|
### Fixed
|
|
@@ -4,7 +4,7 @@ import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
|
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
|
-
import { isLocalFilePath, resolveLocalFilePath } from '../wordpress-client.js';
|
|
7
|
+
import { isLocalFilePath, looksLikeBase64Payload, resolveLocalFilePath } from '../wordpress-client.js';
|
|
8
8
|
// Ticket 5a19d816: on Windows, respira_upload_media(file="C:/Users/.../photo.jpg")
|
|
9
9
|
// fell through the local-file detection (which only matched '/', './', '../',
|
|
10
10
|
// '~') into the base64 branch. Buffer.from(nonBase64, 'base64') doesn't throw,
|
|
@@ -33,6 +33,40 @@ test('isLocalFilePath: base64 payloads and data:/http(s): URLs are still NOT tre
|
|
|
33
33
|
assert.equal(isLocalFilePath('http://example.com/photo.jpg'), false);
|
|
34
34
|
assert.equal(isLocalFilePath('https://example.com/photo.jpg'), false);
|
|
35
35
|
});
|
|
36
|
+
// Ticket 7c1cd8ac: every JPEG begins with the bytes FF D8 FF, which base64-encode
|
|
37
|
+
// to the four characters "/9j/". So a bare base64 JPEG always starts with a
|
|
38
|
+
// slash and was matched by the POSIX-absolute arm, sending the upload down the
|
|
39
|
+
// local-file branch. It never reached WordPress: it died with
|
|
40
|
+
// "File not found: <the whole payload>", which then echoed the entire image
|
|
41
|
+
// back to the agent inside the error message. The pre-existing base64 case in
|
|
42
|
+
// this file missed it only because its sample blob starts with a letter.
|
|
43
|
+
function base64JpegOfLength(bytes) {
|
|
44
|
+
const buf = Buffer.alloc(bytes);
|
|
45
|
+
buf[0] = 0xff;
|
|
46
|
+
buf[1] = 0xd8;
|
|
47
|
+
buf[2] = 0xff;
|
|
48
|
+
buf[3] = 0xe0;
|
|
49
|
+
for (let i = 4; i < bytes; i++)
|
|
50
|
+
buf[i] = (i * 37) & 0xff;
|
|
51
|
+
return buf.toString('base64');
|
|
52
|
+
}
|
|
53
|
+
test('isLocalFilePath: a bare base64 JPEG is a payload, not a path (starts with "/9j/")', () => {
|
|
54
|
+
const jpeg = base64JpegOfLength(7500);
|
|
55
|
+
assert.equal(jpeg.startsWith('/9j/'), true, 'precondition: JPEG base64 starts with /9j/');
|
|
56
|
+
assert.equal(isLocalFilePath(jpeg), false);
|
|
57
|
+
assert.equal(looksLikeBase64Payload(jpeg), true);
|
|
58
|
+
});
|
|
59
|
+
test('looksLikeBase64Payload: real paths are never mistaken for a payload', () => {
|
|
60
|
+
const longPosix = '/home/user/' + 'directory/'.repeat(40) + 'photo.jpg';
|
|
61
|
+
assert.equal(looksLikeBase64Payload(longPosix), false);
|
|
62
|
+
assert.equal(isLocalFilePath(longPosix), true);
|
|
63
|
+
// No extension, no dots, long: still excluded by the character-mix rule.
|
|
64
|
+
const noExtension = '/home/user/' + 'directory/'.repeat(40) + 'photo';
|
|
65
|
+
assert.equal(looksLikeBase64Payload(noExtension), false);
|
|
66
|
+
assert.equal(isLocalFilePath(noExtension), true);
|
|
67
|
+
// Short blobs stay conservative: not long enough to claim they are a payload.
|
|
68
|
+
assert.equal(looksLikeBase64Payload('/9j/4AAQSkZJRg=='), false);
|
|
69
|
+
});
|
|
36
70
|
test('resolveLocalFilePath: Windows drive-letter paths pass through unchanged (no cwd corruption)', () => {
|
|
37
71
|
// Regression guard: node:path's resolve() is POSIX on non-Windows hosts and
|
|
38
72
|
// does not recognize "C:\..." as absolute, so running it through resolve()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-media-path-detection.test.js","sourceRoot":"","sources":["../../src/__tests__/upload-media-path-detection.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"upload-media-path-detection.test.js","sourceRoot":"","sources":["../../src/__tests__/upload-media-path-detection.test.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ export declare function pickActiveSiteIdForConfig(state: RespiraMcpState, namesp
|
|
|
36
36
|
* versions and the migration path above both stay correct.
|
|
37
37
|
*/
|
|
38
38
|
export declare function applyActiveSiteIdForConfig(state: RespiraMcpState, namespace: string, siteId: string): RespiraMcpState;
|
|
39
|
+
/**
|
|
40
|
+
* Hard ceiling on the text of an error response, so no single tool failure can
|
|
41
|
+
* push an oversized JSON-RPC frame at the host. Middle-truncated: the head
|
|
42
|
+
* carries the reason, the tail carries whatever hint the thrower appended.
|
|
43
|
+
* Override with RESPIRA_MAX_ERROR_MESSAGE_CHARS (0 disables).
|
|
44
|
+
*/
|
|
45
|
+
export declare function truncateErrorMessage(message: string): string;
|
|
39
46
|
/**
|
|
40
47
|
* v7.2.1: hoist plugin-side dropped-styling warnings to the TOP of a build
|
|
41
48
|
* write result so the agent sees them before it inspects anything else.
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;AAwCzE,MAAM,MAAM,eAAe,GAAG;IAC5B,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAkBf;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,eAAe,CAUjB;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -183,6 +183,22 @@ class ToolTimeoutError extends Error {
|
|
|
183
183
|
this.name = 'ToolTimeoutError';
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Hard ceiling on the text of an error response, so no single tool failure can
|
|
188
|
+
* push an oversized JSON-RPC frame at the host. Middle-truncated: the head
|
|
189
|
+
* carries the reason, the tail carries whatever hint the thrower appended.
|
|
190
|
+
* Override with RESPIRA_MAX_ERROR_MESSAGE_CHARS (0 disables).
|
|
191
|
+
*/
|
|
192
|
+
export function truncateErrorMessage(message) {
|
|
193
|
+
const override = parseInt(process.env.RESPIRA_MAX_ERROR_MESSAGE_CHARS || '', 10);
|
|
194
|
+
const cap = Number.isFinite(override) && override >= 0 ? override : 4000;
|
|
195
|
+
if (cap === 0 || message.length <= cap)
|
|
196
|
+
return message;
|
|
197
|
+
const head = message.slice(0, Math.floor(cap * 0.75));
|
|
198
|
+
const tail = message.slice(-Math.floor(cap * 0.25));
|
|
199
|
+
return `${head}\n\n[... ${message.length - cap} characters of this error message omitted. ` +
|
|
200
|
+
`The full value was most likely an argument echoed back verbatim; it is not needed to act on the error. ...]\n\n${tail}`;
|
|
201
|
+
}
|
|
186
202
|
function getMaxToolTimeoutMs() {
|
|
187
203
|
return Math.max(5000, parseInt(process.env.RESPIRA_MAX_TOOL_TIMEOUT_MS || '120000', 10));
|
|
188
204
|
}
|
|
@@ -2023,6 +2039,18 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
2023
2039
|
}
|
|
2024
2040
|
}
|
|
2025
2041
|
}
|
|
2042
|
+
// Ticket 7c1cd8ac. capResponseSize() guards the SUCCESS path only, so
|
|
2043
|
+
// every error envelope left this server uncapped. A single
|
|
2044
|
+
// respira_upload_media call whose payload was echoed back inside the
|
|
2045
|
+
// message ("File not found: <the whole base64 image>") produced a
|
|
2046
|
+
// 1.2 MB JSON-RPC frame in testing, against a 100 KiB cap that exists
|
|
2047
|
+
// precisely because MCP hosts stop reading — and then answer nothing
|
|
2048
|
+
// else on that connection — when one frame is too large. That is the
|
|
2049
|
+
// "every later tool call times out until I restart the server" half of
|
|
2050
|
+
// this ticket. An error message has no business being longer than a
|
|
2051
|
+
// paragraph; truncate in the middle so both the reason and any trailing
|
|
2052
|
+
// hint survive.
|
|
2053
|
+
errorMessage = truncateErrorMessage(errorMessage);
|
|
2026
2054
|
const errorWithUpdateNotice = await this.appendUpdateNoticeToError(errorMessage);
|
|
2027
2055
|
const activeSite = this.getActiveSiteSummary(args);
|
|
2028
2056
|
// B-17 (v6.18.7): gate the JS stack trace behind RESPIRA_DEBUG.
|
|
@@ -3091,7 +3119,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
3091
3119
|
},
|
|
3092
3120
|
{
|
|
3093
3121
|
name: 'wordpress_upload_media',
|
|
3094
|
-
description: 'Upload a media file (image, document, video) to WordPress. Supports base64 encoded files, file URLs, file paths, or raw SVG markup strings (starting with <svg or <?xml). Fails fast with a clear error if the file exceeds 50MB (override via RESPIRA_MAX_UPLOAD_MB) or the upload does not complete within
|
|
3122
|
+
description: 'Upload a media file (image, document, video) to WordPress. Supports base64 encoded files, file URLs, file paths, or raw SVG markup strings (starting with <svg or <?xml). Fails fast with a clear error if the file exceeds 50MB (override via RESPIRA_MAX_UPLOAD_MB) or the upload does not complete within 90 seconds (override via RESPIRA_UPLOAD_TIMEOUT_MS).',
|
|
3095
3123
|
inputSchema: {
|
|
3096
3124
|
type: 'object',
|
|
3097
3125
|
properties: {
|