refactor: enhance mcp init (#4238)

* fix(MCPService): extend command support to include 'bun' and 'bunx', and improve environment variable handling

* fix(MCPService): enhance environment variable handling by incorporating default environment settings

* fix(hooks): simplify active MCP servers selection logic
This commit is contained in:
LiuVaayne 2025-04-01 13:08:25 +08:00 committed by GitHub
parent 95df69ff82
commit d7bd240a9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 20 deletions

View File

@ -5,7 +5,7 @@ import { isLinux, isMac, isWin } from '@main/constant'
import { getBinaryName, getBinaryPath } from '@main/utils/process' import { getBinaryName, getBinaryPath } from '@main/utils/process'
import { Client } from '@modelcontextprotocol/sdk/client/index.js' import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js' import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js' import { getDefaultEnvironment, StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
import { nanoid } from '@reduxjs/toolkit' import { nanoid } from '@reduxjs/toolkit'
import { MCPServer, MCPTool } from '@types' import { MCPServer, MCPTool } from '@types'
import { app } from 'electron' import { app } from 'electron'
@ -69,13 +69,8 @@ class McpService {
} else if (server.command) { } else if (server.command) {
let cmd = server.command let cmd = server.command
if (server.command === 'npx') { if (server.command === 'npx' || server.command === 'bun' || server.command === 'bunx') {
cmd = await getBinaryPath('bun') cmd = await getBinaryPath('bun')
if (cmd === 'bun') {
cmd = 'npx'
}
Logger.info(`[MCP] Using command: ${cmd}`) Logger.info(`[MCP] Using command: ${cmd}`)
// add -x to args if args exist // add -x to args if args exist
@ -83,25 +78,20 @@ class McpService {
if (!args.includes('-y')) { if (!args.includes('-y')) {
!args.includes('-y') && args.unshift('-y') !args.includes('-y') && args.unshift('-y')
} }
if (cmd.includes('bun') && !args.includes('x')) { if (!args.includes('x')) {
args.unshift('x') args.unshift('x')
} }
} }
}
if (server.command === 'uvx') {
cmd = await getBinaryPath('uvx')
}
Logger.info(`[MCP] Starting server with command: ${cmd} ${args ? args.join(' ') : ''}`)
if (server.registryUrl) { if (server.registryUrl) {
if (cmd.includes('npx') || cmd.includes('bun') || cmd.includes('bunx')) {
server.env = { server.env = {
...server.env, ...server.env,
NPM_CONFIG_REGISTRY: server.registryUrl NPM_CONFIG_REGISTRY: server.registryUrl
} }
} else if (cmd.includes('uvx') || cmd.includes('uv')) { }
} else if (server.command === 'uvx' || server.command === 'uv') {
cmd = await getBinaryPath(server.command)
if (server.registryUrl) {
server.env = { server.env = {
...server.env, ...server.env,
UV_DEFAULT_INDEX: server.registryUrl, UV_DEFAULT_INDEX: server.registryUrl,
@ -110,12 +100,14 @@ class McpService {
} }
} }
Logger.info(`[MCP] Starting server with command: ${cmd} ${args ? args.join(' ') : ''}`)
// Logger.info(`[MCP] Environment variables for server:`, server.env) // Logger.info(`[MCP] Environment variables for server:`, server.env)
transport = new StdioClientTransport({ transport = new StdioClientTransport({
command: cmd, command: cmd,
args, args,
env: { env: {
...getDefaultEnvironment(),
PATH: this.getEnhancedPath(process.env.PATH || ''), PATH: this.getEnhancedPath(process.env.PATH || ''),
...server.env ...server.env
} }
@ -251,6 +243,7 @@ class McpService {
`${homeDir}/.npm-global/bin`, `${homeDir}/.npm-global/bin`,
`${homeDir}/.yarn/bin`, `${homeDir}/.yarn/bin`,
`${homeDir}/.cargo/bin`, `${homeDir}/.cargo/bin`,
`${homeDir}/.cherrystudio/bin`,
'/opt/local/bin' '/opt/local/bin'
) )
} }
@ -264,12 +257,18 @@ class McpService {
`${homeDir}/.npm-global/bin`, `${homeDir}/.npm-global/bin`,
`${homeDir}/.yarn/bin`, `${homeDir}/.yarn/bin`,
`${homeDir}/.cargo/bin`, `${homeDir}/.cargo/bin`,
`${homeDir}/.cherrystudio/bin`,
'/snap/bin' '/snap/bin'
) )
} }
if (isWin) { if (isWin) {
newPaths.push(`${process.env.APPDATA}\\npm`, `${homeDir}\\AppData\\Local\\Yarn\\bin`, `${homeDir}\\.cargo\\bin`) newPaths.push(
`${process.env.APPDATA}\\npm`,
`${homeDir}\\AppData\\Local\\Yarn\\bin`,
`${homeDir}\\.cargo\\bin`,
`${homeDir}\\.cherrystudio\\bin`
)
} }
// 只添加不存在的路径 // 只添加不存在的路径

View File

@ -11,7 +11,7 @@ ipcRenderer.on('mcp:servers-changed', (_event, servers) => {
export const useMCPServers = () => { export const useMCPServers = () => {
const mcpServers = useAppSelector((state) => state.mcp.servers) const mcpServers = useAppSelector((state) => state.mcp.servers)
const activedMcpServers = useAppSelector((state) => state.mcp.servers?.filter((server) => server.isActive)) const activedMcpServers = mcpServers.filter((server) => server.isActive)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
return { return {