cherry-studio/src/main/mcpServers/factory.ts
LiuVaayne d41229c69b
Add browser CDP MCP server with session management (#11844)
*  feat: add CDP browser MCP server

* ♻️ refactor: add navigation timeout for browser cdp

* 🐛 fix: reuse window for execute and add debugger logging

*  feat: add show option and multiline execute for browser cdp

*  feat: support multiple sessions for browser cdp

* ♻️ refactor: add LRU and idle cleanup for browser cdp sessions

* Refactor browser-cdp for readability and set Firefox UA

* 🐛 fix: type electron mock for cdp tests

* ♻️ refactor: rename browser_cdp MCP server to browser

Simplify the MCP server name from @cherry/browser-cdp to just browser
for cleaner tool naming in the MCP protocol.

*  feat: add fetch tool to browser MCP server

Add a new `fetch` tool that uses the CDP-controlled browser to fetch URLs
and return content in various formats (html, txt, markdown, json).

Also ignore .conductor folder in biome and eslint configs.

* ♻️ refactor: split browser MCP server into modular folder structure

Reorganize browser.ts (525 lines) into browser/ folder with separate
files for better maintainability. Each tool now has its own file with
schema, definition, and handler.

* ♻️ refactor: use switch statement in browser server request handler

* ♻️ refactor: extract helpers and use handler registry pattern

- Add successResponse/errorResponse helpers in tools/utils.ts
- Add closeWindow helper to consolidate window cleanup logic
- Add ensureDebuggerAttached helper to consolidate debugger setup
- Add toolHandlers map for registry-based handler lookup
- Simplify server.ts to use dynamic handler dispatch

* 🐛 fix: improve browser MCP server robustness

- Add try-catch for JSON.parse in fetch() to handle invalid JSON gracefully
- Add Zod schema validation to reset tool for consistency with other tools
- Fix memory leak in open() by ensuring event listeners cleanup on timeout
- Add JSDoc comments for key methods and classes

* ♻️ refactor: rename browser MCP to @cherry/browser

Follow naming convention of other builtin MCP servers.

* 🌐 i18n: translate pending strings across 8 locales

Translate all "[to be translated]" markers including:
- CDP browser MCP server description (all 8 locales)
- "Extra High" reasoning chain length option (6 locales)
- Git Bash configuration strings (el-gr, ja-jp)
2025-12-16 09:29:30 +08:00

59 lines
1.9 KiB
TypeScript

import { loggerService } from '@logger'
import type { Server } from '@modelcontextprotocol/sdk/server/index.js'
import type { BuiltinMCPServerName } from '@types'
import { BuiltinMCPServerNames } from '@types'
import BraveSearchServer from './brave-search'
import BrowserServer from './browser'
import DiDiMcpServer from './didi-mcp'
import DifyKnowledgeServer from './dify-knowledge'
import FetchServer from './fetch'
import FileSystemServer from './filesystem'
import MemoryServer from './memory'
import PythonServer from './python'
import ThinkingServer from './sequentialthinking'
const logger = loggerService.withContext('MCPFactory')
export function createInMemoryMCPServer(
name: BuiltinMCPServerName,
args: string[] = [],
envs: Record<string, string> = {}
): Server {
logger.debug(`[MCP] Creating in-memory MCP server: ${name} with args: ${args} and envs: ${JSON.stringify(envs)}`)
switch (name) {
case BuiltinMCPServerNames.memory: {
const envPath = envs.MEMORY_FILE_PATH
return new MemoryServer(envPath).server
}
case BuiltinMCPServerNames.sequentialThinking: {
return new ThinkingServer().server
}
case BuiltinMCPServerNames.braveSearch: {
return new BraveSearchServer(envs.BRAVE_API_KEY).server
}
case BuiltinMCPServerNames.fetch: {
return new FetchServer().server
}
case BuiltinMCPServerNames.filesystem: {
return new FileSystemServer(args).server
}
case BuiltinMCPServerNames.difyKnowledge: {
const difyKey = envs.DIFY_KEY
return new DifyKnowledgeServer(difyKey, args).server
}
case BuiltinMCPServerNames.python: {
return new PythonServer().server
}
case BuiltinMCPServerNames.didiMCP: {
const apiKey = envs.DIDI_API_KEY
return new DiDiMcpServer(apiKey).server
}
case BuiltinMCPServerNames.browser: {
return new BrowserServer().server
}
default:
throw new Error(`Unknown in-memory MCP server: ${name}`)
}
}