vscode-terminal-mcp 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.
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // src/mcp-entry.ts
26
+ var net = __toESM(require("net"));
27
+ var path = __toESM(require("path"));
28
+ var os = __toESM(require("os"));
29
+ var SOCKET_PATH = path.join(os.tmpdir(), "vscode-terminal-mcp.sock");
30
+ var RECONNECT_DELAY_MS = 1e3;
31
+ var MAX_RECONNECT_ATTEMPTS = 30;
32
+ var StdioToIpcBridge = class {
33
+ socket = null;
34
+ pendingRequests = /* @__PURE__ */ new Map();
35
+ socketBuffer = "";
36
+ stdinBuffer = "";
37
+ connected = false;
38
+ reconnectAttempts = 0;
39
+ async start() {
40
+ await this.connectToExtension();
41
+ this.listenStdin();
42
+ }
43
+ async connectToExtension() {
44
+ return new Promise((resolve, reject) => {
45
+ const attempt = () => {
46
+ this.socket = net.createConnection(SOCKET_PATH, () => {
47
+ this.connected = true;
48
+ this.reconnectAttempts = 0;
49
+ this.setupSocketListeners();
50
+ resolve();
51
+ });
52
+ this.socket.on("error", (err) => {
53
+ this.connected = false;
54
+ this.reconnectAttempts++;
55
+ if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
56
+ const errorMsg = `Failed to connect to extension host after ${MAX_RECONNECT_ATTEMPTS} attempts: ${err.message}`;
57
+ process.stderr.write(errorMsg + "\n");
58
+ reject(new Error(errorMsg));
59
+ return;
60
+ }
61
+ setTimeout(attempt, RECONNECT_DELAY_MS);
62
+ });
63
+ };
64
+ attempt();
65
+ });
66
+ }
67
+ setupSocketListeners() {
68
+ if (!this.socket) return;
69
+ this.socket.on("data", (data) => {
70
+ this.socketBuffer += data.toString();
71
+ let newlineIndex;
72
+ while ((newlineIndex = this.socketBuffer.indexOf("\n")) !== -1) {
73
+ const messageStr = this.socketBuffer.slice(0, newlineIndex);
74
+ this.socketBuffer = this.socketBuffer.slice(newlineIndex + 1);
75
+ if (!messageStr.trim()) continue;
76
+ try {
77
+ const ipcResponse = JSON.parse(messageStr);
78
+ this.handleIpcResponse(ipcResponse);
79
+ } catch {
80
+ process.stderr.write(
81
+ `Failed to parse IPC response: ${messageStr}
82
+ `
83
+ );
84
+ }
85
+ }
86
+ });
87
+ this.socket.on("close", () => {
88
+ this.connected = false;
89
+ for (const [id, pending] of this.pendingRequests) {
90
+ pending.reject(new Error("IPC connection closed"));
91
+ this.pendingRequests.delete(id);
92
+ }
93
+ });
94
+ this.socket.on("error", (err) => {
95
+ process.stderr.write(`IPC socket error: ${err.message}
96
+ `);
97
+ });
98
+ }
99
+ handleIpcResponse(ipcResponse) {
100
+ const pending = this.pendingRequests.get(ipcResponse.id);
101
+ if (!pending) {
102
+ return;
103
+ }
104
+ this.pendingRequests.delete(ipcResponse.id);
105
+ if (ipcResponse.error) {
106
+ const errorResponse = {
107
+ jsonrpc: "2.0",
108
+ id: ipcResponse.id,
109
+ error: ipcResponse.error
110
+ };
111
+ this.writeStdout(errorResponse);
112
+ } else {
113
+ const successResponse = {
114
+ jsonrpc: "2.0",
115
+ id: ipcResponse.id,
116
+ result: ipcResponse.result
117
+ };
118
+ this.writeStdout(successResponse);
119
+ }
120
+ }
121
+ listenStdin() {
122
+ process.stdin.setEncoding("utf8");
123
+ process.stdin.on("data", (chunk) => {
124
+ this.stdinBuffer += chunk;
125
+ let newlineIndex;
126
+ while ((newlineIndex = this.stdinBuffer.indexOf("\n")) !== -1) {
127
+ const messageStr = this.stdinBuffer.slice(0, newlineIndex);
128
+ this.stdinBuffer = this.stdinBuffer.slice(newlineIndex + 1);
129
+ if (!messageStr.trim()) continue;
130
+ try {
131
+ const jsonRpc = JSON.parse(messageStr);
132
+ this.handleJsonRpcRequest(jsonRpc);
133
+ } catch {
134
+ const errorResponse = {
135
+ jsonrpc: "2.0",
136
+ id: void 0,
137
+ error: { code: -32700, message: "Parse error" }
138
+ };
139
+ this.writeStdout(errorResponse);
140
+ }
141
+ }
142
+ });
143
+ process.stdin.on("end", () => {
144
+ this.shutdown();
145
+ });
146
+ }
147
+ handleJsonRpcRequest(message) {
148
+ if (!this.connected || !this.socket) {
149
+ if (message.id !== void 0) {
150
+ const errorResponse = {
151
+ jsonrpc: "2.0",
152
+ id: message.id,
153
+ error: {
154
+ code: -32603,
155
+ message: "Extension host not connected"
156
+ }
157
+ };
158
+ this.writeStdout(errorResponse);
159
+ }
160
+ return;
161
+ }
162
+ const ipcRequest = {
163
+ id: String(message.id ?? `notif-${Date.now()}`),
164
+ method: message.method,
165
+ params: message.params
166
+ };
167
+ if (message.id !== void 0) {
168
+ this.pendingRequests.set(ipcRequest.id, {
169
+ resolve: () => {
170
+ },
171
+ reject: (err) => {
172
+ const errorResponse = {
173
+ jsonrpc: "2.0",
174
+ id: message.id,
175
+ error: {
176
+ code: -32603,
177
+ message: err instanceof Error ? err.message : String(err)
178
+ }
179
+ };
180
+ this.writeStdout(errorResponse);
181
+ }
182
+ });
183
+ }
184
+ this.socket.write(JSON.stringify(ipcRequest) + "\n");
185
+ }
186
+ writeStdout(message) {
187
+ process.stdout.write(JSON.stringify(message) + "\n");
188
+ }
189
+ shutdown() {
190
+ if (this.socket) {
191
+ this.socket.destroy();
192
+ this.socket = null;
193
+ }
194
+ process.exit(0);
195
+ }
196
+ };
197
+ var bridge = new StdioToIpcBridge();
198
+ bridge.start().catch((err) => {
199
+ process.stderr.write(`Fatal: ${err.message}
200
+ `);
201
+ process.exit(1);
202
+ });
203
+ //# sourceMappingURL=mcp-entry.js.map
package/icon.png ADDED
Binary file
package/icon.svg ADDED
@@ -0,0 +1,65 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#1e1e1e"/>
5
+ <stop offset="100%" style="stop-color:#252526"/>
6
+ </linearGradient>
7
+ <linearGradient id="accent" x1="0%" y1="0%" x2="100%" y2="0%">
8
+ <stop offset="0%" style="stop-color:#0098ff"/>
9
+ <stop offset="100%" style="stop-color:#007acc"/>
10
+ </linearGradient>
11
+ </defs>
12
+
13
+ <!-- Background rounded square -->
14
+ <rect x="8" y="8" width="240" height="240" rx="28" ry="28" fill="url(#bg)"/>
15
+
16
+ <!-- VSCode-style bottom panel area -->
17
+ <rect x="24" y="56" width="208" height="176" rx="8" ry="8" fill="#1e1e1e" stroke="#3c3c3c" stroke-width="1.5"/>
18
+
19
+ <!-- Tab bar -->
20
+ <rect x="24" y="56" width="208" height="32" rx="8" ry="0" fill="#2d2d2d"/>
21
+ <rect x="24" y="76" width="208" height="12" fill="#2d2d2d"/>
22
+
23
+ <!-- Active tab -->
24
+ <rect x="24" y="56" width="96" height="32" rx="8" ry="0" fill="#1e1e1e"/>
25
+ <rect x="24" y="76" width="96" height="12" fill="#1e1e1e"/>
26
+ <!-- Active tab bottom border (VSCode blue accent) -->
27
+ <rect x="24" y="86" width="96" height="2" fill="#007acc"/>
28
+
29
+ <!-- Tab icon: terminal symbol -->
30
+ <polyline points="36,66 44,72 36,78" fill="none" stroke="#cccccc" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
31
+ <text x="50" y="77" font-family="Segoe UI, Arial, sans-serif" font-size="11" fill="#cccccc" font-weight="500">TERMINAL</text>
32
+
33
+ <!-- Inactive tab -->
34
+ <text x="134" y="77" font-family="Segoe UI, Arial, sans-serif" font-size="11" fill="#6e6e6e">OUTPUT</text>
35
+
36
+ <!-- Terminal content area -->
37
+ <!-- Prompt line 1 -->
38
+ <text x="36" y="116" font-family="Consolas, monospace" font-size="13" fill="#6a9955">~</text>
39
+ <text x="48" y="116" font-family="Consolas, monospace" font-size="13" fill="#cccccc">$</text>
40
+ <text x="62" y="116" font-family="Consolas, monospace" font-size="13" fill="#ce9178">npm run build</text>
41
+
42
+ <!-- Output lines -->
43
+ <text x="36" y="138" font-family="Consolas, monospace" font-size="11" fill="#608b4e">✓</text>
44
+ <text x="50" y="138" font-family="Consolas, monospace" font-size="11" fill="#858585">compiled successfully</text>
45
+
46
+ <text x="36" y="156" font-family="Consolas, monospace" font-size="11" fill="#608b4e">✓</text>
47
+ <text x="50" y="156" font-family="Consolas, monospace" font-size="11" fill="#858585">tests passed</text>
48
+
49
+ <!-- Current prompt line -->
50
+ <text x="36" y="182" font-family="Consolas, monospace" font-size="13" fill="#6a9955">~</text>
51
+ <text x="48" y="182" font-family="Consolas, monospace" font-size="13" fill="#cccccc">$</text>
52
+
53
+ <!-- Blinking cursor -->
54
+ <rect x="62" y="170" width="8" height="16" rx="1" fill="#007acc">
55
+ <animate attributeName="opacity" values="1;0.3;1" dur="1s" repeatCount="indefinite"/>
56
+ </rect>
57
+
58
+ <!-- MCP connection dot top-right -->
59
+ <circle cx="216" cy="68" r="4" fill="#28c840"/>
60
+
61
+ <!-- Bottom status bar -->
62
+ <rect x="24" y="220" width="208" height="12" rx="0" ry="0" fill="#007acc"/>
63
+ <text x="32" y="229" font-family="Segoe UI, Arial, sans-serif" font-size="8" fill="#ffffff">MCP: 1 session</text>
64
+ <text x="184" y="229" font-family="Segoe UI, Arial, sans-serif" font-size="8" fill="#ffffff">bash</text>
65
+ </svg>
package/package.json ADDED
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "vscode-terminal-mcp",
3
+ "displayName": "Terminal MCP Server",
4
+ "description": "MCP server that provides visible terminal sessions in VSCode for Claude Code and subagents",
5
+ "version": "0.1.0",
6
+ "publisher": "sirlordt",
7
+ "license": "MIT",
8
+ "author": "sirlordt",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/sirlordt/vscode-terminal-mcp.git"
12
+ },
13
+ "homepage": "https://github.com/sirlordt/vscode-terminal-mcp#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/sirlordt/vscode-terminal-mcp/issues"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "terminal",
20
+ "vscode",
21
+ "claude",
22
+ "claude-code",
23
+ "model-context-protocol",
24
+ "ai-tools"
25
+ ],
26
+ "mcpName": "io.github.sirlordt/vscode-terminal-mcp",
27
+ "icon": "icon.png",
28
+ "engines": {
29
+ "vscode": "^1.99.0"
30
+ },
31
+ "categories": [
32
+ "Other"
33
+ ],
34
+ "activationEvents": [
35
+ "onStartupFinished"
36
+ ],
37
+ "main": "./dist/extension.js",
38
+ "contributes": {
39
+ "mcpServers": {
40
+ "vscode-terminal-mcp": {
41
+ "type": "stdio",
42
+ "command": "node",
43
+ "args": [
44
+ "${extensionPath}/dist/mcp-entry.js"
45
+ ]
46
+ }
47
+ },
48
+ "configuration": {
49
+ "title": "Terminal MCP",
50
+ "properties": {
51
+ "terminalMcp.blockedCommands": {
52
+ "type": "array",
53
+ "items": {
54
+ "type": "string"
55
+ },
56
+ "default": [
57
+ "rm -rf /",
58
+ "mkfs",
59
+ "dd if=",
60
+ ":(){ :|:& };:"
61
+ ],
62
+ "description": "Commands that are never allowed to execute"
63
+ },
64
+ "terminalMcp.allowedDirectories": {
65
+ "type": "array",
66
+ "items": {
67
+ "type": "string"
68
+ },
69
+ "default": [],
70
+ "description": "Allowed working directories (empty = unrestricted)"
71
+ },
72
+ "terminalMcp.defaultTimeoutMs": {
73
+ "type": "number",
74
+ "default": 30000,
75
+ "description": "Default timeout for command execution in milliseconds"
76
+ },
77
+ "terminalMcp.maxConcurrentSessions": {
78
+ "type": "number",
79
+ "default": 10,
80
+ "description": "Maximum number of concurrent terminal sessions"
81
+ },
82
+ "terminalMcp.maxOutputLines": {
83
+ "type": "number",
84
+ "default": 10000,
85
+ "description": "Maximum number of output lines to buffer per session"
86
+ },
87
+ "terminalMcp.idleTimeoutMs": {
88
+ "type": "number",
89
+ "default": 300000,
90
+ "description": "Auto-close idle sessions after this many milliseconds (0 = disabled)"
91
+ }
92
+ }
93
+ }
94
+ },
95
+ "scripts": {
96
+ "vscode:prepublish": "npm run build",
97
+ "build": "node esbuild.config.mjs",
98
+ "watch": "node esbuild.config.mjs --watch",
99
+ "lint": "eslint src/ --ext .ts",
100
+ "format": "prettier --write \"src/**/*.ts\"",
101
+ "test": "vitest run",
102
+ "test:watch": "vitest",
103
+ "package": "vsce package"
104
+ },
105
+ "dependencies": {
106
+ "@modelcontextprotocol/sdk": "^1.9.0",
107
+ "strip-ansi": "^7.1.0",
108
+ "uuid": "^9.0.0",
109
+ "zod": "^3.24.0",
110
+ "zod-to-json-schema": "^3.23.0"
111
+ },
112
+ "devDependencies": {
113
+ "@types/node": "^20.12.0",
114
+ "@types/uuid": "^9.0.0",
115
+ "@types/vscode": "^1.99.0",
116
+ "@vscode/test-electron": "^2.4.0",
117
+ "@vscode/vsce": "^2.26.0",
118
+ "esbuild": "^0.21.0",
119
+ "eslint": "^8.57.0",
120
+ "prettier": "^3.2.0",
121
+ "typescript": "^5.4.0",
122
+ "vitest": "^1.6.0"
123
+ }
124
+ }
@@ -0,0 +1,54 @@
1
+ # MCP SDK - Patterns and Architecture
2
+
3
+ ## Base Protocol
4
+ - JSON-RPC 2.0 as message format
5
+ - 3-component architecture: **Server** (exposes capabilities), **Client** (consumes), **Host** (manages communication - Claude Desktop, VSCode)
6
+
7
+ ## Package @modelcontextprotocol/sdk
8
+ - Core: `@modelcontextprotocol/server` and `@modelcontextprotocol/client`
9
+ - Transports: `@modelcontextprotocol/node` (HTTP), Express, Hono
10
+ - Requires `zod` as peer dependency for schema validation
11
+ - Setup with ES Modules (`"type": "module"`)
12
+
13
+ ## 3 Protocol Primitives
14
+ 1. **Tools** - Executable functions the LLM can invoke with structured parameters
15
+ 2. **Resources** - Data sources (databases, APIs, filesystem)
16
+ 3. **Prompts** - Predefined templates for interactions
17
+
18
+ ## Request Structure (JSON-RPC 2.0)
19
+ ```json
20
+ {
21
+ "jsonrpc": "2.0",
22
+ "id": "<unique-id>",
23
+ "method": "tools/call",
24
+ "params": {
25
+ "name": "<tool-name>",
26
+ "arguments": {}
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## Tool Definition
32
+ Each tool requires:
33
+ - `name` - Unique identifier
34
+ - `title` - Human-readable name
35
+ - `description` - Functionality explanation
36
+ - `inputSchema` - JSON Schema (defined with Zod)
37
+ - Handler function - Executes logic and returns results
38
+
39
+ ## Supported Transports
40
+
41
+ ### stdio (Standard I/O)
42
+ - Ideal for local servers
43
+ - Communication via process stdin/stdout
44
+ - Auto-discovery in VSCode extensions
45
+
46
+ ### SSE (Server-Sent Events over HTTP)
47
+ - POST for client->server
48
+ - Supports streaming
49
+ - Standard HTTP authentication (bearer tokens, API keys, OAuth)
50
+
51
+ ## Connection Lifecycle
52
+ 1. **Initialization** - Capability exchange and version negotiation
53
+ 2. **Operation** - Normal tool execution and resource access
54
+ 3. **Termination** - Orderly connection shutdown
@@ -0,0 +1,36 @@
1
+ # VSCode Terminal API - Capabilities and Limitations
2
+
3
+ ## Terminal Creation
4
+ ```typescript
5
+ const terminal = vscode.window.createTerminal('MyTerminal');
6
+ terminal.sendText("command", addNewLine);
7
+ terminal.show();
8
+ ```
9
+
10
+ ## Pseudoterminal Interface (Custom PTY)
11
+ ```typescript
12
+ interface Pseudoterminal {
13
+ open(): void;
14
+ close(): void;
15
+ handleInput(data: string): void;
16
+ onDidWrite: Event<string>; // Writes data to terminal UI
17
+ setDimensions(cols, rows): void;
18
+ onDidClose: Event<number | void>;
19
+ }
20
+
21
+ vscode.window.createTerminal({ pty: myPseudoterminal });
22
+ ```
23
+
24
+ ## Critical Limitation
25
+ The standard Terminal API **does NOT provide direct output reading** from integrated terminals.
26
+ `sendText()` sends text to the shell, but capturing output requires workarounds.
27
+
28
+ ## Shell Integration API (VSCode 1.93+)
29
+ - `onDidStartTerminalShellExecution` - Event fired when a command starts
30
+ - `execution.read()` - AsyncIterable<string> with output chunks
31
+ - `execution.exitCode` - Thenable<number | undefined>
32
+ - Requires active shell integration (automatic in bash/zsh/PowerShell)
33
+
34
+ ## Recommended Strategy
35
+ 1. **Primary**: Shell Integration API (when available)
36
+ 2. **Fallback**: Polling-based output stabilization detection
@@ -0,0 +1,43 @@
1
+ # VSCode Extension as MCP Server
2
+
3
+ ## Native Support (VSCode 1.99+)
4
+ - Extensions can serve as MCP servers
5
+ - Auto-discovery by Claude Code / Copilot without additional configuration
6
+ - Communication via **stdio** by default
7
+
8
+ ## Declaration in package.json
9
+ ```jsonc
10
+ {
11
+ "contributes": {
12
+ "mcpServers": {
13
+ "server-name": {
14
+ "type": "stdio",
15
+ "command": "node",
16
+ "args": ["${extensionPath}/dist/mcp-entry.js"]
17
+ }
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ ## Key Architectural Problem
24
+ `contributes.mcpServers` launches a **child process** separate from the extension host.
25
+ The VSCode Terminal API (`vscode.window.createTerminal`, Shell Integration) is only
26
+ available **within the extension host process**.
27
+
28
+ ## Solution: IPC Bridge
29
+ ```
30
+ [Claude Code] --stdio--> [mcp-entry.js (shim)] --IPC--> [Extension Host (Terminal API)]
31
+ ```
32
+
33
+ - `mcp-entry.js`: Thin stdio-to-IPC bridge. Reads JSON-RPC from stdin, forwards via Unix socket.
34
+ - `extension.ts`: In activate(), creates IPC server (Unix domain socket), instantiates MCP Server with handlers, processes forwarded requests.
35
+
36
+ ## Workspace Configuration
37
+ `.vscode/mcp.json` or `settings.json` file for per-team configuration.
38
+
39
+ ## Existing MCP Servers in the Environment
40
+ 1. **desktop-commander** (v0.2.38) - Command execution, files
41
+ 2. **playwright-mcp** - Browser automation
42
+ 3. **context7** - Contextual documentation
43
+ 4. **chrome-devtools-mcp** (v0.20.2) - DevTools
@@ -0,0 +1,45 @@
1
+ # Desktop Commander MCP - Implementation Reference
2
+
3
+ ## Overview
4
+ Desktop Commander is the most relevant MCP as a reference. It implements command
5
+ execution with output capture, session management, and security.
6
+
7
+ ## Exposed Tools
8
+ - **Terminal**: `execute_command`, `read_output`, `force_terminate`, `list_sessions`, `list_processes`
9
+ - **Filesystem**: `read_file`, `write_file`, `move_file`, `search`
10
+ - **Code editing**: `edit_block` (surgical text replacement)
11
+
12
+ ## Security Patterns
13
+ - Two execution modes:
14
+ 1. **Safe mode** - Executable allowlist without shell interpretation
15
+ 2. **Legacy mode** - Command string allowlist/blocklist
16
+ - Command validation before execution
17
+ - Timeout control
18
+ - Working directory restrictions
19
+ - Stdin support with timeout protection
20
+
21
+ ## Configuration
22
+ ```json
23
+ {
24
+ "blockedCommands": ["rm -rf /", "mkfs", "dd if="],
25
+ "defaultShell": "/bin/bash",
26
+ "allowedDirectories": ["/home/user/projects"],
27
+ "fileReadLineLimit": 1000,
28
+ "fileWriteLineLimit": 1000
29
+ }
30
+ ```
31
+
32
+ ## Differences with Our Solution
33
+ | Aspect | Desktop Commander | Our MCP |
34
+ |--------|------------------|---------|
35
+ | Visibility | No visible terminal | Visible terminal in VSCode |
36
+ | Integration | Independent process | Embedded in VSCode extension |
37
+ | Output | Captured text only | Text + visual terminal |
38
+ | Subagents | Not designed for this | Native support with agentId |
39
+ | Context | Loses visual context | User sees the execution |
40
+
41
+ ## Lessons Applied
42
+ 1. Circular buffer for output with pagination
43
+ 2. Dangerous command blocklist by default
44
+ 3. Configurable timeout with partial return
45
+ 4. Session management with Map<id, session>
package/server.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
3
+ "name": "io.github.sirlordt/vscode-terminal-mcp",
4
+ "title": "Terminal MCP Server",
5
+ "description": "MCP server that executes commands in visible VSCode terminal tabs with full output capture, session reuse, long-running process support, and subagent isolation.",
6
+ "version": "0.1.0",
7
+ "packages": [
8
+ {
9
+ "registry": "npm",
10
+ "name": "vscode-terminal-mcp"
11
+ }
12
+ ]
13
+ }