mcp-walkthrough 0.2.1 → 0.2.4

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,73 @@ 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.
126
+
127
+ ### walkthrough_control
120
128
 
121
- ### walkthrough_navigate
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
+
153
+ ### Configuration
154
+
155
+ All settings are persisted to `~/.walkthrough/config.json` and survive server restarts:
156
+
157
+ - **voice** — Selected voice name (default: `en-US-AriaNeural`)
158
+ - **voiceEnabled** — Voice narration on/off (default: `true`)
159
+ - **showBubbles** — Explanation bubbles on/off (default: `true`)
160
+
161
+ Toggle voice and bubbles on the fly via `walkthrough_control` — changes persist immediately.
162
+
129
163
  ### Keyboard Shortcuts
130
164
 
131
- During an active walkthrough:
132
- - **Cmd+Shift+Right** — Next step
133
- - **Cmd+Shift+Left** — Previous step
165
+ During an active walkthrough (shown in the explanation bubble):
166
+ - **Cmd+Shift+Right** (macOS) / **Ctrl+Shift+Right** (Linux/Windows) — Next step
167
+ - **Cmd+Shift+Left** (macOS) / **Ctrl+Shift+Left** (Linux/Windows) — Previous step
134
168
  - **Status bar** — Shows current step, click to stop
135
169
 
136
170
  ### Writing Explanations
137
171
 
138
- Explanations render as markdown in VS Code comment bubbles. Tips:
172
+ Explanations render as markdown in VS Code comment bubbles and are also narrated as speech. Tips:
139
173
 
174
+ - **Write as natural speech** — the voice reads it aloud, so avoid heavy markdown
140
175
  - **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
176
+ - **Avoid `##` headers** — they render too large in the comment bubble. Use **bold** instead
177
+ - Inline code, code blocks, lists, and links all work in bubbles
143
178
 
144
179
  ## How It Works
145
180
 
@@ -165,6 +200,8 @@ mcp-walkthrough/
165
200
  │ ├── index.ts # MCP server entry point, tool registration
166
201
  │ ├── bridge.ts # Unix socket client to VS Code extension
167
202
  │ ├── code-cli.ts # Cross-platform VS Code CLI discovery
203
+ │ ├── config.ts # Persisted walkthrough settings (~/.walkthrough/)
204
+ │ ├── tts.ts # Text-to-speech (Edge TTS + native fallback)
168
205
  │ ├── socket.ts # Socket path computation and discovery
169
206
  │ └── utils/
170
207
  │ └── logger.ts # Pino logger (stderr only)
@@ -178,7 +215,8 @@ mcp-walkthrough/
178
215
  │ ├── bridge.test.ts
179
216
  │ ├── code-cli.test.ts
180
217
  │ ├── postinstall.test.ts
181
- └── socket.test.ts
218
+ ├── socket.test.ts
219
+ │ └── tts.test.ts
182
220
  └── docs/
