mcp-walkthrough 0.2.1 → 0.2.3

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 CHANGED
@@ -5,19 +5,22 @@
5
5
 
6
6
  # MCP Walkthrough
7
7
 
8
- An MCP server for interactive code walkthroughs. Claude drives the narrative — opens files, highlights code, shows inline explanations, and navigates step by step.
8
+ An MCP server for interactive code walkthroughs with voice narration. Claude drives the narrative — opens files, highlights code, explains inline, and reads each step aloud using neural text-to-speech.
9
9
 
10
10
  ## Overview
11
11
 
12
- Text in a terminal isn't enough when you want Claude to explain a solution. MCP Walkthrough lets Claude open files in VS Code, highlight specific lines, and show rich markdown explanations right next to the code. Navigate at your own pace — forward, back, or let it autoplay.
12
+ Text in a terminal isn't enough when you want Claude to explain a solution. MCP Walkthrough lets Claude open files in VS Code, highlight specific lines, show rich markdown explanations, and **narrate each step with a natural-sounding voice**. Navigate at your own pace — forward, back, pause, or let the voice guide you.
13
13
 
14
14
  **Key Features:**
15
+ - **Voice Narration** — Neural text-to-speech reads each step aloud (400+ voices via Microsoft Edge TTS)
15
16
  - **Inline Explanations** — Markdown comment bubbles appear right next to highlighted code
16
- - **Multi-Step Walkthroughs** — Claude sends all steps at once, you navigate with keyboard shortcuts
17
- - **Autoplay** — Optional auto-advance with reading-speed-based timing
17
+ - **Multi-Step Walkthroughs** — Claude sends all steps at once, voice auto-advances through them
18
+ - **Live Controls** — Pause, resume, skip, stop, toggle voice/bubbles on the fly
19
+ - **Voice Selection** — Choose your narrator, audition voices, preference persisted across sessions
18
20
  - **Keyboard Navigation** — `Cmd+Shift+Right` / `Cmd+Shift+Left` to navigate steps
19
21
  - **Selection Reading** — Claude can see what you've highlighted to discuss it further
20
22
  - **Focus Preservation** — Opens files without stealing focus from your terminal
23
+ - **Offline Fallback** — Falls back to native TTS (`say`/`espeak`) when offline
21
24
 
22
25
  > **Note:** This MCP server requires VS Code, VS Code Insiders, or Cursor. It includes a companion VS Code extension that is automatically installed when you `npm install`. The CLI is auto-discovered even if `code` is not in your PATH.
23
26
 
@@ -78,24 +81,25 @@ MCP tools are deferred (loaded on-demand), so Claude may not use them automatica
78
81
  ```markdown
79
82
  ## Walkthrough MCP
80
83
 
81
- You have access to walkthrough tools via MCP. Use them to visually walk the user through code — open files, highlight lines, and show inline explanations in VS Code.
84
+ You have access to walkthrough tools via MCP. Use them to visually walk the user through code with voice narration — open files, highlight lines, show inline explanations, and read each step aloud in VS Code.
82
85
  ```
83
86
 
84
87
  ## Available Tools
85
88
 
86
89
  | Tool | Description |
87
90
  |------|-------------|
91
+ | **walkthrough** | Start a voiced, multi-step code walkthrough |
92
+ | **walkthrough_control** | Pause, resume, next, prev, stop, toggle voice/bubbles |
93
+ | **walkthrough_voice** | Change narrator voice, audition voices, list available |
94
+ | **walkthrough_status** | Get current walkthrough state |
88
95
  | **show_code** | Open a file and highlight specific lines |
89
- | **explain_code** | Highlight lines + show an inline markdown explanation bubble |
96
+ | **explain_code** | Highlight lines + show explanation bubble (+ voice if enabled) |
90
97
  | **clear_explanations** | Remove all explanation bubbles |
91
- | **walkthrough** | Start a multi-step walkthrough with all steps at once |
92
- | **walkthrough_navigate** | Navigate an active walkthrough (next/prev/goto) |
93
- | **walkthrough_status** | Get current walkthrough state |
94
98
  | **get_selection** | Read the currently highlighted code in VS Code |
95
99
 
96
100
  ### walkthrough
