From dca2a9c82094d29f9deceabf7de48dabb0b2b546 Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Fri, 2 May 2025 03:07:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=85=A8=E5=B1=80=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E7=9A=84=20mcp=20=E6=9C=8D=E5=8A=A1=E5=99=A8=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- src/global.ts | 22 ++++- src/sidebar/installed.controller.ts | 53 ++++-------- src/sidebar/installed.service.ts | 127 ++++++++++++++++++++++++++++ src/sidebar/workspace.controller.ts | 2 +- src/sidebar/workspace.service.ts | 2 + 6 files changed, 170 insertions(+), 38 deletions(-) create mode 100644 src/sidebar/installed.service.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 936597d..0053b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - 修复部分因为服务器名称特殊字符而导致的保存实效的错误 - 插件模式下,左侧管理面板中的「MCP连接(工作区)」视图可以进行增删改查了 - 新增「MCP连接(全局)」,用于安装全局范围的 mcp server - +- 增加引导页面 ## [main] 0.0.5 - 支持对已经打开过的文件项目进行管理 diff --git a/src/global.ts b/src/global.ts index b699027..8f08e3a 100644 --- a/src/global.ts +++ b/src/global.ts @@ -6,7 +6,6 @@ import * as fs from 'fs'; export type FsPath = string; export const panels = new Map(); - export interface IStdioConnectionItem { type: 'stdio'; name: string; @@ -133,6 +132,27 @@ export function getWorkspaceConnectionConfig() { return connection; } +export function getInstalledConnectionConfigPath() { + const homeDir = os.homedir(); + const configDir = fspath.join(homeDir, '.openmcp'); + const connectionConfig = fspath.join(configDir, CONNECTION_CONFIG_NAME); + return connectionConfig; +} + +/** + * @description 保存连接信息到全局配置文件,这个部分和「安装的连接」对应 + * @returns + */ +export function saveConnectionConfig() { + if (!_connectionConfig) { + return; + } + + const connectionConfig = getInstalledConnectionConfigPath(); + + fs.writeFileSync(connectionConfig, JSON.stringify(_connectionConfig, null, 2), 'utf-8'); +} + export function saveWorkspaceConnectionConfig(workspace: string) { if (!_workspaceConnectionConfig) { diff --git a/src/sidebar/installed.controller.ts b/src/sidebar/installed.controller.ts index 4400ad7..641f161 100644 --- a/src/sidebar/installed.controller.ts +++ b/src/sidebar/installed.controller.ts @@ -1,7 +1,8 @@ import * as vscode from 'vscode'; import { RegisterCommand, RegisterTreeDataProvider } from '../common'; -import { getWorkspaceConnectionConfig, getWorkspacePath, panels, saveWorkspaceConnectionConfig } from '../global'; import { ConnectionViewItem } from './common'; +import { getConnectionConfig, getInstalledConnectionConfigPath, saveConnectionConfig } from '../global'; +import { acquireInstalledConnection, deleteInstalledConnection } from './installed.service'; @RegisterTreeDataProvider('openmcp.sidebar.installed-connection') export class McpInstalledConnectProvider implements vscode.TreeDataProvider { @@ -17,7 +18,7 @@ export class McpInstalledConnectProvider implements vscode.TreeDataProvider { // TODO: 读取 configDir 下的所有文件,作为子节点 - const connection = getWorkspaceConnectionConfig(); + const connection = getConnectionConfig(); const sidebarItems = connection.items.map((item, index) => { // 连接的名字 const itemName = `${item.name} (${item.type})` @@ -36,49 +37,31 @@ export class McpInstalledConnectProvider implements vscode.TreeDataProvider { + const { exec } = require('child_process'); + const { promisify } = require('util'); + const execAsync = promisify(exec); + + try { + const { stdout } = await execAsync(`which ${command.split(' ')[0]}`, { cwd }); + return stdout.trim(); + } catch (error) { + throw new Error(`无法找到命令: ${command.split(' ')[0]}`); + } +} + +export async function acquireInstalledConnection(): Promise { + // 让用户选择连接类型 + const connectionType = await vscode.window.showQuickPick(['stdio', 'sse'], { + placeHolder: '请选择连接类型' + }); + + if (!connectionType) { + return; // 用户取消选择 + } + + if (connectionType === 'stdio') { + // 获取 command + const commandString = await vscode.window.showInputBox({ + prompt: '请输入连接的 command', + placeHolder: '例如: mcp run main.py' + }); + + if (!commandString) { + return; // 用户取消输入 + } + + // 获取 cwd + const cwd = await vscode.window.showInputBox({ + prompt: '请输入工作目录 (cwd),可选', + placeHolder: '例如: /path/to/project' + }); + + // 校验 command + cwd 是否有效 + try { + const commandPath = await validateAndGetCommandPath(commandString, cwd); + console.log('Command Path:', commandPath); + } catch (error) { + vscode.window.showErrorMessage(`无效的 command: ${error}`); + return; + } + + const commands = commandString.split(' '); + const command = commands[0]; + const args = commands.slice(1); + + // 保存连接配置 + return { + type: 'stdio', + name: `stdio-${Date.now()}`, + command: command, + args, + cwd: cwd || '' + }; + + } else if (connectionType === 'sse') { + // 获取 url + const url = await vscode.window.showInputBox({ + prompt: '请输入连接的 URL', + placeHolder: '例如: https://127.0.0.1:8080' + }); + + if (!url) { + return; // 用户取消输入 + } + + // 获取 oauth + const oauth = await vscode.window.showInputBox({ + prompt: '请输入 OAuth 令牌,可选', + placeHolder: '例如: your-oauth-token' + }); + + // 保存连接配置 + return { + type: 'sse', + name: `sse-${Date.now()}`, + version: '1.0', // 假设默认版本为 1.0,可根据实际情况修改 + url: url, + oauth: oauth || '' + } + } +} + diff --git a/src/sidebar/workspace.controller.ts b/src/sidebar/workspace.controller.ts index 978c61f..83d109b 100644 --- a/src/sidebar/workspace.controller.ts +++ b/src/sidebar/workspace.controller.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import { RegisterCommand, RegisterTreeDataProvider } from '../common'; -import { getWorkspaceConnectionConfig, getWorkspaceConnectionConfigPath, getWorkspacePath, panels, saveWorkspaceConnectionConfig } from '../global'; +import { getWorkspaceConnectionConfig, getWorkspaceConnectionConfigPath, getWorkspacePath, saveWorkspaceConnectionConfig } from '../global'; import { ConnectionViewItem } from './common'; import { revealOpenMcpWebviewPanel } from '../webview/webview.service'; import { acquireUserCustomConnection, deleteUserConnection } from './workspace.service'; diff --git a/src/sidebar/workspace.service.ts b/src/sidebar/workspace.service.ts index af15a9b..6f913e9 100644 --- a/src/sidebar/workspace.service.ts +++ b/src/sidebar/workspace.service.ts @@ -2,6 +2,8 @@ import { getWorkspaceConnectionConfig, getWorkspacePath, IConnectionItem, panels import * as vscode from 'vscode'; + + export async function acquireUserCustomConnection(): Promise { // 让用户选择连接类型 const connectionType = await vscode.window.showQuickPick(['stdio', 'sse'], {