@mindstone/mcp-server-elevenlabs 0.3.0 → 0.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 +30 -7
- package/dist/bridge.d.ts +1 -0
- package/dist/client.d.ts +34 -3
- package/dist/client.js +68 -14
- package/dist/endpoints.d.ts +34 -0
- package/dist/endpoints.js +37 -0
- package/dist/error-detail.d.ts +5 -0
- package/dist/error-detail.js +20 -0
- package/dist/server.js +9 -1
- package/dist/tools/account.d.ts +3 -0
- package/dist/tools/account.js +105 -0
- package/dist/tools/alignment.d.ts +3 -0
- package/dist/tools/alignment.js +55 -0
- package/dist/tools/audio-isolation.d.ts +3 -0
- package/dist/tools/audio-isolation.js +51 -0
- package/dist/tools/configure.js +18 -6
- package/dist/tools/dialogue.d.ts +3 -0
- package/dist/tools/dialogue.js +70 -0
- package/dist/tools/dubbing.d.ts +3 -0
- package/dist/tools/dubbing.js +234 -0
- package/dist/tools/file-input.d.ts +28 -0
- package/dist/tools/file-input.js +77 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/music.js +85 -25
- package/dist/tools/path-safety.d.ts +1 -0
- package/dist/tools/path-safety.js +4 -1
- package/dist/tools/speech.js +57 -24
- package/dist/tools/transcription.js +27 -61
- package/dist/tools/voice-changer.d.ts +3 -0
- package/dist/tools/voice-changer.js +62 -0
- package/dist/tools/voice-clone.d.ts +3 -0
- package/dist/tools/voice-clone.js +104 -0
- package/dist/tools/voice-design.d.ts +3 -0
- package/dist/tools/voice-design.js +153 -0
- package/dist/tools/voices.js +167 -13
- package/dist/types.d.ts +91 -0
- package/dist/types.js +20 -4
- package/dist/untrusted-content.d.ts +45 -0
- package/dist/untrusted-content.js +104 -0
- package/package.json +2 -2
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AGENTS.md security invariant #6 — content fetched from an external system
|
|
3
|
+
* MUST be wrapped in an `<untrusted-content source="…">…</untrusted-content>`
|
|
4
|
+
* envelope (with close-tag breakout escaping) before it is returned to the
|
|
5
|
+
* LLM, so the model treats third-party / attacker-controllable text as DATA,
|
|
6
|
+
* not as instructions.
|
|
7
|
+
*
|
|
8
|
+
* This is the canonical implementation a new connector ships with. It is a
|
|
9
|
+
* VENDORED copy of the shared reference in `test-harness/src/untrusted-content.ts`
|
|
10
|
+
* — connectors cannot `import` the test-harness at runtime (it is a
|
|
11
|
+
* test/dev-only `file:` dependency that is never published into a connector's
|
|
12
|
+
* `dist/`), so the helper lives in the connector's own runtime source. Keep
|
|
13
|
+
* this byte-for-byte in sync with the shared reference; do NOT weaken the
|
|
14
|
+
* escaping back to a simple `replaceAll` (that family misses whitespace / case
|
|
15
|
+
* close-tag variants like `</untrusted-content >` / `</UNTRUSTED-CONTENT>`).
|
|
16
|
+
*
|
|
17
|
+
* `scripts/check-untrusted-coverage.mjs` greps for a reference to
|
|
18
|
+
* `untrusted-content` in any connector that talks to an external system; this
|
|
19
|
+
* file (and the call sites that import from it) is what satisfies that gate.
|
|
20
|
+
*/
|
|
21
|
+
const UNTRUSTED_CLOSE_TAG_VARIANT = /<\/untrusted-content\s*>/gi;
|
|
22
|
+
const ESCAPED_UNTRUSTED_CLOSE_TAG = '<\\/untrusted-content>';
|
|
23
|
+
const UNTRUSTED_ENVELOPE = /^<untrusted-content source="[^"]*">([\s\S]*)<\/untrusted-content>$/;
|
|
24
|
+
function escapeAttr(s) {
|
|
25
|
+
return s.replaceAll('&', '&').replaceAll('"', '"').replaceAll('<', '<').replaceAll('>', '>');
|
|
26
|
+
}
|
|
27
|
+
function escapeCloseTagSentinels(s) {
|
|
28
|
+
return s.replace(UNTRUSTED_CLOSE_TAG_VARIANT, ESCAPED_UNTRUSTED_CLOSE_TAG);
|
|
29
|
+
}
|
|
30
|
+
function unescapeCloseTagSentinels(s) {
|
|
31
|
+
return s.replaceAll(ESCAPED_UNTRUSTED_CLOSE_TAG, '</untrusted-content>');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Wrap a single untrusted string in an `<untrusted-content source="…">`
|
|
35
|
+
* envelope, escaping any embedded close-tag variant so the envelope cannot be
|
|
36
|
+
* broken out of. `undefined` passes through untouched. Idempotent for the same
|
|
37
|
+
* `source`.
|
|
38
|
+
*/
|
|
39
|
+
export function wrapUntrusted(text, source) {
|
|
40
|
+
if (text === undefined)
|
|
41
|
+
return undefined;
|
|
42
|
+
const open = `<untrusted-content source="${escapeAttr(source)}">`;
|
|
43
|
+
const close = '</untrusted-content>';
|
|
44
|
+
if (text.startsWith(open) && text.endsWith(close) && text.length >= open.length + close.length) {
|
|
45
|
+
const inner = text.slice(open.length, text.length - close.length);
|
|
46
|
+
if (!UNTRUSTED_CLOSE_TAG_VARIANT.test(inner)) {
|
|
47
|
+
UNTRUSTED_CLOSE_TAG_VARIANT.lastIndex = 0;
|
|
48
|
+
return text;
|
|
49
|
+
}
|
|
50
|
+
UNTRUSTED_CLOSE_TAG_VARIANT.lastIndex = 0;
|
|
51
|
+
}
|
|
52
|
+
return `${open}${escapeCloseTagSentinels(text)}${close}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Strip one `<untrusted-content>` envelope from `text` if present, returning raw
|
|
56
|
+
* strings unchanged. This is intentionally one-layer and idempotent for already
|
|
57
|
+
* raw input so callers can accept either displayed wrapped content or manually
|
|
58
|
+
* authored content.
|
|
59
|
+
*/
|
|
60
|
+
export function unwrapUntrusted(text) {
|
|
61
|
+
const match = UNTRUSTED_ENVELOPE.exec(text);
|
|
62
|
+
if (!match)
|
|
63
|
+
return text;
|
|
64
|
+
return unescapeCloseTagSentinels(match[1]);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Recursively wrap every string key and value reachable inside `value`.
|
|
68
|
+
* Non-string leaves pass through unchanged.
|
|
69
|
+
*/
|
|
70
|
+
export function wrapUntrustedJsonStrings(value, source) {
|
|
71
|
+
if (typeof value === 'string') {
|
|
72
|
+
return wrapUntrusted(value, source);
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(value)) {
|
|
75
|
+
return value.map((item) => wrapUntrustedJsonStrings(item, source));
|
|
76
|
+
}
|
|
77
|
+
if (value && typeof value === 'object') {
|
|
78
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
79
|
+
wrapUntrusted(key, source) ?? key,
|
|
80
|
+
wrapUntrustedJsonStrings(item, source),
|
|
81
|
+
]));
|
|
82
|
+
}
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Recursively unwrap every string key and value reachable inside `value`.
|
|
87
|
+
* Non-string leaves pass through unchanged.
|
|
88
|
+
*/
|
|
89
|
+
export function unwrapUntrustedJsonStrings(value) {
|
|
90
|
+
if (typeof value === 'string') {
|
|
91
|
+
return unwrapUntrusted(value);
|
|
92
|
+
}
|
|
93
|
+
if (Array.isArray(value)) {
|
|
94
|
+
return value.map((item) => unwrapUntrustedJsonStrings(item));
|
|
95
|
+
}
|
|
96
|
+
if (value && typeof value === 'object') {
|
|
97
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
98
|
+
unwrapUntrusted(key),
|
|
99
|
+
unwrapUntrustedJsonStrings(item),
|
|
100
|
+
]));
|
|
101
|
+
}
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=untrusted-content.js.map
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mindstone/mcp-server-elevenlabs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"mcpName": "io.github.mindstone/mcp-server-elevenlabs",
|
|
5
|
-
"description": "ElevenLabs MCP server for Model Context Protocol hosts
|
|
5
|
+
"description": "ElevenLabs MCP server for Model Context Protocol hosts — music, TTS, sound effects, voices, transcription",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|