97
101
 
98
- The main tool. Claude generates all steps and sends them at once. The VS Code extension handles navigation.
102
+ The main tool. Claude generates all steps and sends them at once. Voice narration and explanation bubbles are on by default. Returns immediately — narration runs in the background.
99
103
 
100
104
  ```json
101
105
  {
@@ -104,42 +108,63 @@ The main tool. Claude generates all steps and sends them at once. The VS Code ex
104
108
  "file": "/absolute/path/to/file.ts",
105
109
  "line": 10,
106
110
  "endLine": 25,
107
- "explanation": "This validates the JWT token on every request.\n\nThe `secret` is loaded from environment variables.",
111
+ "explanation": "This validates the JWT token on every request. The secret is loaded from environment variables.",
108
112
  "title": "Token Validation"
109
113
  }
110
114
  ],
111
- "autoplay": false,
112
- "delayMs": 5000
115
+ "voice": true,
116
+ "showBubbles": true
113
117
  }
114
118
  ```
115
119
 
116
120
  **Parameters:**
117
121
  - `steps` — Array of `{ file, line, endLine?, explanation, title? }`
118
- - `autoplay` — Auto-advance through steps (default: `false`)
119
- - `delayMs` — Delay between steps in ms when autoplay is on (default: calculated from reading speed)
122
+ - `voice` — Enable voice narration (default: `true`)
123
+ - `showBubbles` — Show inline explanation bubbles (default: `true`)
124
+
125
+ Write explanations as **natural spoken language** — markdown is stripped before narration.
120
126
 
121
- ### walkthrough_navigate
127
+ ### walkthrough_control
128
+
129
+ Control an active walkthrough on the fly:
122
130
 
123
131
  ```json
124
132
  { "action": "next" }
125
133
  { "action": "prev" }
126
- { "action": "goto", "step": 3 }
134
+ { "action": "pause" }
135
+ { "action": "resume" }
136
+ { "action": "stop" }
137
+ { "voice": false }
138
+ { "showBubbles": false }
139
+ ```
140
+
141
+ ### walkthrough_voice
142
+
143
+ Change the narrator voice. Speaks a sample so you hear the difference. Persisted across sessions.
144
+
145
+ ```json
146
+ { "voice": "en-US-GuyNeural" }
147
+ { "list": true, "locale": "en-US" }
148
+ { "audition": true, "locale": "en-US", "gender": "Female" }
127
149
  ```
128
150
 
151
+ Popular voices: `en-US-AriaNeural`, `en-US-MichelleNeural`, `en-US-AndrewNeural`, `en-US-GuyNeural`
152
+
129
153
  ### Keyboard Shortcuts
130
154
 
131
- During an active walkthrough:
132
- - **Cmd+Shift+Right** — Next step
133
- - **Cmd+Shift+Left** — Previous step
155
+ During an active walkthrough (shown in the explanation bubble):
156
+ - **Cmd+Shift+Right** (macOS) / **Ctrl+Shift+Right** (Linux/Windows) — Next step
157
+ - **Cmd+Shift+Left** (macOS) / **Ctrl+Shift+Left** (Linux/Windows) — Previous step
134
158
  - **Status bar** — Shows current step, click to stop
135
159
 
136
160
  ### Writing Explanations
137
161
 
138
- Explanations render as markdown in VS Code comment bubbles. Tips:
162
+ Explanations render as markdown in VS Code comment bubbles and are also narrated as speech. Tips:
139
163
 
164
+ - **Write as natural speech** — the voice reads it aloud, so avoid heavy markdown
140
165
  - **Use actual newlines** for paragraphs, not `\n` escape sequences
141
- - **Avoid `##` headers** — they render very large in the comment bubble. Use **bold** instead
142
- - Inline code with backticks, code blocks, lists, and links all work
166
+ - **Avoid `##` headers** — they render too large in the comment bubble. Use **bold** instead
167
+ - Inline code, code blocks, lists, and links all work in bubbles
143
168
 
144
169
  ## How It Works
145
170
 
@@ -165,6 +190,7 @@ mcp-walkthrough/
165
190
  │ ├── index.ts # MCP server entry point, tool registration
166
191
  │ ├── bridge.ts # Unix socket client to VS Code extension
