代码工具MCP服务器
- 仅本地MCP服务器通过STDIO为LLM提供核心编码工具。
- 工具:
list_directory,read_file,write_file,search_file_content,glob,replace,read_many_files.
Windows上的Codex CLI有局限性,因为它依赖于编写PowerShell/Python脚本进行基本的读、写、grep操作。此MCP服务器公开了使Codex CLI在Windows上更快的标准工具。您可以在Linux或Mac上使用它,它可以工作,但可能不是必需的。
这是没有保证的,任何问题或错误都应该报告给存储库,但要意识到风险,并自行承担使用风险。
发布说明可在中跟踪 CHANGELOG.md.
安装
- 全球的:
npm i -g code-tools-mcp - 一次性:
npx code-tools-mcp
跑
code-tools-mcp --root C:/path/to/workspace
CODEX CLI配置示例
[mcp_servers.code-tools]
command = "{path to npm.cmd}"
args = [ "-y", "code-tools-mcp"]
env = { APPDATA = "C:\\Users\\{username}\\AppData\\Roaming", LOCALAPPDATA = "C:\\Users\\{username}\\AppData\\Local", HOME = "C:\\Users\\{username}", SystemRoot = "C:\\Windows", ComSpec = "C:\\Windows\\System32\\cmd.exe" }
startup_timeout_ms = 20_000自动检测到工作区根:
- 如果
CODE_TOOLS_MCP_ROOT定了,就赢了。 - 否则,如果传递了CLI标志,则使用它:
--root C:/path/to/workspace(或-r). - 否则,服务器会从当前工作目录向上查找
.git文件夹,并将该目录用作根目录。 - 否则,它默认为当前工作目录。
- MCP初始化后,如果客户端支持Roots,服务器将调用
roots/list并使用这些file://根作为活动权限根。 - 如果客户端发送
notifications/roots/list_changed,服务器会自动刷新根目录。 - 如果无效
file://如果返回根,则现有的env/CLI/git派生根仍然有效。
其他工作区根:
- 集
CODE_TOOLS_MCP_ROOTS或通过--roots(路径分隔符分隔)以添加额外的工作区目录。
可选的无限制路径模式:
- 集
CODE_TOOLS_MCP_ALLOW_ANY_PATHS=true以允许在配置的工作区根之外进行访问。 - 在这种模式下,工具仍然应用敏感的路径检查;除非明确启用,否则忽略工作区外路径的默认过滤设置为关闭。
不带env-var的Claude配置示例(传递根标志):
{
"mcpServers": {
"code-tools": {
"command": "node",
"args": [
"C:/Users/adity/Projects/code-tools-mcp/dist/index.js",
"--root",
"C:/Users/adity/Projects/code-tools-mcp"
]
}
}
}Claude桌面配置示例
添加到您的Claude配置JSON中:
{
"mcpServers": {
"code-tools": {
"command": "node",
"args": ["/ABSOLUTE/PATH/code-tools-mcp/dist/index.js"],
"env": { "CODE_TOOLS_MCP_ROOT": "/ABSOLUTE/PATH/TO/YOUR/WORKSPACE" }
}
}
}备注
- 使用STDIO传输;避免
console.log(stdout)。所有诊断都会写入stderr。 - 文件操作仅限于工作区根。
- 您可以通过以下方式选择不受限制的文件系统访问
CODE_TOOLS_MCP_ALLOW_ANY_PATHS=true. - 默认情况下,所有工具都执行相同的路径策略:除非明确覆盖,否则敏感和git忽略的路径将被阻止。
ripgrep是已弃用的别名search_file_content;使用search_file_content前进。.geminiignore参数被解析为Gemini奇偶校验,但尚未应用于忽略逻辑(在我们将行为与.gitignore处理)。计划在下一个小版本中发布;有关更新,请参阅CHANGELOG。
______________________________________________________________________
一切:
- 使用AST的Repomap
______________________________________________________________________
工具
list_directory
列出目录内容,首先列出目录,尊重 .gitignore.
参数:
dir_path(字符串,必填):绝对路径,或工作区到目录的相对路径no_ignore(布尔值,可选):跳过gitignore过滤respect_git_ignore(布尔值,可选):显式启用/禁用gitignore过滤ignore(string\[\],可选):要忽略的Glob模式(名称匹配)file_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }max_entries(数字,可选):响应中包含的最大条目数
例子:
await client.callTool('list_directory', {
dir_path: '/path/to/workspace/src'
});read_file
读取具有可选分页的文件。二进制感知(图像、音频、PDF)。
参数:
file_path(字符串,必填):绝对路径,或文件的工作区相对路径no_ignore(布尔值,可选):跳过gitignore过滤respect_git_ignore(布尔值,可选):显式启用/禁用gitignore过滤file_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }offset(数字,可选):起始行(从0开始)limit(number,可选):要返回的行数
例子:
await client.callTool('read_file', {
file_path: '/path/to/workspace/src/index.ts',
offset: 0,
limit: 100
});write_file
创建或覆盖文件。
参数:
file_path(string,必填):要写入的文件的绝对路径或工作区相对路径no_ignore(布尔值,可选):跳过gitignore过滤respect_git_ignore(布尔值,可选):显式启用/禁用gitignore过滤file_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }content(字符串,必填):完整文件内容
例子:
await client.callTool('write_file', {
file_path: '/path/to/workspace/src/new-file.ts',
content: 'export const foo = "bar";'
});搜索文件内容
使用ripgrep进行快速正则表达式搜索(如果不可用,则回退到JS搜索)。
参数:
pattern(字符串,必填):搜索模式(默认为正则表达式)dir_path(字符串,可选):要搜索的目录或文件(绝对或相对工作区)include(字符串,可选):Glob过滤器(例如。,**/*.ts)case_sensitive(boolean,可选):如果为true,则搜索区分大小写(默认为false)fixed_strings(boolean,可选):如果为true,则将模式视为文字context(数字,可选):接受ripgrep奇偶校验;紧凑型输出目前仅返回匹配的行after(数字,可选):接受ripgrep奇偶校验;紧凑型输出目前仅返回匹配的行before(数字,可选):接受ripgrep奇偶校验;紧凑型输出目前仅返回匹配的行no_ignore(boolean,可选):如果为true,则不尊重忽略文件/默认排除respect_git_ignore(布尔值,可选):显式启用/禁用忽略过滤file_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }max_matches(数字,可选):返回的最大匹配项数max_output_bytes(数字,可选):最大输出大小(字节)
例子:
await client.callTool('search_file_content', {
pattern: 'function.*async',
include: '**/*.ts'
});通配符
查找与glob模式匹配的文件。
参数:
pattern(string,必填):球状图案(例如。,src/**/*.ts)dir_path(字符串,可选):要在其中搜索的绝对目录case_sensitive(布尔值,可选):区分大小写的匹配(默认为false)no_ignore(布尔值,可选):跳过gitignore过滤file_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }respect_git_ignore(布尔值,可选):尊重.gitignore(默认为true)respect_gemini_ignore(布尔值,可选):保留用于Gemini兼容性max_results(数字,可选):响应中包含的最大路径
例子:
await client.callTool('glob', {
pattern: 'src/**/*.ts'
});替换
使用精确的文字匹配替换文件中的文本。
参数:
file_path(字符串,必填)no_ignore(布尔值,可选):跳过gitignore过滤respect_git_ignore(布尔值,可选):显式启用/禁用gitignore过滤file_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }instruction(字符串,可选)old_string(字符串,必填)new_string(字符串,必填)expected_replacements(数字,可选)
例子:
await client.callTool('replace', {
file_path: '/path/to/workspace/src/index.ts',
old_string: 'const foo = 1;',
new_string: 'const foo = 2;'
});read_many_files
读取并连接多个文件中的内容。
参数:
include(string\[\],必填):全局模式或路径exclude(string\[\],可选)no_ignore(布尔值,可选):跳过gitignore过滤respect_git_ignore(布尔值,可选):显式启用/禁用gitignore过滤recursive(boolean,可选):保留兼容性;递归搜索目前是默认行为useDefaultExcludes(boolean,可选):默认为truefile_filtering_options(对象,可选):{ respect_git_ignore?: boolean, respect_gemini_ignore?: boolean }max_files(数字,可选):响应中包含的最大文件数max_output_bytes(数字,可选):最大输出大小(字节)
例子:
await client.callTool('read_many_files', {
include: ['src/**/*.ts']
});______________________________________________________________________
从MCP客户端使用这些工具
工具发现:客户端调用tools/list(支持光标分页)并可能接收tools/list_changed当设置更改时。
TypeScript示例
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
// Connect to the server
const transport = new StdioClientTransport({
command: 'node',
args: ['/path/to/code-tools-mcp/dist/index.js'],
env: { CODE_TOOLS_MCP_ROOT: '/path/to/workspace' }
});
const client = new Client({
name: 'example-client',
version: '1.0.0'
}, {
capabilities: {}
});
await client.connect(transport);
// List available tools
const tools = await client.listTools();
console.log('Available tools:', tools.tools.map(t => t.name));
// Call a tool
const result = await client.callTool({
name: 'read_file',
arguments: {
file_path: '/path/to/workspace/src/index.ts'
}
});
console.log('Result:', result);______________________________________________________________________
工具稳定性
- 工具名称稳定 并且不会在次要版本中更改
- 参数名称稳定 -可以添加新的可选参数
- 描述简洁明了 -详细的参数文档在JSON模式中(通过Zod)
.describe())
______________________________________________________________________
TypeScript类型
所有工具输入和输出类型均可在 src/types/tools.ts:
import type {
ReadFileInput,
ReadFileOutput,
SearchFileContentInput,
SearchFileContentOutput,
// ... other types
} from 'code-tools-mcp/types/tools';