@mcptoolshop/voice-soundboard-core 0.1.0 → 0.1.1
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 +260 -0
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo-dark.jpg" alt="MCP Voice Soundboard" width="420" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h3 align="center">Text-to-speech MCP server for AI agents.</h3>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://github.com/mcp-tool-shop-org/mcp-voice-soundboard/actions"><img src="https://img.shields.io/github/actions/workflow/status/mcp-tool-shop-org/mcp-voice-soundboard/ci.yml?style=flat-square&label=CI" alt="CI"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@mcp-tool-shop/voice-soundboard-mcp"><img src="https://img.shields.io/npm/v/@mcp-tool-shop/voice-soundboard-mcp?style=flat-square&color=cb3837&logo=npm" alt="npm"></a>
|
|
10
|
+
<img src="https://img.shields.io/badge/node-%E2%89%A520-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js 20+">
|
|
11
|
+
<img src="https://img.shields.io/badge/TypeScript-5.7-3178c6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript">
|
|
12
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License: MIT"></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
12 voices • 5 presets • 8 emotions • SSML-lite • SFX tags • multi-speaker dialogue<br>
|
|
17
|
+
Swappable TTS backends. Guardrails built in. Ships as a single <code>npx</code> command.
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Highlights
|
|
23
|
+
|
|
24
|
+
- **MCP native** — stdio transport, works with Claude Desktop, Cursor, and any MCP client
|
|
25
|
+
- **5 tools** — `voice_speak`, `voice_dialogue`, `voice_status`, `voice_interrupt`, `voice_inner_monologue`
|
|
26
|
+
- **12 approved voices** — curated set with presets (`narrator`, `announcer`, `whisper`, `storyteller`, `assistant`)
|
|
27
|
+
- **Emotion spans** — 8 emotions via `[happy]...[/happy]` inline markup
|
|
28
|
+
- **SSML-lite** — `<break>`, `<emphasis>`, `<prosody>` without full SSML complexity
|
|
29
|
+
- **SFX tags** — `[ding]`, `[chime]`, `[whoosh]`, `[tada]`, `[error]`, `[click]` inline sound effects
|
|
30
|
+
- **Multi-speaker dialogue** — `Speaker: line` format with auto-cast and pause directives
|
|
31
|
+
- **Guardrails** — rate limiting, concurrency semaphore, request timeouts, path traversal protection, secret redaction
|
|
32
|
+
- **Swappable backends** — Mock (built-in), HTTP proxy, Python bridge, or bring your own
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx @mcp-tool-shop/voice-soundboard-mcp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or install globally:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g @mcp-tool-shop/voice-soundboard-mcp
|
|
44
|
+
voice-soundboard-mcp
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Claude Desktop / MCP Client Config
|
|
48
|
+
|
|
49
|
+
Add to your MCP client configuration (e.g. `claude_desktop_config.json`):
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"voice-soundboard": {
|
|
55
|
+
"command": "npx",
|
|
56
|
+
"args": ["-y", "@mcp-tool-shop/voice-soundboard-mcp"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
With options:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"voice-soundboard": {
|
|
68
|
+
"command": "npx",
|
|
69
|
+
"args": [
|
|
70
|
+
"-y", "@mcp-tool-shop/voice-soundboard-mcp",
|
|
71
|
+
"--artifact=path",
|
|
72
|
+
"--output-dir=/tmp/voice-output",
|
|
73
|
+
"--timeout=30000",
|
|
74
|
+
"--max-concurrent=2"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## MCP Tools
|
|
82
|
+
|
|
83
|
+
### `voice_speak`
|
|
84
|
+
|
|
85
|
+
Synthesize speech from text.
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
text: "Hello world!"
|
|
89
|
+
voice?: "am_fenrir" # Voice ID or preset name
|
|
90
|
+
speed?: 1.0 # 0.5 - 2.0
|
|
91
|
+
format?: "wav" # wav | mp3 | ogg | raw
|
|
92
|
+
artifactMode?: "path" # path | base64
|
|
93
|
+
sfx?: true # Enable [ding], [chime] etc.
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### `voice_dialogue`
|
|
97
|
+
|
|
98
|
+
Multi-speaker dialogue synthesis.
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
script: "Alice: Hello!\nBob: Hey there!"
|
|
102
|
+
cast?: { "Alice": "af_sky", "Bob": "am_fenrir" }
|
|
103
|
+
speed?: 1.0
|
|
104
|
+
concat?: true # Combine into single file
|
|
105
|
+
debug?: true # Include cue_sheet
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `voice_status`
|
|
109
|
+
|
|
110
|
+
Returns engine health, available voices, presets, and backend info. No arguments.
|
|
111
|
+
|
|
112
|
+
### `voice_interrupt`
|
|
113
|
+
|
|
114
|
+
Stop or rollback active synthesis.
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
streamId?: "stream-123"
|
|
118
|
+
reason?: "user_spoke" # user_spoke | context_change | timeout | manual
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `voice_inner_monologue`
|
|
122
|
+
|
|
123
|
+
Ephemeral micro-utterances for ambient narration. Requires `--ambient` flag or `VOICE_SOUNDBOARD_AMBIENT_ENABLED=1`.
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
text: "Interesting..." # Max 500 chars, auto-redacted
|
|
127
|
+
category?: "thinking" # general | thinking | observation | debug
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Voices
|
|
131
|
+
|
|
132
|
+
| ID | Name | Accent | Gender |
|
|
133
|
+
|----|------|--------|--------|
|
|
134
|
+
| `af_aoede` | Aoede | American | Female |
|
|
135
|
+
| `af_jessica` | Jessica | American | Female |
|
|
136
|
+
| `af_sky` | Sky | American | Female |
|
|
137
|
+
| `am_eric` | Eric | American | Male |
|
|
138
|
+
| `am_fenrir` | Fenrir | American | Male |
|
|
139
|
+
| `am_liam` | Liam | American | Male |
|
|
140
|
+
| `am_onyx` | Onyx | American | Male |
|
|
141
|
+
| `bf_alice` | Alice | British | Female |
|
|
142
|
+
| `bf_emma` | Emma | British | Female |
|
|
143
|
+
| `bf_isabella` | Isabella | British | Female |
|
|
144
|
+
| `bm_george` | George | British | Male |
|
|
145
|
+
| `bm_lewis` | Lewis | British | Male |
|
|
146
|
+
|
|
147
|
+
### Presets
|
|
148
|
+
|
|
149
|
+
| Preset | Voice | Speed | Description |
|
|
150
|
+
|--------|-------|-------|-------------|
|
|
151
|
+
| `narrator` | `bm_george` | 0.95 | Calm documentary style |
|
|
152
|
+
| `announcer` | `am_onyx` | 1.05 | News anchor energy |
|
|
153
|
+
| `whisper` | `af_aoede` | 0.85 | Soft, intimate |
|
|
154
|
+
| `storyteller` | `bf_emma` | 0.90 | Warm bedtime-story feel |
|
|
155
|
+
| `assistant` | `af_jessica` | 1.0 | Neutral, helpful |
|
|
156
|
+
|
|
157
|
+
## Emotion Spans
|
|
158
|
+
|
|
159
|
+
Wrap text in emotion tags to control prosody:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
[happy]Great news![/happy] But [sad]I have to go.[/sad]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Supported: `happy`, `sad`, `angry`, `fearful`, `surprised`, `disgusted`, `calm`, `excited`
|
|
166
|
+
|
|
167
|
+
## CLI Flags
|
|
168
|
+
|
|
169
|
+
| Flag | Default | Description |
|
|
170
|
+
|------|---------|-------------|
|
|
171
|
+
| `--artifact=path\|base64` | `path` | Audio delivery mode |
|
|
172
|
+
| `--output-dir=<path>` | `<tmpdir>/voice-soundboard/` | Output directory |
|
|
173
|
+
| `--backend=mock\|http` | `mock` | Backend selection |
|
|
174
|
+
| `--backend-url=<url>` | — | HTTP backend URL |
|
|
175
|
+
| `--ambient` | off | Enable inner-monologue system |
|
|
176
|
+
| `--max-concurrent=<n>` | `1` | Max concurrent synthesis requests |
|
|
177
|
+
| `--timeout=<ms>` | `20000` | Per-request timeout |
|
|
178
|
+
| `--retention-minutes=<n>` | `240` | Auto-cleanup age (0 to disable) |
|
|
179
|
+
|
|
180
|
+
## Packages
|
|
181
|
+
|
|
182
|
+
This is a pnpm monorepo with two publishable packages:
|
|
183
|
+
|
|
184
|
+
| Package | Description | npm |
|
|
185
|
+
|---------|-------------|-----|
|
|
186
|
+
| [`@mcp-tool-shop/voice-soundboard-core`](packages/core) | Backend-agnostic core library (validation, SSML, chunking, schemas) | [](https://www.npmjs.com/package/@mcp-tool-shop/voice-soundboard-core) |
|
|
187
|
+
| [`@mcp-tool-shop/voice-soundboard-mcp`](packages/mcp-server) | MCP server with CLI, guardrails, and transport | [](https://www.npmjs.com/package/@mcp-tool-shop/voice-soundboard-mcp) |
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Install
|
|
193
|
+
pnpm install
|
|
194
|
+
|
|
195
|
+
# Build
|
|
196
|
+
pnpm build
|
|
197
|
+
|
|
198
|
+
# Test (342 tests)
|
|
199
|
+
pnpm test
|
|
200
|
+
|
|
201
|
+
# Lint
|
|
202
|
+
pnpm --filter @mcp-tool-shop/voice-soundboard-core exec ruff check . # Python legacy
|
|
203
|
+
pnpm exec ruff check voice_soundboard/ tests/ --ignore=E501 # Python legacy
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Project Structure
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
mcp-voice-soundboard/
|
|
210
|
+
packages/
|
|
211
|
+
core/ @mcp-tool-shop/voice-soundboard-core
|
|
212
|
+
src/
|
|
213
|
+
limits.ts SHIP_LIMITS, text/chunk limits
|
|
214
|
+
schemas.ts VoiceRequest, VoiceResponse, error codes
|
|
215
|
+
artifact.ts resolveOutputDir, path sandbox
|
|
216
|
+
voices.ts Approved voice registry + presets
|
|
217
|
+
emotion.ts Emotion span parser
|
|
218
|
+
ssml/ SSML-lite parser + limits
|
|
219
|
+
chunking/ Text chunker
|
|
220
|
+
sfx/ SFX tag parser + registry
|
|
221
|
+
sandbox.ts Safe filenames, symlink checks
|
|
222
|
+
ambient.ts AmbientEmitter for inner monologue
|
|
223
|
+
redact.ts PII/secret redaction
|
|
224
|
+
mcp-server/ @mcp-tool-shop/voice-soundboard-mcp
|
|
225
|
+
src/
|
|
226
|
+
server.ts MCP tool registration + guardrail wiring
|
|
227
|
+
cli.ts CLI entrypoint (stdio transport)
|
|
228
|
+
backend.ts Backend abstraction + mock/HTTP
|
|
229
|
+
concurrency.ts SynthesisSemaphore
|
|
230
|
+
rateLimit.ts ToolRateLimiter (sliding window)
|
|
231
|
+
timeout.ts withTimeout utility
|
|
232
|
+
retention.ts Output file cleanup timer
|
|
233
|
+
redact.ts Server-level redaction
|
|
234
|
+
validation.ts Synthesis result validation
|
|
235
|
+
tools/ Individual tool handlers
|
|
236
|
+
assets/ Logo, audio event manifests
|
|
237
|
+
docs/ Architecture docs
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Security
|
|
241
|
+
|
|
242
|
+
See [SECURITY.md](SECURITY.md) for vulnerability reporting.
|
|
243
|
+
|
|
244
|
+
See [THREAT_MODEL.md](THREAT_MODEL.md) for the full threat surface analysis.
|
|
245
|
+
|
|
246
|
+
## Related
|
|
247
|
+
|
|
248
|
+
| Project | Description |
|
|
249
|
+
|---------|-------------|
|
|
250
|
+
| [soundboard-plugin](https://github.com/mcp-tool-shop-org/soundboard-plugin) | Claude Code plugin — slash commands, emotion-aware narration |
|
|
251
|
+
|
|
252
|
+
## License
|
|
253
|
+
|
|
254
|
+
[MIT](LICENSE)
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
<p align="center">
|
|
259
|
+
Built by <a href="https://github.com/mcp-tool-shop-org">mcp-tool-shop</a>
|
|
260
|
+
</p>
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcptoolshop/voice-soundboard-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Backend-agnostic core library for MCP Voice Soundboard — validation, SSML-lite, chunking, emotion spans, SFX tags, and schemas.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
|
-
"dist"
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
10
11
|
],
|
|
11
12
|
"license": "MIT",
|
|
12
13
|
"author": "mcp-tool-shop <64996768+mcp-tool-shop@users.noreply.github.com>",
|