167
192
  │ ├── code-cli.ts # Cross-platform VS Code CLI discovery
193
+ │ ├── tts.ts # Text-to-speech (Edge TTS + native fallback)
168
194
  │ ├── socket.ts # Socket path computation and discovery
169
195
  │ └── utils/
170
196
  │ └── logger.ts # Pino logger (stderr only)
@@ -178,7 +204,8 @@ mcp-walkthrough/
178
204
  │ ├── bridge.test.ts
179
205
  │ ├── code-cli.test.ts
180
206
  │ ├── postinstall.test.ts
181
- └── socket.test.ts
207
+ ├── socket.test.ts
208
+ │ └── tts.test.ts
182
209
  └── docs/
183
210
  ```
184
211
 
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
6
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
7
  import { z } from "zod";
8
8
  import { checkBridge, clearExplanations, ensureExtensionInstalled, getSelection, getWalkthroughStatus, navigateWalkthrough, openFile, showExplanation, startWalkthrough, } from "./bridge.js";
9
+ import { cleanupTts, getVoice, listVoices, setVoice, speak, stopSpeaking, stripMarkdown, } from "./tts.js";
9
10
  import { flushLogs, logger } from "./utils/logger.js";
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = dirname(__filename);
@@ -42,6 +43,9 @@ server.registerTool("explain_code", {
42
43
  },
43
44
  }, async (args) => {
44
45
  const result = await showExplanation(args.file, args.line, args.endLine, args.explanation, args.title, args.startChar, args.endChar);
46
+ if (playback.voice) {
47
+ speak(stripMarkdown(args.explanation)).catch((err) => logger.warn({ err }, "TTS failed for explain_code"));
48
+ }
45
49
  return {
46
50
  content: [{ type: "text", text: JSON.stringify(result) }],
47
51
  };
@@ -61,38 +65,250 @@ const stepSchema = z.object({
61
65
  explanation: z.string().describe("Markdown explanation"),
62
66
  title: z.string().optional().describe("Step title"),
63
67
  });
68
+ // --- Walkthrough state ---
69
+ let activeSteps = [];
70
+ let narrationAbort = null;
71
+ let paused = false;
72
+ let pauseResolve = null;
73
+ const playback = { voice: true, showBubbles: true };
74
+ async function runNarration(startIndex) {
75
+ narrationAbort = new AbortController();
76
+ const signal = narrationAbort.signal;
77
+ for (let i = startIndex; i < activeSteps.length; i++) {
78
+ if (signal.aborted)
79
+ break;
80
+ while (paused && !signal.aborted) {
81
+ await new Promise((r) => {
82
+ pauseResolve = r;
83
+ });
84
+ pauseResolve = null;
85
+ }
86
+ if (signal.aborted)
87
+ break;
88
+ if (i > startIndex) {
89
+ await navigateWalkthrough("next");
90
+ }
91
+ if (playback.voice) {
92
+ const step = activeSteps[i];
93
+ if (step) {
94
+ const text = stripMarkdown(step.explanation);
95
+ await speak(text);
96
+ }
97
+ }
98
+ }
99
+ narrationAbort = null;
100
+ if (!signal.aborted) {
101
+ await navigateWalkthrough("next");
102
+ activeSteps = [];
103
+ }
104
+ }
105
+ function stopNarration() {
106
+ paused = false;
107
+ pauseResolve?.();
108
+ stopSpeaking();
109
+ narrationAbort?.abort();
110
+ narrationAbort = null;
111
+ }
64
112
  server.registerTool("walkthrough", {
65
- description: "Start a multi-step code walkthrough. Sends all steps to VS Code at once. The extension handles navigation user clicks prev/next or uses Cmd+Shift+Left/Right. Optional autoplay with delay between steps. Returns current step state so you can navigate with walkthrough_navigate. Explanation markdown renders as VS Code comment widgets — use actual newlines, avoid ## headers (too large — use **bold**), inline code and code blocks work.",
113
+ description: "Start a multi-step code walkthrough with voice narration. Opens files, highlights code, shows inline explanation bubbles, and reads each step aloud. Voice and bubbles are on by default. Returns immediately narration runs in background. Control with walkthrough_control (next, prev, stop, pause, resume, toggle voice/bubbles). Write explanations as natural spoken language.",
66
114
  inputSchema: {
67
115
  steps: z.array(stepSchema).describe("Array of walkthrough steps"),
68
- autoplay: z
116
+ voice: z
69
117
  .boolean()
70
118
  .optional()
71
- .describe("Auto-advance through steps (default: false)"),
72
- delayMs: z
73
- .number()
119
+ .describe("Enable voice narration (default: true)"),
120
+ showBubbles: z
121
+ .boolean()
74
122
  .optional()
75
- .describe("Delay between steps in ms when autoplay is on (default: 5000)"),
123
+ .describe("Show explanation bubbles (default: true)"),
76
124
  },
77
125
  }, async (args) => {
78
- const result = await startWalkthrough(args.steps, args.autoplay, args.delayMs);
126
+ stopNarration();
127
+ activeSteps = args.steps;
128
+ if (args.voice !== undefined)
129
+ playback.voice = args.voice;
130
+ if (args.showBubbles !== undefined)
131
+ playback.showBubbles = args.showBubbles;
132
+ paused = false;
133
+ const result = await startWalkthrough(activeSteps, false);
134
+ runNarration(0).catch((err) => logger.error({ err }, "Narration failed"));
79
135
  return {
80
- content: [{ type: "text", text: JSON.stringify(result) }],
136
+ content: [
137
+ { type: "text", text: JSON.stringify(result) },
138
+ {
139
+ type: "text",
140
+ text: "Controls: next | prev | pause | resume | stop — use walkthrough_control. Toggle voice/bubbles on the fly.",
141
+ },
142
+ ],
81
143
  };
82
144
  });
83
- server.registerTool("walkthrough_navigate", {
84
- description: "Navigate an active walkthrough. Use when the user says next, back, or asks to jump to a step. Returns the current step state.",
145
+ server.registerTool("walkthrough_control", {
146
+ description: "Control an active walkthrough. Navigate (next/prev/goto), stop, pause, resume, or toggle voice and bubbles on the fly. Changes take effect immediately.",
85
147
  inputSchema: {
86
- action: z.enum(["next", "prev", "goto"]).describe("Navigation action"),
148
+ action: z
149
+ .enum(["next", "prev", "goto", "stop", "pause", "resume"])
150
+ .optional()
151
+ .describe("Navigation or playback action"),
87
152
  step: z
88
153
  .number()
89
154
  .optional()
90
155
  .describe("Step index (0-based) for goto action"),
156
+ voice: z.boolean().optional().describe("Toggle voice narration on/off"),
157
+ showBubbles: z
158
+ .boolean()
159
+ .optional()
160
+ .describe("Toggle explanation bubbles on/off"),
91
161
  },
92
162
  }, async (args) => {
93
- const result = await navigateWalkthrough(args.action, args.step);
163
+ if (args.voice !== undefined)
164
+ playback.voice = args.voice;
165
+ if (args.showBubbles !== undefined)
166
+ playback.showBubbles = args.showBubbles;
167
+ if (args.action === "stop") {
168
+ stopNarration();
169
+ activeSteps = [];
170
+ return {
171
+ content: [
172
+ { type: "text", text: JSON.stringify({ ok: true, stopped: true }) },
173
+ ],
174
+ };
175
+ }
176
+ if (args.action === "pause") {
177
+ paused = true;
178
+ stopSpeaking();
179
+ return {
180
+ content: [
181
+ { type: "text", text: JSON.stringify({ ok: true, paused: true }) },
182
+ ],
183
+ };
184
+ }
185
+ if (args.action === "resume") {
186
+ paused = false;
187
+ pauseResolve?.();
188
+ return {
189
+ content: [
190
+ { type: "text", text: JSON.stringify({ ok: true, resumed: true }) },
191
+ ],
192
+ };
193
+ }
194
+ if (args.action === "next" ||
195
+ args.action === "prev" ||
196
+ args.action === "goto") {
197
+ stopNarration();
198
+ const result = await navigateWalkthrough(args.action, args.step);
199
+ if (result.active &&
200
+ playback.voice &&
201
+ typeof result.currentStep === "number") {
202
+ runNarration(result.currentStep).catch((err) => logger.error({ err }, "Narration failed"));
203
+ }
204
+ return {
205
+ content: [{ type: "text", text: JSON.stringify(result) }],
206
+ };
207
+ }
94
208
  return {
95
- content: [{ type: "text", text: JSON.stringify(result) }],
209
+ content: [
210
+ { type: "text", text: JSON.stringify({ ok: true, ...playback }) },
211
+ ],
212
+ };
213
+ });
214
+ server.registerTool("walkthrough_voice", {
215
+ description: "Change the narration voice. Speaks a sample so you hear the difference. Persisted across sessions. Use audition=true to hear voices back-to-back. Filter by locale and gender.",
216
+ inputSchema: {
217
+ voice: z
218
+ .string()
219
+ .optional()
220
+ .describe("Voice name (e.g. en-US-GuyNeural, en-US-AriaNeural)"),
221
+ list: z
222
+ .boolean()
223
+ .optional()
224
+ .describe("List available voices without playing them"),
225
+ audition: z
226
+ .boolean()
227
+ .optional()
228
+ .describe("Play voices back-to-back so you can compare"),
229
+ locale: z
230
+ .string()
231
+ .optional()
232
+ .describe("Filter by locale prefix (e.g. 'en-US', 'en', 'de')"),
233
+ gender: z
234
+ .enum(["Male", "Female"])
235
+ .optional()
236
+ .describe("Filter by gender"),
237
+ },
238
+ }, async (args, extra) => {
239
+ const voices = await listVoices();
240
+ let filtered = args.locale
241
+ ? voices.filter((v) => v.locale.toLowerCase().startsWith(args.locale.toLowerCase()))
242
+ : voices;
243
+ if (args.gender) {
244
+ filtered = filtered.filter((v) => v.gender === args.gender);
245
+ }
246
+ if (args.list) {
247
+ return {
248
+ content: [{ type: "text", text: JSON.stringify(filtered) }],
249
+ };
250
+ }
251
+ if (args.audition) {
252
+ const toAudition = args.locale
253
+ ? filtered
254
+ : filtered.filter((v) => v.locale === "en-US");
255
+ const originalVoice = getVoice();
256
+ const played = [];
257
+ const onAbort = () => stopSpeaking();
258
+ extra.signal?.addEventListener("abort", onAbort);
259
+ for (const v of toAudition) {
260
+ if (extra.signal?.aborted)
261
+ break;
262
+ if (v.name.includes("Multilingual"))
263
+ continue;
264
+ setVoice(v.name);
265
+ const name = v.name
266
+ .replace(/Neural$/, "")
267
+ .replace(/^[\w]+-[\w]+-/, "")
268
+ .replace(/-/g, " ");
269
+ await speak(`I'm ${name}. Here's how I sound narrating a code walkthrough for you.`);
270
+ played.push(v.name);
271
+ }
272
+ extra.signal?.removeEventListener("abort", onAbort);
273
+ setVoice(originalVoice);
274
+ stopSpeaking();
275
+ return {
276
+ content: [
277
+ {
278
+ type: "text",
279
+ text: JSON.stringify({
280
+ ok: true,
281
+ auditioned: played,
282
+ currentVoice: originalVoice,
283
+ }),
284
+ },
285
+ ],
286
+ };
287
+ }
288
+ if (args.voice) {
289
+ setVoice(args.voice);
290
+ const name = args.voice.replace(/Neural$/, "").replace(/-/g, " ");
291
+ await speak(`Hi, I'm ${name}. This is how I sound when narrating a code walkthrough.`);
292
+ return {
293
+ content: [
294
+ {
295
+ type: "text",
296
+ text: JSON.stringify({
297
+ ok: true,
298
+ voice: args.voice,
299
+ persisted: true,
300
+ }),
301
+ },
302
+ ],
303
+ };
304
+ }
305
+ return {
306
+ content: [
307
+ {
308
+ type: "text",
309
+ text: JSON.stringify({ currentVoice: getVoice() }),
310
+ },
311
+ ],
96
312
  };
