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 + } + } + } } /**