183
221
  ```
184
222
 
@@ -0,0 +1,8 @@
1
+ export interface WalkthroughConfig {
2
+ voice: string;
3
+ voiceEnabled: boolean;
4
+ showBubbles: boolean;
5
+ }
6
+ export declare function getConfig(): WalkthroughConfig;
7
+ export declare function updateConfig(opts: Partial<WalkthroughConfig>): void;
8
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;CACtB;AAiCD,wBAAgB,SAAS,IAAI,iBAAiB,CAE7C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAKnE"}
package/dist/config.js ADDED
@@ -0,0 +1,48 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { logger } from "./utils/logger.js";
5
+ const CONFIG_DIR = join(homedir(), ".walkthrough");
6
+ const CONFIG_PATH = join(CONFIG_DIR, "config.json");
7
+ const DEFAULTS = {
8
+ voice: "en-US-AriaNeural",
9
+ voiceEnabled: true,
10
+ showBubbles: true,
11
+ };
12
+ function load() {
13
+ try {
14
+ if (existsSync(CONFIG_PATH)) {
15
+ const parsed = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
16
+ if (typeof parsed?.voice === "string") {
17
+ return { ...DEFAULTS, ...parsed };
18
+ }
19
+ }
20
+ }
21
+ catch (err) {
22
+ logger.warn({ err }, "Failed to load walkthrough config");
23
+ }
24
+ return { ...DEFAULTS };
25
+ }
26
+ function save(cfg) {
27
+ try {
28
+ mkdirSync(CONFIG_DIR, { recursive: true });
29
+ writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
30
+ }
31
+ catch (err) {
32
+ logger.warn({ err }, "Failed to save walkthrough config");
33
+ }
34
+ }
35
+ const config = load();
36
+ export function getConfig() {
37
+ return { ...config };
38
+ }
39
+ export function updateConfig(opts) {
40
+ if (opts.voice !== undefined)
41
+ config.voice = opts.voice;
42
+ if (opts.voiceEnabled !== undefined)
43
+ config.voiceEnabled = opts.voiceEnabled;
44
+ if (opts.showBubbles !== undefined)
45
+ config.showBubbles = opts.showBubbles;
46
+ save(config);
47
+ }
48
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACnD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAQpD,MAAM,QAAQ,GAAsB;IAClC,KAAK,EAAE,kBAAkB;IACzB,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF,SAAS,IAAI;IACX,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;YAC9D,IAAI,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,mCAAmC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,IAAI,CAAC,GAAsB;IAClC,IAAI,CAAC;QACH,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,mCAAmC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;AAEtB,MAAM,UAAU,SAAS;IACvB,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAgC;IAC3D,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACxD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IAC7E,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IAC1E,IAAI,CAAC,MAAM,CAAC,CAAC;AACf,CAAC"}
package/dist/index.js CHANGED
@@ -6,6 +6,8 @@ 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 { getConfig, updateConfig } from "./config.js";
10
+ import { cleanupTts, listVoices, speak, stopSpeaking, stripMarkdown, } from "./tts.js";
9
11
  import { flushLogs, logger } from "./utils/logger.js";
10
12
  const __filename = fileURLToPath(import.meta.url);
11
13
  const __dirname = dirname(__filename);
@@ -42,6 +44,9 @@ server.registerTool("explain_code", {
42
44
  },
43
45
  }, async (args) => {
44
46
  const result = await showExplanation(args.file, args.line, args.endLine, args.explanation, args.title, args.startChar, args.endChar);
47
+ if (getConfig().voiceEnabled) {
48
+ speak(stripMarkdown(args.explanation), getConfig().voice).catch((err) => logger.warn({ err }, "TTS failed for explain_code"));
49
+ }
45
50
  return {
46
51
  content: [{ type: "text", text: JSON.stringify(result) }],
47
52
  };
@@ -61,38 +66,243 @@ const stepSchema = z.object({
61
66
  explanation: z.string().describe("Markdown explanation"),
62
67
  title: z.string().optional().describe("Step title"),
63
68
  });
69
+ // --- Walkthrough state ---
70
+ let activeSteps = [];
71
+ let narrationAbort = null;
72
+ let paused = false;
73
+ let pauseResolve = null;
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 (getConfig().voiceEnabled) {
92
+ const step = activeSteps[i];
93
+ if (step) {
94
+ const text = stripMarkdown(step.explanation);
95
+ await speak(text, getConfig().voice);
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
+ updateConfig({ voiceEnabled: args.voice, showBubbles: args.showBubbles });
129
+ paused = false;
130
+ const result = await startWalkthrough(activeSteps, false);
131
+ runNarration(0).catch((err) => logger.error({ err }, "Narration failed"));
79
132
  return {
80
- content: [{ type: "text", text: JSON.stringify(result) }],
133
+ content: [
134
+ { type: "text", text: JSON.stringify(result) },
135
+ {
136
+ type: "text",
137
+ text: "Controls: next | prev | pause | resume | stop — use walkthrough_control. Toggle voice/bubbles on the fly.",
138
+ },
139
+ ],
81
140
  };
82
141
  });
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.",
142
+ server.registerTool("walkthrough_control", {
143
+ 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
144
  inputSchema: {
86
- action: z.enum(["next", "prev", "goto"]).describe("Navigation action"),
145
+ action: z
146
+ .enum(["next", "prev", "goto", "stop", "pause", "resume"])
147
+ .optional()
148
+ .describe("Navigation or playback action"),
87
149
  step: z
88
150
  .number()
89
151
  .optional()
90
152
  .describe("Step index (0-based) for goto action"),
153
+ voice: z.boolean().optional().describe("Toggle voice narration on/off"),
154
+ showBubbles: z
155
+ .boolean()
156
+ .optional()
157
+ .describe("Toggle explanation bubbles on/off"),
91
158
  },
92
159
  }, async (args) => {
93
- const result = await navigateWalkthrough(args.action, args.step);
160
+ updateConfig({ voiceEnabled: args.voice, showBubbles: args.showBubbles });
161
+ if (args.action === "stop") {
162
+ stopNarration();
163
+ activeSteps = [];
164
+ return {
165
+ content: [
166
+ { type: "text", text: JSON.stringify({ ok: true, stopped: true }) },
167
+ ],
168
+ };
169
+ }
170
+ if (args.action === "pause") {
171
+ paused = true;
172
+ stopSpeaking();
173
+ return {
174
+ content: [
175
+ { type: "text", text: JSON.stringify({ ok: true, paused: true }) },
176
+ ],
177
+ };
178
+ }
179
+ if (args.action === "resume") {
180
+ paused = false;
181
+ pauseResolve?.();
182
+ return {
183
+ content: [
184
+ { type: "text", text: JSON.stringify({ ok: true, resumed: true }) },
185
+ ],
186
+ };
187
+ }
188
+ if (args.action === "next" ||
189
+ args.action === "prev" ||
190
+ args.action === "goto") {
191
+ stopNarration();
192
+ const result = await navigateWalkthrough(args.action, args.step);
193
+ if (result.active &&
194
+ getConfig().voiceEnabled &&
195
+ typeof result.currentStep === "number") {
196
+ runNarration(result.currentStep).catch((err) => logger.error({ err }, "Narration failed"));
197
+ }
198
+ return {
199
+ content: [{ type: "text", text: JSON.stringify(result) }],
200
+ };
201
+ }
94
202
  return {
95
- content: [{ type: "text", text: JSON.stringify(result) }],
203
+ content: [
204
+ { type: "text", text: JSON.stringify({ ok: true, ...getConfig() }) },
205
+ ],
206
+ };
207
+ });
208
+ server.registerTool("walkthrough_voice", {
209
+ 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.",
210
+ inputSchema: {
211
+ voice: z
212
+ .string()
213
+ .optional()
214
+ .describe("Voice name (e.g. en-US-GuyNeural, en-US-AriaNeural)"),
215
+ list: z
216
+ .boolean()
217
+ .optional()
218
+ .describe("List available voices without playing them"),
219
+ audition: z
220
+ .boolean()
221
+ .optional()
222
+ .describe("Play voices back-to-back so you can compare"),
223
+ locale: z
224
+ .string()
225
+ .optional()
226
+ .describe("Filter by locale prefix (e.g. 'en-US', 'en', 'de')"),
227
+ gender: z
228
+ .enum(["Male", "Female"])
229
+ .optional()
230
+ .describe("Filter by gender"),
231
+ },
232
+ }, async (args, extra) => {
233
+ const voices = await listVoices();
234
+ let filtered = args.locale
235
+ ? voices.filter((v) => v.locale.toLowerCase().startsWith(args.locale.toLowerCase()))
236
+ : voices;
237
+ if (args.gender) {
238
+ filtered = filtered.filter((v) => v.gender === args.gender);
239
+ }
240
+ if (args.list) {
241
+ return {
242
+ content: [{ type: "text", text: JSON.stringify(filtered) }],
243
+ };
244
+ }
245
+ if (args.audition) {
246
+ const toAudition = args.locale
247
+ ? filtered
248
+ : filtered.filter((v) => v.locale === "en-US");
249
+ const originalVoice = getConfig().voice;
250
+ const played = [];
251
+ const onAbort = () => stopSpeaking();
252
+ extra.signal?.addEventListener("abort", onAbort);
253
+ for (const v of toAudition) {
254
+ if (extra.signal?.aborted)
255
+ break;
256
+ if (v.name.includes("Multilingual"))
257
+ continue;
258
+ updateConfig({ voice: v.name });
259
+ const name = v.name
260
+ .replace(/Neural$/, "")
261
+ .replace(/^[\w]+-[\w]+-/, "")
262
+ .replace(/-/g, " ");
263
+ await speak(`I'm ${name}. Here's how I sound narrating a code walkthrough for you.`, v.name);
264
+ played.push(v.name);
265
+ }
266
+ extra.signal?.removeEventListener("abort", onAbort);
267
+ updateConfig({ voice: originalVoice });
268
+ stopSpeaking();
269
+ return {
270
+ content: [
271
+ {
272
+ type: "text",
273
+ text: JSON.stringify({
274
+ ok: true,
275
+ auditioned: played,
276
+ currentVoice: originalVoice,
277
+ }),
278
+ },
279
+ ],
280
+ };
281
+ }
282
+ if (args.voice) {
283
+ updateConfig({ voice: args.voice });
284
+ const name = args.voice.replace(/Neural$/, "").replace(/-/g, " ");
285
+ await speak(`Hi, I'm ${name}. This is how I sound when narrating a code walkthrough.`, args.voice);
286
+ return {
287
+ content: [
288
+ {
289
+ type: "text",
290
+ text: JSON.stringify({
291
+ ok: true,
292
+ voice: args.voice,
293
+ persisted: true,
294
+ }),
295
+ },
296
+ ],
297
+ };
298
+ }
299
+ return {
300
+ content: [
301
+ {
302
+ type: "text",
303
+ text: JSON.stringify({ currentVoice: getConfig().voice }),
304
+ },
305
+ ],
96
306
  };
