mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-08 06:19:05 +08:00
* refactor: rewrite filesystem MCP server with new tool set - Replace existing filesystem MCP with modular architecture - Implement 6 new tools: glob, ls, grep, read, write, delete - Add comprehensive TypeScript types and Zod schemas - Maintain security with path validation and allowed directories - Improve error handling and user feedback - Add result limits for performance (100 files/matches max) - Format output with clear, helpful messages - Keep backward compatibility with existing import patterns BREAKING CHANGE: Tools renamed from snake_case to lowercase - read_file → read - write_file → write - list_directory → ls - search_files → glob - New tools: grep, delete - Removed: edit_file, create_directory, directory_tree, move_file, get_file_info * 🐛 fix: remove filesystem allowed directories restriction * 🐛 fix: relax binary detection for text files * ✨ feat: add edit tool with fuzzy matching to filesystem MCP server - Add edit tool with 9 fallback replacers from opencode for robust string replacement (SimpleReplacer, LineTrimmedReplacer, BlockAnchorReplacer, WhitespaceNormalizedReplacer, etc.) - Add Levenshtein distance algorithm for similarity matching - Improve descriptions for all tools (read, write, glob, grep, ls, delete) following opencode patterns for better LLM guidance - Register edit tool in server and export from tools index * ♻️ refactor: replace allowedDirectories with baseDir in filesystem MCP server - Change server to use single baseDir (from WORKSPACE_ROOT env or userData/workspace default) - Remove list_allowed_directories tool as restriction mechanism is removed - Add ripgrep integration for faster grep searches with JS fallback - Simplify validatePath() by removing allowlist checks - Display paths relative to baseDir in tool outputs * 📝 docs: standardize filesystem MCP server tool descriptions - Unify description format to bullet-point style across all tools - Add absolute path requirement to ls, glob, grep schemas and descriptions - Update glob and grep to output absolute paths instead of relative paths - Add missing error case documentation for edit tool (old_string === new_string) - Standardize optional path parameter descriptions * ♻️ refactor: use ripgrep for glob tool and extract shared utilities - Extract shared ripgrep utilities (runRipgrep, getRipgrepAddonPath) to types.ts - Rewrite glob tool to use `rg --files --glob` for reliable file matching - Update grep tool to import shared ripgrep utilities * 🐛 fix: handle ripgrep exit code 2 with valid results in glob tool - Process ripgrep stdout when content exists, regardless of exit code - Exit code 2 can indicate partial errors while still returning valid results - Remove fallback directory listing (had buggy regex for root-level files) - Update tool description to clarify patterns without "/" match at any depth * 🔥 chore: remove filesystem.ts.backup file Remove unnecessary backup file from mcpServers directory * 🐛 fix: use correct default workspace path in filesystem MCP server Change default baseDir from userData/workspace to userData/Data/Workspace to match the app's data storage convention (Data/Files, Data/Notes, etc.) Addresses PR #11937 review feedback. * 🐛 fix: pass WORKSPACE_ROOT to FileSystemServer constructor The envs object passed to createInMemoryMCPServer was not being used for the filesystem server. Now WORKSPACE_ROOT is passed as a constructor parameter, following the same pattern as other MCP servers. * \feat: add link to documentation for MCP server configuration requirement Wrap the configuration requirement tag in a link to the documentation for better user guidance on MCP server settings. --------- Co-authored-by: kangfenmao <kangfenmao@qq.com>
59 lines
2.0 KiB
TypeScript
59 lines
2.0 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(envs.WORKSPACE_ROOT).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}`)
|
|
}
|
|
}
|