97
313
  });
98
314
  server.registerTool("walkthrough_status", {
@@ -120,6 +336,8 @@ async function main() {
120
336
  if (cleanupStarted)
121
337
  return;
122
338
  cleanupStarted = true;
339
+ stopNarration();
340
+ cleanupTts();
123
341
  logger.info("Shutting down...");
124
342
  flushLogs();
125
343
  const timeoutId = setTimeout(() => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/tts.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export declare function getVoice(): string;
2
+ export declare function setVoice(voice: string): void;
3
+ export declare function listVoices(): Promise<{
4
+ name: string;
5
+ locale: string;
6
+ gender: string;
7
+ }[]>;
8
+ export declare function stripMarkdown(text: string): string;
9
+ export declare function speak(text: string): Promise<void>;
10
+ export declare function _speak(text: string, cmd: string, args: string[]): Promise<void>;
11
+ export declare function stopSpeaking(): void;
12
+ export declare function isSpeaking(): boolean;
13
+ export declare function cleanupTts(): void;
14
+ //# sourceMappingURL=tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAoDA,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAI5C;AAED,wBAAsB,UAAU,IAAI,OAAO,CACzC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CACnD,CAUA;AAID,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAalD;AAwFD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvD;AAED,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAgB,YAAY,IAAI,IAAI,CAKnC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAOjC"}
package/dist/tts.js ADDED
@@ -0,0 +1,182 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
3
+ import { homedir, tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { MsEdgeTTS, OUTPUT_FORMAT } from "msedge-tts";
6
+ import { logger } from "./utils/logger.js";
7
+ let currentProcess = null;
8
+ let edgeTts = null;
9
+ let edgeTtsDir = null;
10
+ let cachedVoices = null;
11
+ const DEFAULT_VOICE = "en-US-AriaNeural";
12
+ const CONFIG_DIR = join(homedir(), ".walkthrough");
13
+ const CONFIG_PATH = join(CONFIG_DIR, "config.json");
14
+ function loadConfig() {
15
+ try {
16
+ if (existsSync(CONFIG_PATH)) {
17
+ const parsed = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
18
+ if (typeof parsed?.voice === "string")
19
+ return parsed;
20
+ }
21
+ }
22
+ catch (err) {
23
+ logger.warn({ err }, "Failed to load TTS config");
24
+ }
25
+ return { voice: DEFAULT_VOICE };
26
+ }
27
+ function saveConfig(cfg) {
28
+ try {
29
+ mkdirSync(CONFIG_DIR, { recursive: true });
30
+ writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
31
+ }
32
+ catch (err) {
33
+ logger.warn({ err }, "Failed to save TTS config");
34
+ }
35
+ }
36
+ const config = loadConfig();
37
+ export function getVoice() {
38
+ return config.voice;
39
+ }
40
+ export function setVoice(voice) {
41
+ config.voice = voice;
42
+ saveConfig(config);
43
+ edgeTts = null;
44
+ }
45
+ export async function listVoices() {
46
+ if (cachedVoices)
47
+ return cachedVoices;
48
+ const tts = new MsEdgeTTS();
49
+ const voices = await tts.getVoices();
50
+ cachedVoices = voices.map((v) => ({
51
+ name: v.ShortName ?? "",
52
+ locale: v.Locale ?? "",
53
+ gender: v.Gender ?? "",
54
+ }));
55
+ return cachedVoices;
56
+ }
57
+ // --- Markdown stripping ---
58
+ export function stripMarkdown(text) {
59
+ return text
60
+ .replace(/```[\s\S]*?```/g, "")
61
+ .replace(/`([^`]+)`/g, "$1")
62
+ .replace(/\*\*([^*]+)\*\*/g, "$1")
63
+ .replace(/\*([^*]+)\*/g, "$1")
64
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
65
+ .replace(/^#{1,6}\s+/gm, "")
66
+ .replace(/^[-*+]\s+/gm, "")
67
+ .replace(/^\d+\.\s+/gm, "")
68
+ .replace(/^>\s+/gm, "")
69
+ .replace(/\n{3,}/g, "\n\n")
70
+ .trim();
71
+ }
72
+ // --- Process runner (shared by playFile and _speak) ---
73
+ function runProcess(cmd, args) {
74
+ return new Promise((resolve) => {
75
+ stopSpeaking();
76
+ try {
77
+ const proc = spawn(cmd, args, { stdio: "ignore" });
78
+ currentProcess = proc;
79
+ proc.on("close", () => {
80
+ if (currentProcess === proc)
81
+ currentProcess = null;
82
+ resolve();
83
+ });
84
+ proc.on("error", () => {
85
+ if (currentProcess === proc)
86
+ currentProcess = null;
87
+ resolve();
88
+ });
89
+ }
90
+ catch {
91
+ resolve();
92
+ }
93
+ });
94
+ }
95
+ // --- Edge TTS ---
96
+ async function getEdgeTts() {
97
+ if (!edgeTts) {
98
+ edgeTts = new MsEdgeTTS();
99
+ await edgeTts.setMetadata(config.voice, OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3);
100
+ edgeTtsDir = join(tmpdir(), `walkthrough-tts-${process.pid}`);
101
+ mkdirSync(edgeTtsDir, { recursive: true });
102
+ }
103
+ return edgeTts;
104
+ }
105
+ function getPlayerArgs(filePath) {
106
+ if (process.platform === "darwin")
107
+ return ["afplay", [filePath]];
108
+ if (process.platform === "linux")
109
+ return ["mpg123", ["-q", filePath]];
110
+ if (process.platform === "win32") {
111
+ const escaped = filePath.replace(/'/g, "''");
112
+ return [
113
+ "powershell",
114
+ [
115
+ "-Command",
116
+ `Add-Type -AssemblyName presentationCore; $p = New-Object System.Windows.Media.MediaPlayer; $p.Open([Uri]'${escaped}'); $p.Play(); Start-Sleep -Seconds 300`,
117
+ ],
118
+ ];
119
+ }
120
+ return null;
121
+ }
122
+ async function speakEdgeTts(text) {
123
+ const tts = await getEdgeTts();
124
+ if (!edgeTtsDir)
125
+ throw new Error("Edge TTS dir not initialized");
126
+ const result = await tts.toFile(edgeTtsDir, text);
127
+ const playerArgs = getPlayerArgs(result.audioFilePath);
128
+ if (playerArgs) {
129
+ await runProcess(...playerArgs);
130
+ }
131
+ try {
132
+ rmSync(result.audioFilePath, { force: true });
133
+ }
134
+ catch { }
135
+ }
136
+ // --- Native TTS fallback ---
137
+ function speakNative(text) {
138
+ if (process.platform === "darwin")
139
+ return runProcess("say", [text]);
140
+ if (process.platform === "linux")
141
+ return runProcess("espeak", [text]);
142
+ if (process.platform === "win32") {
143
+ const escaped = text.replace(/'/g, "''");
144
+ return runProcess("powershell", [
145
+ "-Command",
146
+ `Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak('${escaped}')`,
147
+ ]);
148
+ }
149
+ return Promise.resolve();
150
+ }
151
+ // --- Public API ---
152
+ export async function speak(text) {
153
+ try {
154
+ await speakEdgeTts(text);
155
+ }
156
+ catch (err) {
157
+ logger.warn({ err }, "Edge TTS failed, falling back to native");
158
+ await speakNative(text);
159
+ }
160
+ }
161
+ export function _speak(text, cmd, args) {
162
+ return runProcess(cmd, [...args, text]);
163
+ }
164
+ export function stopSpeaking() {
165
+ if (currentProcess) {
166
+ currentProcess.kill();
167
+ currentProcess = null;
168
+ }
169
+ }
170
+ export function isSpeaking() {
171
+ return currentProcess !== null;
172
+ }
173
+ export function cleanupTts() {
174
+ stopSpeaking();
175
+ if (edgeTtsDir) {
176
+ try {
177
+ rmSync(edgeTtsDir, { recursive: true, force: true });
178
+ }
179
+ catch { }
180
+ }
181
+ }
182
+ //# sourceMappingURL=tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.js","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-walkthrough",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "MCP server for interactive code walkthroughs - Claude-driven code tours",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,6 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@modelcontextprotocol/sdk": "^1.18.1",
46
+ "msedge-tts": "^2.0.4",
46
47
  "pino": "^10.0.0",
47
48
  "zod": "^3.25.0"
48
49
  },