├── .gitignore
├── LICENSE
├── README.md
├── images
└── adding_voice.png
├── package.json
├── src
└── index.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules/
3 | npm-debug.log*
4 | yarn-debug.log*
5 | yarn-error.log*
6 |
7 | # Build output
8 | build/
9 | dist/
10 | *.tsbuildinfo
11 |
12 | # IDE
13 | .vscode/
14 | .idea/
15 | *.swp
16 | *.swo
17 |
18 | # OS
19 | .DS_Store
20 | Thumbs.db
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 say-mcp-server contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # say-mcp-server
2 |
3 |
4 | 
5 |
6 | An MCP server that provides text-to-speech functionality using macOS's built-in `say` command.
7 |
8 | ## Requirements
9 |
10 | - macOS (uses the built-in `say` command)
11 | - Node.js >= 14.0.0
12 |
13 | ## Configuration
14 |
15 | Add the following to your MCP settings configuration file:
16 |
17 | ```json
18 | {
19 | "mcpServers": {
20 | "say": {
21 | "command": "node",
22 | "args": ["/path/to/say-mcp-server/build/index.js"]
23 | }
24 | }
25 | }
26 | ```
27 |
28 |
29 | ## Installation
30 |
31 | ```bash
32 | npm install say-mcp-server
33 | ```
34 |
35 | ## Tools
36 |
37 | ### speak
38 |
39 | The `speak` tool provides access to macOS's text-to-speech capabilities with extensive customization options.
40 |
41 | #### Basic Usage
42 |
43 | Use macOS text-to-speech to speak text aloud.
44 |
45 | Parameters:
46 | - `text` (required): Text to speak. Supports:
47 | - Plain text
48 | - Basic punctuation for pauses
49 | - Newlines for natural breaks
50 | - [[slnc 500]] for 500ms silence
51 | - [[rate 200]] for changing speed mid-text
52 | - [[volm 0.5]] for changing volume mid-text
53 | - [[emph +]] and [[emph -]] for emphasis
54 | - [[pbas +10]] for pitch adjustment
55 | - `voice` (optional): Voice to use (default: "Alex")
56 | - `rate` (optional): Speaking rate in words per minute (default: 175, range: 1-500)
57 | - `background` (optional): Run speech in background to allow further MCP interaction (default: false)
58 |
59 | #### Advanced Features
60 |
61 | 1. Voice Modulation:
62 | ```typescript
63 | use_mcp_tool({
64 | server_name: "say",
65 | tool_name: "speak",
66 | arguments: {
67 | text: "[[volm 0.7]] This is quieter [[volm 1.0]] and this is normal [[volm 1.5]] and this is louder",
68 | voice: "Victoria"
69 | }
70 | });
71 | ```
72 |
73 | 2. Dynamic Rate Changes:
74 | ```typescript
75 | use_mcp_tool({
76 | server_name: "say",
77 | tool_name: "speak",
78 | arguments: {
79 | text: "Normal speed [[rate 300]] now speaking faster [[rate 100]] and now slower",
80 | voice: "Fred"
81 | }
82 | });
83 | ```
84 |
85 | 3. Emphasis and Pitch:
86 | ```typescript
87 | use_mcp_tool({
88 | server_name: "say",
89 | tool_name: "speak",
90 | arguments: {
91 | text: "[[emph +]] Important point! [[emph -]] [[pbas +10]] Higher pitch [[pbas -10]] Lower pitch",
92 | voice: "Samantha"
93 | }
94 | });
95 | ```
96 |
97 | #### Integration Examples
98 |
99 | 1. With Marginalia Search:
100 | ```typescript
101 | // Search for a topic and have the results read aloud
102 | const searchResult = await use_mcp_tool({
103 | server_name: "marginalia-mcp-server",
104 | tool_name: "search",
105 | arguments: { query: "quantum computing basics", count: 1 }
106 | });
107 |
108 | await use_mcp_tool({
109 | server_name: "say",
110 | tool_name: "speak",
111 | arguments: {
112 | text: searchResult.results[0].description,
113 | voice: "Daniel",
114 | rate: 150
115 | }
116 | });
117 | ```
118 |
119 | 2. With YouTube Transcripts:
120 | ```typescript
121 | // Read a YouTube video transcript
122 | const transcript = await use_mcp_tool({
123 | server_name: "youtube-transcript",
124 | tool_name: "get_transcript",
125 | arguments: {
126 | url: "https://youtube.com/watch?v=example",
127 | lang: "en"
128 | }
129 | });
130 |
131 | await use_mcp_tool({
132 | server_name: "say",
133 | tool_name: "speak",
134 | arguments: {
135 | text: transcript.text,
136 | voice: "Samantha",
137 | rate: 175
138 | }
139 | });
140 | ```
141 |
142 | 3. Background Speech with Multiple Actions:
143 | ```typescript
144 | // Start long speech in background
145 | await use_mcp_tool({
146 | server_name: "say",
147 | tool_name: "speak",
148 | arguments: {
149 | text: "This is a long speech that will run in the background...",
150 | voice: "Rocko (Italian (Italy))",
151 | rate: 69,
152 | background: true
153 | }
154 | });
155 |
156 | // Immediately perform another action while speech continues
157 | await use_mcp_tool({
158 | server_name: "marginalia-mcp-server",
159 | tool_name: "search",
160 | arguments: { query: "parallel processing" }
161 | });
162 | ```
163 |
164 | 4. With Apple Notes:
165 | ```typescript
166 | // Read notes aloud
167 | const notes = await use_mcp_tool({
168 | server_name: "apple-notes-mcp",
169 | tool_name: "search-notes",
170 | arguments: { query: "meeting notes" }
171 | });
172 |
173 | if (notes.length > 0) {
174 | await use_mcp_tool({
175 | server_name: "say",
176 | tool_name: "speak",
177 | arguments: {
178 | text: notes[0].content,
179 | voice: "Karen",
180 | rate: 160
181 | }
182 | });
183 | }
184 | ```
185 |
186 | Example:
187 | ```typescript
188 | use_mcp_tool({
189 | server_name: "say",
190 | tool_name: "speak",
191 | arguments: {
192 | text: "Hello, world!",
193 | voice: "Victoria",
194 | rate: 200
195 | }
196 | });
197 | ```
198 |
199 | ### list_voices
200 |
201 | List all available text-to-speech voices on the system.
202 |
203 | Example:
204 | ```typescript
205 | use_mcp_tool({
206 | server_name: "say",
207 | tool_name: "list_voices",
208 | arguments: {}
209 | });
210 | ```
211 |
212 | ## Recommended Voices
213 |
214 |
Voice | 217 |Language/Region | 218 |Intellectual Figure | 219 |Haiku | 220 |CLI Specification | 221 |
---|---|---|---|---|
Anna (Premium) | 224 |German | 225 |Emmy Noether | 226 |Symmetrie haucht Leben Algebras verborgne Form Abstraktion blüht Symmetry breathes life Algebra's hidden forms Abstraction blooms |
227 | -v "Anna (Premium)" |
228 |
Emma (Premium) | 231 |Italian | 232 |Maria Adelaide Sneider | 233 |Algoritmi in danza Macchina sussurra dolce Il codice vive Algorithms dance Machine whispers secrets soft Code becomes alive |
234 | -v "Emma (Premium)" |
235 |
Federica (Premium) | 238 |Italian | 239 |Pia Nalli | 240 |Teoremi fluenti Numeri danzano liberi Verità emerge Flowing theorems dance Numbers move in freedom's space Truth emerges pure |
241 | -v "Federica (Premium)" |
242 |
Serena (Premium) | 245 |English (UK) | 246 |Bertha Swirles | 247 |Quantum waves ripple Through mathematical seas deep Truth's light emerges Quantum waves ripple Through mathematical seas deep Truth's light emerges |
248 | -v "Serena (Premium)" |
249 |
Petra (Premium) | 252 |German | 253 |Ruth Moufang | 254 |Algebra spricht In Symmetrien versteckt Wahrheit erblüht Algebra speaks soft Hidden in symmetries pure Truth blooms anew here |
255 | -v "Petra (Premium)" |
256 |
Yuna (Premium) | 259 |Korean | 260 |Hee Oh | 261 |숨은 패턴 빛나고 마음의 방정식 핀다 지식 자라나 Hidden patterns gleam Mind's equations softly bloom Knowledge multiplies |
262 | -v "Yuna (Premium)" |
263 |
Alva (Premium) | 266 |Swedish | 267 |Sonja Korovkin | 268 |Mönster flödar fritt Genom tankens labyrinter Visdom blomstrar här Patterns flowing free Through labyrinths of the mind Wisdom blooms right here |
269 | -v "Alva (Premium)" |
270 |
Amélie (Premium) | 273 |French (Canada) | 274 |Sophie Germain | 275 |Nombres premiers murmurent Dansent entre les silences Symétrie s'ouvre Prime numbers whisper Dancing between the silence Symmetry unfolds |
276 | -v "Amélie (Premium)" |
277 |
Ewa (Premium) | 280 |Polish | 281 |Maria Wielgus | 282 |Logiki korzenie Matematyczne krainy Myśl kiełkująca Logic's tender roots Mathematical landscapes Thought's seeds germinate |
283 | -v "Ewa (Premium)" |
284 |
Kiyara (Premium) | 287 |Hindi | 288 |Shakuntala Devi | 289 |गणित की लय में अंक नृत्य करते हैं ज्ञान जगता है In rhythm of math Numbers dance their sacred steps Knowledge awakens |
290 | -v "Kiyara (Premium)" |
291 |
Majed (Premium) | 294 |Arabic | 295 |Maha Al-Aswad | 296 |أرقام ترقص في فضاء اللانهاية الحقيقة تشرق Numbers dance freely In infinity's vast space Truth rises like dawn |
297 | -v "Majed (Premium)" |
298 |
Tünde (Premium) | 301 |Hungarian | 302 |Julia Erdős | 303 |Számok táncolnak Végtelen térben szállnak Igazság virrad Numbers dance and soar Through infinite space they glide Truth dawns pure and bright |
304 | -v "Tünde (Premium)" |
305 |
Fiona (Enhanced) | 308 |English (Scottish) | 309 |Mary Somerville | 310 |Highland mists reveal Mathematical mysteries Truth shines like the stars Highland mists reveal Mathematical mysteries Truth shines like the stars |
311 | -v "Fiona (Enhanced)" |
312 |
Lesya (Enhanced) | 315 |Ukrainian | 316 |Olena Voinova | 317 |Тиша говорить Між зірками знання спить Думка проростає Silence speaks softly Knowledge sleeps among the stars Thought begins to grow |
318 | -v "Lesya (Enhanced)" |
319 |
Carmit (Enhanced) | 322 |Hebrew | 323 |Tali Seror | 324 |מילים נושמות בשקט בין שורות של דממה שיר מתעורר Words breathe silently Between lines of deep stillness Poem awakening |
325 | -v "Carmit (Enhanced)" |
326 |
Milena (Enhanced) | 329 |Russian | 330 |Olga Ladyzhenskaya | 331 |Память шепчет нам Уравнения текут Истина молчит Memory whispers Equations flow like rivers Truth speaks silently |
332 | -v "Milena (Enhanced)" |
333 |
Katya (Enhanced) | 336 |Russian | 337 |Sofia Kovalevskaya | 338 |Числа танцуют В пространстве бесконечном Истина цветёт Numbers dance freely In space of infinity Truth blooms like a flower |
339 | -v "Katya (Enhanced)" |
340 |
Damayanti (Enhanced) | 343 |Indonesian | 344 |Sri Pekerti | 345 |Angka menari Dalam ruang tak batas Kebenaran tumbuh Numbers dance gently In boundless space they flutter Truth grows like new leaves |
346 | -v "Damayanti (Enhanced)" |
347 |
Dariush (Enhanced) | 350 |Persian | 351 |Maryam Mirzakhani | 352 |اعداد می رقصند در فضای بی پایان حقیقت می روید Numbers dance with grace In endless space they traverse Truth springs forth anew |
353 | -v "Dariush (Enhanced)" |
354 |
Rocko (Italian) | 357 |Italian | 358 |Astro Boy (Tetsuwan Atomu) Italian dub |
359 | Robot di metallo Cuore umano batte forte Pace nel futuro Metal robot form Human heart beats strong within Peace in future dawns |
360 | -v "Rocko (Italian (Italy))" |
361 |
Rocko (Italian) | 364 |Italian | 365 |Jeeg Robot d'Acciaio (Kōtetsu Jeeg) |
366 | Acciaio lucente Protettore dei deboli Vola nel cielo Shining steel warrior Protector of the helpless Soars through the heavens |
367 | -v "Rocko (Italian (Italy))" |
368 |
Rocko (Italian) | 371 |Italian | 372 |Numero 5 (Short Circuit) |
373 | Input infinito La coscienza si risveglia Vita artificiale Infinite input Consciousness awakening Artificial life |
374 | -v "Rocko (Italian (Italy))" |
375 |
Binbin (Enhanced) | 378 |Chinese (Mainland) | 379 |Li Shanlan | 380 |算术之道流 数理演绎真理 智慧绽放 Arithmetic flows Logic unfolds truth's pattern Wisdom blossoms bright |
381 | -v "Binbin (Enhanced)" |
382 |
Han (Premium) | 385 |Chinese (Mainland) | 386 |Chen Jingrun | 387 |素数之舞动 哥德巴赫猜想 真理永恒 Prime numbers dancing Goldbach's conjecture whispers Truth eternal flows |
388 | -v "Han (Premium)" |
389 |
Lilian (Premium) | 392 |Chinese (Mainland) | 393 |Hua Luogeng | 394 |数论之光芒 解析延续美 智慧升华 Number theory shines Analysis extends grace Wisdom ascends pure |
395 | -v "Lilian (Premium)" |
396 |
Meijia | 399 |Chinese (Taiwan) | 400 |Sun-Yung Alice Chang | 401 |幾何之美現 曲率流動不息 空間展開 Geometry shows Curvature flows endlessly Space unfolds anew |
402 | -v "Meijia" |
403 |
Sinji (Premium) | 406 |Chinese (Hong Kong) | 407 |Shing-Tung Yau | 408 |流形之奧秘 卡拉比空間動 維度交織 Manifolds reveal Calabi spaces in flow Dimensions weave truth |
409 | -v "Sinji (Premium)" |
410 |
Tingting | 413 |Chinese (Mainland) | 414 |Wang Zhenyi | 415 |星辰轨迹明 天文数学融 智慧闪耀 Starlit paths shine bright Astronomy meets numbers Wisdom radiates |
416 | -v "Tingting" |
417 |
Yue (Premium) | 420 |Chinese (Mainland) | 421 |Chern Shiing-shen | 422 |微分几何 纤维丛中寻真 本质显现 Differential forms In fiber bundles seek truth Essence emerges |
423 | -v "Yue (Premium)" |
424 |