97
307
  });
98
308
  server.registerTool("walkthrough_status", {
@@ -120,6 +330,8 @@ async function main() {
120
330
  if (cleanupStarted)
121
331
  return;
122
332
  cleanupStarted = true;
333
+ stopNarration();
334
+ cleanupTts();
123
335
  logger.info("Shutting down...");
124
336
  flushLogs();
125
337
  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,12 @@
1
+ export declare function listVoices(): Promise<{
2
+ name: string;
3
+ locale: string;
4
+ gender: string;
5
+ }[]>;
6
+ export declare function stripMarkdown(text: string): string;
7
+ export declare function speak(text: string, voice: string): Promise<void>;
8
+ export declare function _speak(text: string, cmd: string, args: string[]): Promise<void>;
9
+ export declare function stopSpeaking(): void;
10
+ export declare function isSpeaking(): boolean;
11
+ export declare function cleanupTts(): void;
12
+ //# sourceMappingURL=tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAgBA,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;AAyFD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtE;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,151 @@
1
+ import { spawn } from "node:child_process";
2
+ import { mkdirSync, rmSync } from "node:fs";
3
+ import { 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 currentVoice = null;
11
+ let cachedVoices = null;
12
+ // --- Voice list ---
13
+ export async function listVoices() {
14
+ if (cachedVoices)
15
+ return cachedVoices;
16
+ const tts = new MsEdgeTTS();
17
+ const voices = await tts.getVoices();
18
+ cachedVoices = voices.map((v) => ({
19
+ name: v.ShortName ?? "",
20
+ locale: v.Locale ?? "",
21
+ gender: v.Gender ?? "",
22
+ }));
23
+ return cachedVoices;
24
+ }
25
+ // --- Markdown stripping ---
26
+ export function stripMarkdown(text) {
27
+ return text
28
+ .replace(/```[\s\S]*?```/g, "")
29
+ .replace(/`([^`]+)`/g, "$1")
30
+ .replace(/\*\*([^*]+)\*\*/g, "$1")
31
+ .replace(/\*([^*]+)\*/g, "$1")
32
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
33
+ .replace(/^#{1,6}\s+/gm, "")
34
+ .replace(/^[-*+]\s+/gm, "")
35
+ .replace(/^\d+\.\s+/gm, "")
36
+ .replace(/^>\s+/gm, "")
37
+ .replace(/\n{3,}/g, "\n\n")
38
+ .trim();
39
+ }
40
+ // --- Process runner ---
41
+ function runProcess(cmd, args) {
42
+ return new Promise((resolve) => {
43
+ stopSpeaking();
44
+ try {
45
+ const proc = spawn(cmd, args, { stdio: "ignore" });
46
+ currentProcess = proc;
47
+ proc.on("close", () => {
48
+ if (currentProcess === proc)
49
+ currentProcess = null;
50
+ resolve();
51
+ });
52
+ proc.on("error", () => {
53
+ if (currentProcess === proc)
54
+ currentProcess = null;
55
+ resolve();
56
+ });
57
+ }
58
+ catch {
59
+ resolve();
60
+ }
61
+ });
62
+ }
63
+ // --- Edge TTS ---
64
+ async function getEdgeTts(voice) {
65
+ if (!edgeTts || currentVoice !== voice) {
66
+ edgeTts = new MsEdgeTTS();
67
+ await edgeTts.setMetadata(voice, OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3);
68
+ currentVoice = voice;
69
+ edgeTtsDir = join(tmpdir(), `walkthrough-tts-${process.pid}`);
70
+ mkdirSync(edgeTtsDir, { recursive: true });
71
+ }
72
+ return edgeTts;
73
+ }
74
+ function getPlayerArgs(filePath) {
75
+ if (process.platform === "darwin")
76
+ return ["afplay", [filePath]];
77
+ if (process.platform === "linux")
78
+ return ["mpg123", ["-q", filePath]];
79
+ if (process.platform === "win32") {
80
+ const escaped = filePath.replace(/'/g, "''");
81
+ return [
82
+ "powershell",
83
+ [
84
+ "-Command",
85
+ `Add-Type -AssemblyName presentationCore; $p = New-Object System.Windows.Media.MediaPlayer; $p.Open([Uri]'${escaped}'); $p.Play(); Start-Sleep -Seconds 300`,
86
+ ],
87
+ ];
88
+ }
89
+ return null;
90
+ }
91
+ async function speakEdgeTts(text, voice) {
92
+ const tts = await getEdgeTts(voice);
93
+ if (!edgeTtsDir)
94
+ throw new Error("Edge TTS dir not initialized");
95
+ const result = await tts.toFile(edgeTtsDir, text);
96
+ const playerArgs = getPlayerArgs(result.audioFilePath);
97
+ if (playerArgs) {
98
+ await runProcess(...playerArgs);
99
+ }
100
+ try {
101
+ rmSync(result.audioFilePath, { force: true });
102
+ }
103
+ catch { }
104
+ }
105
+ // --- Native TTS fallback ---
106
+ function speakNative(text) {
107
+ if (process.platform === "darwin")
108
+ return runProcess("say", [text]);
109
+ if (process.platform === "linux")
110
+ return runProcess("espeak", [text]);
111
+ if (process.platform === "win32") {
112
+ const escaped = text.replace(/'/g, "''");
113
+ return runProcess("powershell", [
114
+ "-Command",
115
+ `Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak('${escaped}')`,
116
+ ]);
117
+ }
118
+ return Promise.resolve();
119
+ }
120
+ // --- Public API ---
121
+ export async function speak(text, voice) {
122
+ try {
123
+ await speakEdgeTts(text, voice);
124
+ }
125
+ catch (err) {
126
+ logger.warn({ err }, "Edge TTS failed, falling back to native");
127
+ await speakNative(text);
128
+ }
129
+ }
130
+ export function _speak(text, cmd, args) {
131
+ return runProcess(cmd, [...args, text]);
132
+ }
133
+ export function stopSpeaking() {
134
+ if (currentProcess) {
135
+ currentProcess.kill();
136
+ currentProcess = null;
137
+ }
138
+ }
139
+ export function isSpeaking() {
140
+ return currentProcess !== null;
141
+ }
142
+ export function cleanupTts() {
143
+ stopSpeaking();
144
+ if (edgeTtsDir) {
145
+ try {
146
+ rmSync(edgeTtsDir, { recursive: true, force: true });
147
+ }
148
+ catch { }
149
+ }
150
+ }
151
+ //# 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.4",
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
  },