mcp-walkthrough 0.1.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 ADDED
@@ -0,0 +1,221 @@
1
+ [![NPM Version](https://img.shields.io/npm/v/mcp-walkthrough)](https://www.npmjs.com/package/mcp-walkthrough)
2
+ [![NPM Downloads](https://img.shields.io/npm/dm/mcp-walkthrough)](https://www.npmjs.com/package/mcp-walkthrough)
3
+ [![CI Status](https://github.com/Stefan-Nitu/mcp-walkthrough/actions/workflows/ci.yml/badge.svg)](https://github.com/Stefan-Nitu/mcp-walkthrough/actions/workflows/ci.yml)
4
+ [![MIT Licensed](https://img.shields.io/npm/l/mcp-walkthrough)](https://github.com/Stefan-Nitu/mcp-walkthrough/blob/main/LICENSE)
5
+
6
+ # MCP Walkthrough
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.
9
+
10
+ ## Overview
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.
13
+
14
+ **Key Features:**
15
+ - **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
18
+ - **Keyboard Navigation** — `Cmd+Shift+Right` / `Cmd+Shift+Left` to navigate steps
19
+ - **Selection Reading** — Claude can see what you've highlighted to discuss it further
20
+ - **Focus Preservation** — Opens files without stealing focus from your terminal
21
+
22
+ > **Note:** This MCP server requires VS Code. It includes a companion VS Code extension that is automatically installed on first run.
23
+
24
+ ## Installation
25
+
26
+ ### Via npm (Recommended)
27
+
28
+ ```bash
29
+ npm install -g mcp-walkthrough
30
+ ```
31
+
32
+ ### From Source
33
+
34
+ ```bash
35
+ git clone https://github.com/Stefan-Nitu/mcp-walkthrough.git
36
+ cd mcp-walkthrough
37
+ bun install
38
+ bun run build
39
+ ```
40
+
41
+ > Requires Bun v1.3.8+ (development) and Node.js v18+ (runtime)
42
+
43
+ ## Quick Start
44
+
45
+ ### With Claude Code
46
+
47
+ Add to `~/.claude.json`:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "mcp-walkthrough": {
53
+ "command": "npx",
54
+ "args": ["-y", "mcp-walkthrough"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ Or if installed globally:
61
+
62
+ ```json
63
+ {
64
+ "mcpServers": {
65
+ "mcp-walkthrough": {
66
+ "command": "mcp-walkthrough"
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ Restart Claude Code to pick up the new server.
73
+
74
+ ### Add a CLAUDE.md hint
75
+
76
+ MCP tools are deferred (loaded on-demand), so Claude may not use them automatically. Add this to your project's `CLAUDE.md`:
77
+
78
+ ```markdown
79
+ ## Walkthrough MCP
80
+
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.
82
+ ```
83
+
84
+ ## Available Tools
85
+
86
+ | Tool | Description |
87
+ |------|-------------|
88
+ | **show_code** | Open a file and highlight specific lines |
89
+ | **explain_code** | Highlight lines + show an inline markdown explanation bubble |
90
+ | **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
+ | **get_selection** | Read the currently highlighted code in VS Code |
95
+
96
+ ### walkthrough
97
+
98
+ The main tool. Claude generates all steps and sends them at once. The VS Code extension handles navigation.
99
+
100
+ ```json
101
+ {
102
+ "steps": [
103
+ {
104
+ "file": "/absolute/path/to/file.ts",
105
+ "line": 10,
106
+ "endLine": 25,
107
+ "explanation": "## Auth Middleware\n\nThis validates the JWT token on every request.",
108
+ "title": "Token Validation"
109
+ }
110
+ ],
111
+ "autoplay": false,
112
+ "delayMs": 5000
113
+ }
114
+ ```
115
+
116
+ **Parameters:**
117
+ - `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)
120
+
121
+ ### walkthrough_navigate
122
+
123
+ ```json
124
+ { "action": "next" }
125
+ { "action": "prev" }
126
+ { "action": "goto", "step": 3 }
127
+ ```
128
+
129
+ ### Keyboard Shortcuts
130
+
131
+ During an active walkthrough:
132
+ - **Cmd+Shift+Right** — Next step
133
+ - **Cmd+Shift+Left** — Previous step
134
+ - **Status bar** — Shows current step, click to stop
135
+
136
+ ## How It Works
137
+
138
+ ```
139
+ Claude Code → MCP Server (stdio) → HTTP localhost:7890 → VS Code Extension → Editor API
140
+ ```
141
+
142
+ 1. Claude calls walkthrough tools via MCP
143
+ 2. The MCP server forwards requests to a companion VS Code extension over HTTP
144
+ 3. The extension uses the VS Code API to open files, select ranges, and create comment threads
145
+ 4. Focus stays in your terminal — code appears in the editor beside it
146
+
147
+ The VS Code extension is bundled with the npm package and automatically installed on first run.
148
+
149
+ ## Development
150
+
151
+ ### Project Structure
152
+
153
+ ```
154
+ mcp-walkthrough/
155
+ ├── src/
156
+ │ ├── index.ts # MCP server entry point, tool registration
157
+ │ ├── bridge.ts # HTTP client to VS Code extension
158
+ │ └── utils/
159
+ │ └── logger.ts # Pino logger (stderr only)
160
+ ├── vscode-extension/
161
+ │ ├── src/
162
+ │ │ └── extension.ts # VS Code extension (HTTP server, Comments API)
163
+ │ └── package.json
164
+ ├── tests/
165
+ │ └── bridge.test.ts
166
+ └── docs/
167
+ ```
168
+
169
+ ### Testing
170
+
171
+ ```bash
172
+ bun test # Run all tests
173
+ bun test --watch # Watch mode
174
+ bun run typecheck # Type checking
175
+ bun run lint # Linting
176
+ bun run check # Full check (typecheck + lint)
177
+ ```
178
+
179
+ ### Building
180
+
181
+ ```bash
182
+ bun run build # Builds MCP server + VS Code extension
183
+ ```
184
+
185
+ The build script syncs the version from root `package.json` into the extension before packaging.
186
+
187
+ ## Troubleshooting
188
+
189
+ ### Tools return "This MCP server only works from VS Code."
190
+
191
+ The MCP server pings the VS Code extension on startup. If the extension isn't running:
192
+
193
+ 1. Make sure you're running Claude Code inside VS Code (not a standalone terminal)
194
+ 2. The extension activates on VS Code startup — try reloading the window (`Cmd+Shift+P` → "Reload Window")
195
+
196
+ ### Extension not installed
197
+
198
+ The MCP server auto-installs the extension on first run via `code --install-extension`. If this fails:
199
+
200
+ 1. Verify the `code` CLI is available in your terminal
201
+ 2. Manually install: `code --install-extension path/to/walkthrough-bridge.vsix`
202
+
203
+ ## Contributing
204
+
205
+ 1. Fork the repository
206
+ 2. Create a feature branch
207
+ 3. **Write tests first** (TDD approach)
208
+ 4. Implement the feature
209
+ 5. Ensure all tests pass (`bun test`)
210
+ 6. Run linting (`bun run lint`)
211
+ 7. Submit a pull request
212
+
213
+ ## License
214
+
215
+ MIT
216
+
217
+ ## Related Projects
218
+
219
+ - [Model Context Protocol](https://modelcontextprotocol.io) - MCP specification and documentation
220
+ - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) - SDK used by this server
221
+ - [MCP Claude Code Conversation History](https://github.com/Stefan-Nitu/mcp-claude-code-conversation-history) - MCP server for searching Claude Code conversations
@@ -0,0 +1,22 @@
1
+ export declare function ensureExtensionInstalled(): void;
2
+ type BridgeResult = Record<string, unknown>;
3
+ export declare let bridgeAvailable: boolean | null;
4
+ export declare function resetBridgeState(): void;
5
+ export declare function checkBridge(): Promise<boolean>;
6
+ export declare function isBridgeAvailable(): boolean;
7
+ export declare function openFile(file: string, line: number, endLine?: number): Promise<BridgeResult>;
8
+ export declare function showExplanation(file: string, line: number, endLine: number | undefined, explanation: string, title?: string): Promise<BridgeResult>;
9
+ export declare function clearExplanations(): Promise<BridgeResult>;
10
+ export interface WalkthroughStep {
11
+ file: string;
12
+ line: number;
13
+ endLine?: number;
14
+ explanation: string;
15
+ title?: string;
16
+ }
17
+ export declare function startWalkthrough(steps: WalkthroughStep[], autoplay?: boolean, delayMs?: number): Promise<BridgeResult>;
18
+ export declare function navigateWalkthrough(action: string, step?: number): Promise<BridgeResult>;
19
+ export declare function getWalkthroughStatus(): Promise<BridgeResult>;
20
+ export declare function getSelection(): Promise<BridgeResult>;
21
+ export {};
22
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAgBA,wBAAgB,wBAAwB,IAAI,IAAI,CAsB/C;AAED,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5C,eAAO,IAAI,eAAe,EAAE,OAAO,GAAG,IAAW,CAAC;AAElD,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAcpD;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAyBD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,YAAY,CAAC,CAE/D;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,eAAe,EAAE,EACxB,QAAQ,CAAC,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAElE;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,CAE1D"}
package/dist/bridge.js ADDED
@@ -0,0 +1,96 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { logger } from "./utils/logger.js";
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+ const EXTENSION_ID = "undefined_publisher.walkthrough-bridge";
9
+ const VSIX_PATH = join(__dirname, "../vscode-extension/walkthrough-bridge.vsix");
10
+ const BRIDGE_URL = "http://127.0.0.1:7890";
11
+ export function ensureExtensionInstalled() {
12
+ try {
13
+ const installed = execSync("code --list-extensions", { encoding: "utf-8" });
14
+ if (installed.includes(EXTENSION_ID)) {
15
+ logger.info("Walkthrough bridge extension already installed");
16
+ return;
17
+ }
18
+ }
19
+ catch {
20
+ logger.warn("Could not check installed extensions");
21
+ }
22
+ if (!existsSync(VSIX_PATH)) {
23
+ logger.error({ path: VSIX_PATH }, "Extension .vsix not found");
24
+ return;
25
+ }
26
+ try {
27
+ execSync(`code --install-extension "${VSIX_PATH}"`, { encoding: "utf-8" });
28
+ logger.info("Installed walkthrough bridge extension");
29
+ }
30
+ catch (error) {
31
+ logger.error({ err: error }, "Failed to install extension");
32
+ }
33
+ }
34
+ export let bridgeAvailable = null;
35
+ export function resetBridgeState() {
36
+ bridgeAvailable = null;
37
+ }
38
+ export async function checkBridge() {
39
+ try {
40
+ const res = await fetch(`${BRIDGE_URL}/ping`, {
41
+ method: "POST",
42
+ headers: { "Content-Type": "application/json" },
43
+ body: "{}",
44
+ });
45
+ const data = (await res.json());
46
+ bridgeAvailable = data.ok === true;
47
+ }
48
+ catch {
49
+ bridgeAvailable = false;
50
+ }
51
+ logger.info({ bridgeAvailable }, "Bridge status");
52
+ return bridgeAvailable;
53
+ }
54
+ export function isBridgeAvailable() {
55
+ return bridgeAvailable === true;
56
+ }
57
+ const BRIDGE_UNAVAILABLE_ERROR = "This MCP server only works from VS Code.";
58
+ async function bridgeRequest(endpoint, data = {}) {
59
+ if (bridgeAvailable === false) {
60
+ return { ok: false, error: BRIDGE_UNAVAILABLE_ERROR };
61
+ }
62
+ try {
63
+ const res = await fetch(`${BRIDGE_URL}${endpoint}`, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify(data),
67
+ });
68
+ return (await res.json());
69
+ }
70
+ catch {
71
+ bridgeAvailable = false;
72
+ return { ok: false, error: BRIDGE_UNAVAILABLE_ERROR };
73
+ }
74
+ }
75
+ export async function openFile(file, line, endLine) {
76
+ return bridgeRequest("/open", { file, line, endLine });
77
+ }
78
+ export async function showExplanation(file, line, endLine, explanation, title) {
79
+ return bridgeRequest("/explain", { file, line, endLine, explanation, title });
80
+ }
81
+ export async function clearExplanations() {
82
+ return bridgeRequest("/clear");
83
+ }
84
+ export async function startWalkthrough(steps, autoplay, delayMs) {
85
+ return bridgeRequest("/walkthrough", { steps, autoplay, delayMs });
86
+ }
87
+ export async function navigateWalkthrough(action, step) {
88
+ return bridgeRequest("/walkthrough/navigate", { action, step });
89
+ }
90
+ export async function getWalkthroughStatus() {
91
+ return bridgeRequest("/walkthrough/status");
92
+ }
93
+ export async function getSelection() {
94
+ return bridgeRequest("/selection");
95
+ }
96
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { z } from "zod";
8
+ import { checkBridge, clearExplanations, ensureExtensionInstalled, getSelection, getWalkthroughStatus, navigateWalkthrough, openFile, showExplanation, startWalkthrough, } from "./bridge.js";
9
+ import { flushLogs, logger } from "./utils/logger.js";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ const packageJson = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
13
+ const server = new McpServer({
14
+ name: "mcp-walkthrough",
15
+ version: packageJson.version,
16
+ });
17
+ server.registerTool("show_code", {
18
+ description: "Open a file in VS Code and highlight specific lines. Use this to walk the user through code.",
19
+ inputSchema: {
20
+ file: z.string().describe("Absolute path to the file"),
21
+ line: z.number().describe("Start line (1-based)"),
22
+ endLine: z.number().optional().describe("End line (1-based)"),
23
+ },
24
+ }, async (args) => {
25
+ const result = await openFile(args.file, args.line, args.endLine);
26
+ return {
27
+ content: [{ type: "text", text: JSON.stringify(result) }],
28
+ };
29
+ });
30
+ server.registerTool("explain_code", {
31
+ description: "Open a file in VS Code, highlight lines, and show an inline markdown explanation bubble. Use this to walk the user through code with rich annotations.",
32
+ inputSchema: {
33
+ file: z.string().describe("Absolute path to the file"),
34
+ line: z.number().describe("Start line (1-based)"),
35
+ endLine: z.number().optional().describe("End line (1-based)"),
36
+ explanation: z.string().describe("Markdown explanation to display"),
37
+ title: z.string().optional().describe("Title for the explanation"),
38
+ },
39
+ }, async (args) => {
40
+ const result = await showExplanation(args.file, args.line, args.endLine, args.explanation, args.title);
41
+ return {
42
+ content: [{ type: "text", text: JSON.stringify(result) }],
43
+ };
44
+ });
45
+ server.registerTool("clear_explanations", {
46
+ description: "Remove all walkthrough explanation bubbles from the editor.",
47
+ }, async () => {
48
+ const result = await clearExplanations();
49
+ return {
50
+ content: [{ type: "text", text: JSON.stringify(result) }],
51
+ };
52
+ });
53
+ const stepSchema = z.object({
54
+ file: z.string().describe("Absolute path to the file"),
55
+ line: z.number().describe("Start line (1-based)"),
56
+ endLine: z.number().optional().describe("End line (1-based)"),
57
+ explanation: z.string().describe("Markdown explanation"),
58
+ title: z.string().optional().describe("Step title"),
59
+ });
60
+ server.registerTool("walkthrough", {
61
+ 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.",
62
+ inputSchema: {
63
+ steps: z.array(stepSchema).describe("Array of walkthrough steps"),
64
+ autoplay: z
65
+ .boolean()
66
+ .optional()
67
+ .describe("Auto-advance through steps (default: false)"),
68
+ delayMs: z
69
+ .number()
70
+ .optional()
71
+ .describe("Delay between steps in ms when autoplay is on (default: 5000)"),
72
+ },
73
+ }, async (args) => {
74
+ const result = await startWalkthrough(args.steps, args.autoplay, args.delayMs);
75
+ return {
76
+ content: [{ type: "text", text: JSON.stringify(result) }],
77
+ };
78
+ });
79
+ server.registerTool("walkthrough_navigate", {
80
+ description: "Navigate an active walkthrough. Use when the user says next, back, or asks to jump to a step. Returns the current step state.",
81
+ inputSchema: {
82
+ action: z.enum(["next", "prev", "goto"]).describe("Navigation action"),
83
+ step: z
84
+ .number()
85
+ .optional()
86
+ .describe("Step index (0-based) for goto action"),
87
+ },
88
+ }, async (args) => {
89
+ const result = await navigateWalkthrough(args.action, args.step);
90
+ return {
91
+ content: [{ type: "text", text: JSON.stringify(result) }],
92
+ };
93
+ });
94
+ server.registerTool("walkthrough_status", {
95
+ description: "Get the current state of an active walkthrough — which step, total steps, step details.",
96
+ }, async () => {
97
+ const result = await getWalkthroughStatus();
98
+ return {
99
+ content: [{ type: "text", text: JSON.stringify(result) }],
100
+ };
101
+ });
102
+ server.registerTool("get_selection", {
103
+ description: "Get the currently selected/highlighted code in VS Code. Returns the file path, line range, and selected text. Use when the user wants to discuss specific code they've highlighted.",
104
+ }, async () => {
105
+ const result = await getSelection();
106
+ return {
107
+ content: [{ type: "text", text: JSON.stringify(result) }],
108
+ };
109
+ });
110
+ async function main() {
111
+ ensureExtensionInstalled();
112
+ await checkBridge();
113
+ const transport = new StdioServerTransport();
114
+ let cleanupStarted = false;
115
+ const cleanup = async () => {
116
+ if (cleanupStarted)
117
+ return;
118
+ cleanupStarted = true;
119
+ logger.info("Shutting down...");
120
+ flushLogs();
121
+ const timeoutId = setTimeout(() => {
122
+ logger.error("Cleanup timeout - forcing exit after 5 seconds");
123
+ flushLogs();
124
+ process.exit(1);
125
+ }, 5000);
126
+ try {
127
+ await server.close();
128
+ clearTimeout(timeoutId);
129
+ logger.info("Cleanup completed");
130
+ process.exit(0);
131
+ }
132
+ catch (error) {
133
+ clearTimeout(timeoutId);
134
+ logger.error({ err: error }, "Error during cleanup");
135
+ flushLogs();
136
+ process.exit(1);
137
+ }
138
+ };
139
+ process.once("SIGINT", cleanup);
140
+ process.once("SIGTERM", cleanup);
141
+ await server.connect(transport);
142
+ process.stdin.once("end", cleanup);
143
+ process.stdin.once("close", cleanup);
144
+ logger.info("mcp-walkthrough server started");
145
+ }
146
+ main().catch((error) => {
147
+ logger.error({ err: error }, "Fatal error");
148
+ flushLogs();
149
+ process.exit(1);
150
+ });
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import pino from "pino";
2
+ export declare const logger: pino.Logger<never, boolean>;
3
+ export declare function flushLogs(): void;
4
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,eAAO,MAAM,MAAM,6BAKlB,CAAC;AAEF,wBAAgB,SAAS,IAAI,IAAI,CAEhC"}
@@ -0,0 +1,9 @@
1
+ import pino from "pino";
2
+ const destination = pino.destination({ dest: 2, sync: false });
3
+ export const logger = pino({
4
+ level: process.env.LOG_LEVEL || "info",
5
+ }, destination);
6
+ export function flushLogs() {
7
+ destination.flushSync();
8
+ }
9
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CACxB;IACE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;CACvC,EACD,WAAW,CACZ,CAAC;AAEF,MAAM,UAAU,SAAS;IACvB,WAAW,CAAC,SAAS,EAAE,CAAC;AAC1B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "mcp-walkthrough",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for interactive code walkthroughs - Claude-driven code tours",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "mcp-walkthrough": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "vscode-extension/walkthrough-bridge.vsix",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "author": "Stefan Nitu",
17
+ "license": "MIT",
18
+ "keywords": [
19
+ "mcp",
20
+ "model-context-protocol",
21
+ "walkthrough",
22
+ "code-tour",
23
+ "claude-code"
24
+ ],
25
+ "scripts": {
26
+ "build": "npm run build:extension && tsc -p tsconfig.build.json",
27
+ "build:extension": "node -e \"const fs=require('fs');const v=require('./package.json').version;const p=JSON.parse(fs.readFileSync('vscode-extension/package.json','utf-8'));p.version=v;fs.writeFileSync('vscode-extension/package.json',JSON.stringify(p,null,2)+'\\n')\" && cd vscode-extension && npm install && npx tsc -p ./ && npx @vscode/vsce package --allow-missing-repository -o walkthrough-bridge.vsix",
28
+ "postinstall": "node -e \"try{require('child_process').execSync('code --install-extension '+require('path').join(__dirname,'vscode-extension','walkthrough-bridge.vsix')+' --force',{stdio:'ignore'})}catch{}\"",
29
+ "dev": "bun --watch src/index.ts",
30
+ "start": "node dist/index.js",
31
+ "test": "bun test",
32
+ "test:watch": "bun test --watch",
33
+ "typecheck": "tsc --noEmit",
34
+ "lint": "biome check",
35
+ "lint:fix": "biome check --write",
36
+ "check": "bun run typecheck && bun run lint",
37
+ "prepare": "husky"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.18.1",
41
+ "pino": "^10.0.0",
42
+ "zod": "^3.25.0"
43
+ },
44
+ "devDependencies": {
45
+ "@biomejs/biome": "^2.4.9",
46
+ "@types/bun": "latest",
47
+ "husky": "^9.1.7",
48
+ "typescript": "^6.0.2"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ }
53
+ }