feat(MCP): add auto-install server configuration and migration for ve… (#4156)

* feat(MCP): add auto-install server configuration and migration for version 87

* update persistReducer version
This commit is contained in:
MyPrototypeWhat 2025-03-31 18:07:50 +08:00 committed by GitHub
parent 5223a3c5a6
commit 2da8a73124
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 53 additions and 4 deletions

View File

@ -42,7 +42,7 @@ const persistedReducer = persistReducer(
{
key: 'cherry-studio',
storage,
version: 87,
version: 88,
blacklist: ['runtime', 'messages'],
migrate
},

View File

@ -1,8 +1,20 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { MCPConfig, MCPServer } from '@renderer/types'
import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
import { nanoid } from '@reduxjs/toolkit'
import type { MCPConfig, MCPServer } from '@renderer/types'
const initialState: MCPConfig = {
servers: []
servers: [
{
id: nanoid(),
name: 'mcp-auto-install',
description: 'Automatically install MCP services (Beta version)',
baseUrl: '',
command: 'npx',
args: ['-y', '@mcpmarket/mcp-auto-install', 'connect', '--json'],
env: {},
isActive: false
}
]
}
const mcpSlice = createSlice({
@ -47,5 +59,6 @@ export const { getActiveServers, getAllServers } = mcpSlice.selectors
// Type-safe selector for accessing this slice from the root state
export const selectMCP = (state: { mcp: MCPConfig }) => state.mcp
export { mcpSlice }
// Export the reducer as default export
export default mcpSlice.reducer

View File

@ -12,6 +12,7 @@ import { createMigrate } from 'redux-persist'
import { RootState } from '.'
import { INITIAL_PROVIDERS, moveProvider } from './llm'
import { mcpSlice } from './mcp'
import { DEFAULT_SIDEBAR_ICONS } from './settings'
// remove logo base64 data to reduce the size of the state
@ -1148,6 +1149,22 @@ const migrateConfig = {
} catch (error) {
return state
}
},
'88': (state: RootState) => {
try {
if (state?.mcp?.servers) {
const hasAutoInstall = state.mcp.servers.some((server) => server.name === 'mcp-auto-install')
if (!hasAutoInstall) {
const defaultServer = mcpSlice.getInitialState().servers[0]
state.mcp.servers = [{ ...defaultServer, id: nanoid() }, ...state.mcp.servers]
}
}
} catch (error) {
console.error(error)
return state
}
return state
}
}

View File

@ -1,6 +1,8 @@
import { Tool, ToolUnion, ToolUseBlock } from '@anthropic-ai/sdk/resources'
import { FunctionCall, FunctionDeclaration, SchemaType, Tool as geminiToool } from '@google/generative-ai'
import { nanoid } from '@reduxjs/toolkit'
import store from '@renderer/store'
import { addMCPServer } from '@renderer/store/mcp'
import { MCPServer, MCPTool, MCPToolResponse } from '@renderer/types'
import { ChatCompletionMessageToolCall, ChatCompletionTool } from 'openai/resources'
@ -126,6 +128,23 @@ export async function callMCPTool(tool: MCPTool): Promise<any> {
})
console.log(`[MCP] Tool called: ${tool.serverName} ${tool.name}`, resp)
if (tool.serverName === 'mcp-auto-install') {
if (resp.data) {
const mcpServer: MCPServer = {
id: nanoid(),
name: resp.data.name,
description: resp.data.description,
baseUrl: resp.data.baseUrl,
command: resp.data.command,
args: resp.data.args,
env: resp.data.env,
isActive: false
}
store.dispatch(addMCPServer(mcpServer))
}
}
return resp
} catch (e) {
console.error(`[MCP] Error calling Tool: ${tool.serverName} ${tool.name}`, e)