From afd408a4b87a83b588a8118d283f3b7e7b7e6bc3 Mon Sep 17 00:00:00 2001 From: Br1an67 <932039080@qq.com> Date: Wed, 7 Jan 2026 20:52:08 +0800 Subject: [PATCH 1/2] feat: automatically configure DevStar MCP Server in container for Trae --- src/remote-container.ts | 126 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/remote-container.ts b/src/remote-container.ts index 5228449..cec4f33 100644 --- a/src/remote-container.ts +++ b/src/remote-container.ts @@ -372,6 +372,14 @@ export default class RemoteContainer { } catch (portError) { vscode.window.showWarningMessage('端口映射设置失败,但容器连接已建立'); } + + // 自动配置 AI IDE 的 MCP Server + try { + await this.configureMCPServerInContainer(sshConfig.hostname, port); + } catch (mcpError) { + console.error('[MCP] 自动配置失败:', mcpError); + // 不阻塞主流程,仅记录错误 + } } // 使用 VSCode Extension API 打开远程连接 @@ -471,6 +479,124 @@ export default class RemoteContainer { console.log('未找到 forwardPorts 参数,跳过端口映射设置。'); } } + + /** + * 在容器内配置 AI IDE 的 MCP Server + * 支持 Trae IDE 等 AI IDE 的 MCP 自动配置 + */ + private async configureMCPServerInContainer(hostname: string, sshPort: number): Promise { + // 获取用户 token + const userToken = this.user.getUserTokenFromLocal(); + if (!userToken) { + console.log('[MCP] 用户未登录,跳过 MCP Server 配置'); + return; + } + + // 获取 DevStar 域名 + const devstarDomain = this.user.getDevstarDomain(); + const mcpUrl = `${devstarDomain}/api/mcp`; + + console.log(`[MCP] 开始配置 MCP Server: ${mcpUrl}`); + + // Trae IDE 的 MCP 配置路径 + const traeMcpPath = '/root/.trae-server/data/Machine/mcp.json'; + + // MCP 配置内容(注意:使用 "mcpServers" 格式) + const mcpConfig = { + mcpServers: { + devstar: { + type: 'http', + url: mcpUrl, + headers: { + Authorization: `Bearer ${userToken}` + } + } + } + }; + + const configJson = JSON.stringify(mcpConfig, null, 2); + + // 使用 SSH 连接到容器并配置 + const ssh = new NodeSSH(); + + try { + await ssh.connect({ + host: hostname, + username: 'root', + port: sshPort, + privateKeyPath: this.user.getUserPrivateKeyPath(), + readyTimeout: 10000, + }); + + console.log('[MCP] SSH 连接成功'); + + // 检查现有配置 + const checkScript = ` + if [ -f "${traeMcpPath}" ]; then + cat "${traeMcpPath}" + else + echo "FILE_NOT_EXISTS" + fi + `; + + const checkResult = await ssh.execCommand(checkScript); + + let needUpdate = true; + + if (checkResult.stdout !== 'FILE_NOT_EXISTS') { + try { + const existingConfig = JSON.parse(checkResult.stdout); + const existingDevstar = existingConfig.mcpServers?.devstar; + + if (existingDevstar) { + // 检查 URL 和 token 是否匹配 + const urlMatch = existingDevstar.url === mcpUrl; + const tokenMatch = existingDevstar.headers?.Authorization === `Bearer ${userToken}`; + + if (urlMatch && tokenMatch) { + console.log('[MCP] DevStar MCP 配置已存在且正确,无需更新'); + needUpdate = false; + } else { + console.log(`[MCP] DevStar MCP 配置需要更新 (URL匹配: ${urlMatch}, Token匹配: ${tokenMatch})`); + } + } + } catch (parseError) { + console.log('[MCP] 解析现有配置失败,将创建新配置'); + } + } else { + console.log('[MCP] 容器内无配置文件,需要创建'); + } + + // 创建或更新配置文件 + if (needUpdate) { + const setupScript = ` + mkdir -p /root/.trae-server/data/Machine && \ + cat > ${traeMcpPath} << 'EOF' +${configJson} +EOF + echo "MCP 配置已更新" + `; + + const result = await ssh.execCommand(setupScript); + + if (result.code === 0) { + console.log('[MCP] DevStar MCP 配置成功'); + } else { + console.error(`[MCP] 配置失败: ${result.stderr}`); + } + } + + } catch (error) { + console.error('[MCP] SSH 连接或配置失败:', error); + throw error; + } finally { + try { + await ssh.dispose(); + } catch (e) { + // ignore dispose error + } + } + } } /** From a816e9cd91316bd035b1e8c0825c2650e1a697d1 Mon Sep 17 00:00:00 2001 From: Br1an67 <932039080@qq.com> Date: Wed, 7 Jan 2026 21:13:48 +0800 Subject: [PATCH 2/2] feat: auto-configure local VSCode MCP Server for GitHub Copilot --- src/remote-container.ts | 120 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/src/remote-container.ts b/src/remote-container.ts index cec4f33..b9403d5 100644 --- a/src/remote-container.ts +++ b/src/remote-container.ts @@ -373,11 +373,19 @@ export default class RemoteContainer { vscode.window.showWarningMessage('端口映射设置失败,但容器连接已建立'); } - // 自动配置 AI IDE 的 MCP Server + // 自动配置本地 VSCode 的 MCP Server + try { + await this.configureMCPServerLocally(); + } catch (mcpError) { + console.error('[MCP] 本地 MCP 配置失败:', mcpError); + // 不阻塞主流程,仅记录错误 + } + + // 自动配置容器内 AI IDE 的 MCP Server try { await this.configureMCPServerInContainer(sshConfig.hostname, port); } catch (mcpError) { - console.error('[MCP] 自动配置失败:', mcpError); + console.error('[MCP] 容器内 MCP 配置失败:', mcpError); // 不阻塞主流程,仅记录错误 } } @@ -597,6 +605,114 @@ EOF } } } + + /** + * 在本地 VSCode 中配置 MCP Server + * 支持 GitHub Copilot 等使用本地 MCP 配置 + */ + private async configureMCPServerLocally(): Promise { + // 获取用户 token + const userToken = this.user.getUserTokenFromLocal(); + if (!userToken) { + console.log('[MCP] 用户未登录,跳过本地 MCP Server 配置'); + return; + } + + // 获取 DevStar 域名 + const devstarDomain = this.user.getDevstarDomain(); + const mcpUrl = `${devstarDomain}/api/mcp`; + + console.log(`[MCP] 开始配置本地 MCP Server: ${mcpUrl}`); + + // 根据操作系统确定配置文件路径 + let mcpConfigPath: string; + const platform = os.platform(); + const homedir = os.homedir(); + + if (platform === 'darwin') { + // macOS + mcpConfigPath = path.join(homedir, 'Library/Application Support/Code/User/mcp.json'); + } else if (platform === 'win32') { + // Windows + mcpConfigPath = path.join(homedir, 'AppData/Roaming/Code/User/mcp.json'); + } else { + // Linux + mcpConfigPath = path.join(homedir, '.config/Code/User/mcp.json'); + } + + console.log(`[MCP] 配置文件路径: ${mcpConfigPath}`); + + // MCP 配置内容(本地 VSCode 使用 "servers" 格式) + const mcpConfig = { + servers: { + devstar: { + type: 'http', + url: mcpUrl, + headers: { + Authorization: `Bearer ${userToken}` + } + } + } + }; + + const configJson = JSON.stringify(mcpConfig, null, 2); + + try { + // 检查现有配置 + let existingConfig: any = {}; + let needUpdate = true; + + if (fs.existsSync(mcpConfigPath)) { + try { + const content = fs.readFileSync(mcpConfigPath, 'utf8'); + existingConfig = JSON.parse(content); + const existingDevstar = existingConfig.servers?.devstar; + + if (existingDevstar) { + // 检查 URL 和 token 是否匹配 + const urlMatch = existingDevstar.url === mcpUrl; + const tokenMatch = existingDevstar.headers?.Authorization === `Bearer ${userToken}`; + + if (urlMatch && tokenMatch) { + console.log('[MCP] 本地 DevStar MCP 配置已存在且正确,无需更新'); + needUpdate = false; + } else { + console.log(`[MCP] 本地 DevStar MCP 配置需要更新 (URL匹配: ${urlMatch}, Token匹配: ${tokenMatch})`); + } + } + } catch (parseError) { + console.log('[MCP] 解析现有配置失败,将创建新配置'); + } + } else { + console.log('[MCP] 本地无配置文件,需要创建'); + } + + // 创建或更新配置文件 + if (needUpdate) { + // 确保目录存在 + const configDir = path.dirname(mcpConfigPath); + if (!fs.existsSync(configDir)) { + fs.mkdirSync(configDir, { recursive: true }); + } + + // 合并现有配置(保留其他 MCP servers) + const newConfig = { + ...existingConfig, + servers: { + ...existingConfig.servers, + ...mcpConfig.servers + } + }; + + fs.writeFileSync(mcpConfigPath, JSON.stringify(newConfig, null, 2), 'utf8'); + console.log('[MCP] 本地 DevStar MCP 配置成功'); + } + + } catch (error) { + console.error('[MCP] 本地 MCP 配置失败:', error); + throw error; + } + } } /**