diff --git a/renderer/src/App.vue b/renderer/src/App.vue index 1370127..feaa9dd 100644 --- a/renderer/src/App.vue +++ b/renderer/src/App.vue @@ -18,8 +18,7 @@ import MainPanel from '@/components/main-panel/index.vue'; import { setDefaultCss } from './hook/css'; import { greenLog, pinkLog } from './views/setting/util'; import { useMessageBridge } from './api/message-bridge'; -import { initialise } from './views/connect/connection'; -import { getPlatform } from './api/platform'; +import { initialise } from './views/connect'; import Tour from '@/components/guide/tour.vue'; import { userHasReadGuide } from './components/guide/tour'; @@ -37,7 +36,9 @@ bridge.addCommandListener('hello', data => { const route = useRoute(); const router = useRouter(); -const useAuth = Boolean(import.meta.env.VITE_USE_AUTH); +const useAuth = Boolean(import.meta.env.VITE_USE_AUTH !== "false"); +console.log(import.meta.env.VITE_USE_AUTH, useAuth); + privilegeStatus.allow = !Boolean(useAuth); onMounted(async () => { diff --git a/renderer/src/components/guide/tour.vue b/renderer/src/components/guide/tour.vue index 122ab47..71c552b 100644 --- a/renderer/src/components/guide/tour.vue +++ b/renderer/src/components/guide/tour.vue @@ -58,7 +58,7 @@ - + @@ -32,18 +32,19 @@ import { defineComponent, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { Connection } from './sidebar'; -import { connectionResult } from '@/views/connect/connection'; +import { mcpClientAdapter } from '@/views/connect/core'; defineComponent({ name: 'connected' }); const { t } = useI18n(); +const client = mcpClientAdapter.masterNode; const fullDisplayServerName = computed(() => { - return connectionResult.serverInfo.name + '/' + connectionResult.serverInfo.version; + return client.connectionResult.name + '/' + client.connectionResult.version; }); const displayServerName = computed(() => { - const name = connectionResult.serverInfo.name; + const name = client.connectionResult.name; if (name.length <= 3) return name; // 处理中文混合名称 diff --git a/renderer/src/router/index.ts b/renderer/src/router/index.ts index 06ea588..1b2a4b4 100644 --- a/renderer/src/router/index.ts +++ b/renderer/src/router/index.ts @@ -6,28 +6,28 @@ const routes: Array = [ { name : "default", path : "/", - redirect : baseURL + "/debug" + redirect : baseURL + "debug" }, { - path: baseURL + "/debug", + path: baseURL + "debug", name: "debug", component: () => import( /* webpackMode: "eager" */ "@/views/debug/index.vue"), meta: { title: "Debug" } }, { - path: baseURL + "/connect", + path: baseURL + "connect", name: "connect", component: () => import( /* webpackMode: "eager" */ "@/views/connect/index.vue"), meta: { title: "Connect" } }, { - path: baseURL + "/setting", + path: baseURL + "setting", name: "setting", component: () => import( /* webpackMode: "eager" */ "@/views/setting/index.vue"), meta: { title: "Setting" } }, { - path: baseURL + "/about", + path: baseURL + "about", name: "about", component: () => import( /* webpackMode: "eager" */ "@/views/about/index.vue"), meta: { title: "Tools" } diff --git a/renderer/src/views/connect/connection-args.vue b/renderer/src/views/connect/connection-args.vue index 148bae5..e264b18 100644 --- a/renderer/src/views/connect/connection-args.vue +++ b/renderer/src/views/connect/connection-args.vue @@ -1,19 +1,19 @@ diff --git a/renderer/src/views/connect/connection-log.vue b/renderer/src/views/connect/connection-log.vue index 0dceaf3..68fdbde 100644 --- a/renderer/src/views/connect/connection-log.vue +++ b/renderer/src/views/connect/connection-log.vue @@ -3,7 +3,7 @@ {{ t('log') }}
-
+
{{ log.message }}
@@ -14,9 +14,17 @@ + + \ No newline at end of file diff --git a/renderer/src/views/connect/core.ts b/renderer/src/views/connect/core.ts index 8745b03..88a049b 100644 --- a/renderer/src/views/connect/core.ts +++ b/renderer/src/views/connect/core.ts @@ -1,11 +1,10 @@ import { useMessageBridge } from "@/api/message-bridge"; -import { reactive, type Reactive } from "vue"; +import { reactive, ref, type Reactive, type Ref } from "vue"; import type { IConnectionResult, ConnectionTypeOptionItem, IConnectionArgs, IConnectionEnvironment, McpOptions } from "./type"; import { ElMessage } from "element-plus"; -import { loadPanels, type SaveTab } from "@/hook/panel"; +import { loadPanels } from "@/hook/panel"; import { getPlatform } from "@/api/platform"; - export const connectionSelectDataViewOption: ConnectionTypeOptionItem[] = [ { value: 'STDIO', @@ -21,34 +20,23 @@ export const connectionSelectDataViewOption: ConnectionTypeOptionItem[] = [ } ] -export async function getLaunchSignature(platform: string): Promise { - const bridge = useMessageBridge(); - const { code, msg } = await bridge.commandRequest(platform + '/launch-signature'); - - if (code !== 200) { - const message = msg.toString(); - ElMessage.error(message); - return []; - } - - // 判断一下版本,新版本的 msg 应该是数组,老版本是对象 - // 返回的数组的第一个为主节点,其余为从节点 - if (Array.isArray(msg)) { - return msg; - } - return [msg]; -} - - export class McpClient { - + // 连接入参 public connectionArgs: Reactive; + // 连接出参 public connectionResult: Reactive; - + + // 预设环境变量,初始化的时候会去获取它们 public presetsEnvironment: string[] = ['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER']; + // 环境变量 public connectionEnvironment: Reactive; + // logger 面板的 ref + public connectionLogRef = ref(null); + // setting 面板的 ref + public connectionSettingRef = ref(null); + constructor( public clientVersion: string = '0.0.1', public clientNamePrefix: string = 'openmcp.connect' @@ -169,23 +157,16 @@ export class McpClient { type: 'error', message }); - + ElMessage.error(message); - return; + return false; } this.connectionResult.status = msg.status; this.connectionResult.clientId = msg.clientId; this.connectionResult.name = msg.name; this.connectionResult.version = msg.version; - - // 同步成功的连接参数到后端,更新 vscode treeview 中的列表 - const deserializeOption = JSON.parse(JSON.stringify(this.connectOption)); - - bridge.postMessage({ - command: platform + '/update-connection-sigature', - data: deserializeOption - }); + return true; } /** @@ -198,7 +179,7 @@ export class McpClient { const presetVars = this.presetsEnvironment; if (enabled) { const values = await this.lookupEnvVar(presetVars); - + if (values) { // 将 key values 合并进 connectionEnv.data 中 // 若已有相同的 key, 则替换 value @@ -232,7 +213,7 @@ export class McpClient { public async lookupEnvVar(varNames: string[]) { const bridge = useMessageBridge(); const { code, msg } = await bridge.commandRequest('lookup-env-var', { keys: varNames }); - + if (code === 200) { this.connectionResult.logString.push({ type: 'info', @@ -252,28 +233,79 @@ export class McpClient { class McpClientAdapter { public clients: McpClient[] = []; + public currentClientIndex: number = 0; + + private defaultClient: McpClient = new McpClient(); constructor( public platform: string - ) {} + ) { } + + /** + * @description 获取连接参数签名 + * @returns + */ + public async getLaunchSignature(): Promise { + const bridge = useMessageBridge(); + const { code, msg } = await bridge.commandRequest(this.platform + '/launch-signature'); + + if (code !== 200) { + const message = msg.toString(); + ElMessage.error(message); + return []; + } + + // 判断一下版本,新版本的 msg 应该是数组,老版本是对象 + // 返回的数组的第一个为主节点,其余为从节点 + if (Array.isArray(msg)) { + return msg; + } + return [msg]; + } + + get masterNode() { + if (this.clients.length === 0) { + return this.defaultClient; + } + return this.clients[0]; + } + + public async saveLaunchSignature() { + const bridge = useMessageBridge(); + const options: McpOptions[] = this.clients.map(client => client.connectOption); + + // 同步成功的连接参数到后端,更新 vscode treeview 中的列表 + const deserializeOption = JSON.parse(JSON.stringify(options)); + bridge.postMessage({ + command: platform + '/update-connection-signature', + data: deserializeOption + }); + } public async launch() { - const launchSignature = await getLaunchSignature(this.platform); + const launchSignature = await this.getLaunchSignature(); + let allOk = true; for (const item of launchSignature) { const client = new McpClient(); // 同步连接参数 await client.acquireConnectionSignature(item); - + // 同步环境变量 await client.handleEnvSwitch(true); // 连接 - await client.connect(this.platform); - + const ok = await client.connect(this.platform); + allOk &&= ok; + this.clients.push(client); } + + // 如果全部成功,保存连接参数 + if (allOk) { + this.saveLaunchSignature(); + } } public async loadPanels() { @@ -283,4 +315,6 @@ class McpClientAdapter { } const platform = getPlatform(); -export const mcpClientAdapter = new McpClientAdapter(platform); \ No newline at end of file +export const mcpClientAdapter = reactive( + new McpClientAdapter(platform) +); \ No newline at end of file diff --git a/renderer/src/views/connect/index.vue b/renderer/src/views/connect/index.vue index c2e67a7..4220cdd 100644 --- a/renderer/src/views/connect/index.vue +++ b/renderer/src/views/connect/index.vue @@ -1,128 +1,96 @@ \ No newline at end of file diff --git a/renderer/src/views/debug/welcome.vue b/renderer/src/views/debug/welcome.vue index a342f6b..6af7184 100644 --- a/renderer/src/views/debug/welcome.vue +++ b/renderer/src/views/debug/welcome.vue @@ -7,7 +7,7 @@ { break; - case 'web/update-connection-sigature': + case 'web/update-connection-signature': updateConnectionOption(data); break; diff --git a/service/src/server.ts b/service/src/server.ts index b036b45..0d70b38 100644 --- a/service/src/server.ts +++ b/service/src/server.ts @@ -179,7 +179,7 @@ wss.on('connection', (ws: any) => { break; - case 'web/update-connection-sigature': + case 'web/update-connection-signature': updateConnectionOption(data); break; diff --git a/software/src/main.ts b/software/src/main.ts index 3d098da..1e9867d 100644 --- a/software/src/main.ts +++ b/software/src/main.ts @@ -64,7 +64,7 @@ function createWindow(): void { break; - case 'electron/update-connection-sigature': + case 'electron/update-connection-signature': updateConnectionOption(data); break; diff --git a/src/webview/webview.service.ts b/src/webview/webview.service.ts index 6763a67..6bc86b0 100644 --- a/src/webview/webview.service.ts +++ b/src/webview/webview.service.ts @@ -99,7 +99,7 @@ export function revealOpenMcpWebviewPanel( break; - case 'vscode/update-connection-sigature': + case 'vscode/update-connection-signature': if (type === 'installed') { updateInstalledConnectionConfig(panelKey, data); } else {