内容
# 大型代码仓库 MCP 服务器
基于标准输入输出的 [模型上下文协议](https://modelcontextprotocol.io/) 服务器,设计为适用于大型复杂代码仓库的标准工具包。使用 [ripgrep](https://github.com/BurntSushi/ripgrep) 实现快速、有界限的搜索,适用于任意大小的代码库。
## 架构
```
┌─────────────────────────────────────────────────────────────────┐
│ MCP 客户端(Codex CLI / Claude Desktop / Claude Code) │
│ │
│ tools/call ──► JSON-RPC 2.0 请求 │
│ 内容长度: N\r\n\r\n{...} │
└─────────────┬───────────────────────────────────▲───────────────┘
│ 标准输入 │ 标准输出
▼ │
┌─────────────────────────────────────────────────────────────────┐
│ large-repo-mcp 服务器 │
│ │
│ ┌──────────┐ ┌────────────┐ ┌──────────────────────┐ │
│ │ 帧解析器 │───►│ JSON-RPC │───►│ 工具调度 │ │
│ │ 内容长度 │ │ 路由器 │ │ │ │
│ │ 帧构建 │ │ 初始化 │ │ 项目搜索 rg │ │
│ │ │ │ 工具列表 │ │ 符号搜索 │ │
│ │ │ │ 工具调用 │ │ 读取范围 │ │
│ └──────────┘ │ ping │ └──────────┬───────────┘ │
│ └────────────┘ │ │
│ │ │
│ ┌────────────────────────────────────────────▼──────────┐ │
│ │ 安全层 │ │
│ │ │ │
│ │ • 路径限制(解析 + 实际路径 + 根目录检查) │ │
│ │ • 命令允许列表(仅 rg,shell: false) │ │
│ │ • 请求大小限制(1 MB) │ │
│ │ • 响应大小限制(200 KB) │ │
│ │ • 空字节拒绝 │ │
│ └───────────────────────────┬───────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ rg(ripgrep) │ │
│ │ 子进程 │ │
│ │ │ │
│ │ • 15 秒超时 │ │
│ │ • JSON 输出 │ │
│ │ • 流式输出 │ │
│ └─────────────────┘ │
│ 标准错误 ──► │
│ 结构化 JSON 日志 │
└─────────────────────────────────────────────────────────────────┘
```
## 请求流程
```
客户端 服务器 ripgrep
│ │ │
│ 内容长度: N\r\n\r\n │ │
│ {"jsonrpc":"2.0", │ │
│ "method":"tools/call",...} │ │
│──────────────────────────────►│ │
│ │ 验证请求大小(≤1MB) │
│ │ 解析 JSON-RPC 帧 │
│ │ 验证工具 + 参数 │
│ │ 解析并限制路径 │
│ │ │
│ │ 启动 rg --json ... │
│ │──────────────────────────────►│
│ │ │
│ │ 流式传输结果(逐行)│
│ │◄──────────────────────────────│
│ │ │
│ │ 执行匹配/字节限制 │
│ │ 达到限制时终止 rg │
│ │ │
│ 内容长度: M\r\n\r\n │ │
│ {"jsonrpc":"2.0", │ │
│ "result":{...}} │ │
│◄──────────────────────────────│ │
│ │ │
```
## 安全保证
| 保证 | 机制 | 限制 |
|-----------|-----------|-------|
| 快速、有界限的搜索 | ripgrep 带有匹配上限 | 最大 500 个匹配 |
| 响应大小限制 | 字节级输出预算 | 200 KB |
| 子进程超时 | `setTimeout` + `child.kill()` | 15 秒 |
| 路径限制 | `path.resolve` + `realpath` + 根目录前缀检查 | 仅限仓库根目录 |
| 符号链接逃逸预防 | `fs.realpath()` 解析然后重新验证 | 双重检查 |
| 命令执行 | 允许列表(仅 `rg`)+ `shell: false` | 无 shell 注入 |
| 请求大小限制 | 解析前在帧级别拒绝 | 1 MB |
| 输入净化 | 空字节拒绝,类型验证 | 所有工具输入 |
| 子进程清理 | 跟踪集合,在关闭信号时终止 | `SIGTERM`/`SIGINT`/`exit` |
## 支持的客户端
- [Codex CLI](https://github.com/openai/codex)
- [Claude Desktop](https://claude.ai/download)
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
- 任何支持 stdio 传输的 MCP 客户端(协议版本 `2024-11-05`)
## 要求
- **Node.js** 18+
- **ripgrep**(`rg`)在 `PATH` 上
- `symbol_search` 需要 PCRE2 支持(大多数官方软件包都包含它)
验证 ripgrep:
```bash
rg --version # 显示版本号
rg --pcre2-version # 显示 PCRE2 版本
```
安装 ripgrep:
| 平台 | 命令 |
|----------|---------|
| macOS | `brew install ripgrep` |
| Ubuntu/Debian | `sudo apt-get install ripgrep` |
| Fedora | `sudo dnf install ripgrep` |
| Windows | `winget install BurntSushi.ripgrep.MSVC` |
| Cargo | `cargo install ripgrep --features pcre2` |
## 安装
```bash
npm install
npm run build
```
## 运行
```bash
npm start
```
默认仓库根目录行为:
- 如果 `REPO_ROOT` 未设置,则仓库根目录为当前工作目录(`process.cwd()`)。
- 设置 `REPO_ROOT` 以显式覆盖。
PowerShell:
```powershell
$env:REPO_ROOT = "C:\absolute\path\to\repo"
npm start
```
## MCP 配置
### Codex(全局)
添加到 `~/.codex/config.toml`:
```toml
[mcp_servers.large_repo_mcp]
command = "node"
args = ["C:/absolute/path/to/mcp/dist/server.js"]
startup_timeout_sec = 30
[mcp_servers.large_repo_mcp.env]
REPO_ROOT = "."
```
### Codex(项目本地)
添加到项目中的 `.codex/config.toml`:
```toml
[mcp_servers.large_repo_mcp]
command = "node"
args = ["C:/absolute/path/to/mcp/dist/server.js"]
startup_timeout_sec = 30
[mcp_servers.large_repo_mcp.env]
REPO_ROOT = "."
```
### Claude Desktop
添加到 Claude Desktop MCP 配置:
```json
{
"mcpServers": {
"large_repo_mcp": {
"command": "node",
"args": ["C:/absolute/path/to/mcp/dist/server.js"],
"env": {
"REPO_ROOT": "C:/absolute/path/to/target-repo"
}
}
}
}
```
### Claude Code
添加到项目中的 `.mcp.json` 或全局的 `~/.claude/mcp.json`:
```json
{
"mcpServers": {
"large_repo_mcp": {
"command": "node",
"args": ["C:/absolute/path/to/mcp/dist/server.js"],
"env": {
"REPO_ROOT": "."
}
}
}
}
```
## 环境变量
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `REPO_ROOT` | `process.cwd()` | 仓库根目录 |
| `LARGE_REPO_MCP_LOG_LEVEL` | `error` | 日志级别:`error`、`warn`、`info`、`debug` |
| `LARGE_REPO_MCP_DEBUG` | — | 设置为 `1` 以强制调试日志记录 |
## 工具
### `project_search_rg`
使用 ripgrep 搜索仓库。支持正则表达式模式和可选的 glob 过滤器。
```
┌──────────────────────────────────────────────────────┐
│ project_search_rg │
│ │
│ 输入 输出 │
│ ───── ────── │
│ pattern(字符串,必填) matches[] │
│ globs(字符串数组,最大 50) .path │
│ maxMatches(1-500,默认 100) .line │
│ .column │
│ .text │
│ .submatches[] │
│ truncated │
│ truncateReason │
│ timedOut │
│ serverVersion │
│ durationMs │
└──────────────────────────────────────────────────────┘
```
**示例调用:**
```json
{
"name": "project_search_rg",
"arguments": {
"pattern": "TODO|FIXME",
"globs": ["*.ts", "*.tsx"],
"maxMatches": 50
}
}
```
### `symbol_search`
使用单词边界匹配(`\b...\b`)搜索确切的符号。自动检测项目类型(TypeScript 或 Python),并相应地限定文件类型。
```
┌──────────────────────────────────────────────────────┐
│ symbol_search │
│ │
│ 输入 输出 │
│ ───── ────── │
│ symbol(字符串,必填) projectType │
│ maxMatches(1-500,默认 100) matchMode │
│ matches[] │
│ .path │
│ 检测逻辑: .line │
│ ┌────────────────────┐ .column │
│ │ tsconfig.json? │ .text │
│ │ 是 → TypeScript │ .submatches[] │
│ │ 否 → 检查文件 │ │
│ │ .py 仅 → Python│ │
│ │ .ts 仅 → TypeScript │ │
│ │ 默认 → TypeScript │ │
│ └────────────────────┘ │
└──────────────────────────────────────────────────────┘
```
**示例调用:**
```json
{
"name": "symbol_search",
"arguments": {
"symbol": "handleRequest",
"maxMatches": 20
}
}
```
### `read_range`
读取文件中的特定行范围。路径必须相对并在仓库根目录内解析。
```
┌──────────────────────────────────────────────────────┐
│ read_range │
│ │
│ 输入 输出 │
│ ───── ────── │
│ path(相对,必填) path(规范化) │
│ startLine(整数,必填) requestedLines │
│ endLine(整数,必填) returnedLines │
│ lines[] │
│ 约束: .line │
│ • 每次调用最多 500 行 .text │
│ • 路径限定为仓库根目录 truncated │
│ • 符号链接已解析和检查 truncateReason │
└──────────────────────────────────────────────────────┘
```
**示例调用:**
```json
{
"name": "read_range",
"arguments": {
"path": "src/server.ts",
"startLine": 1,
"endLine": 50
}
}
```
### `list_files`
使用 ripgrep `--files` 列出仓库文件,带有可选的 glob 过滤器。默认情况下排除 `.git`、`node_modules`、`dist`、`build` 和 `coverage`。
```
┌──────────────────────────────────────────────────────┐
│ list_files │
│ │
│ 输入 输出 │
│ ───── ────── │
│ globs(字符串数组,最大 50) files[](路径) │
│ maxResults(1-500,默认 500) returned │
│ truncated │
│ 自动排除目录: truncateReason │
│ .git、node_modules、dist、 timedOut │
│ build、coverage │
└──────────────────────────────────────────────────────┘
```
**示例调用:**
```json
{
"name": "list_files",
"arguments": {
"globs": ["src/**/*.ts"],
"maxResults": 100
}
}
```
## 项目类型检测
服务器自动检测仓库是 TypeScript 还是 Python,以限定 `symbol_search` 文件类型。检测每进程运行一次,并缓存。
```
┌─────────────────────┐
│ tsconfig.json │
│ 存在? │
└──────┬──────────────┘
是 │ 否
┌──────────┘ │
▼ ▼
┌──────────┐ ┌────────────────────┐
│TypeScript│ │ Python 项目 │
└──────────┘ │ 文件是否存在? │
│ (pyproject.toml, │
│ requirements.txt, │
│ setup.py, 等) │
└──────┬─────────────┘
是 │ 否
┌──────────┤ │
▼ │ ▼
┌────────────┐ │ ┌──────────────────┐
│package.json│ │ │ package.json │
│ 存在? │ │ │ 存在? │
└─────┬──────┘ │ └──────┬───────────┘
是 │ 否 │ 是 │ 否
│ │ │ │ │ │ │
▼ │ ▼ │ ▼ │ ▼
┌────────┐│ ┌──────┐ │ ┌──────────┐ ┌──────────────┐
│ 两者 ││ │PYTHON│ │ │TypeScript│ │ 计算 .ts vs │
│ 扫描 ││ └──────┘ │ └──────────┘ │ .py 文件 │
│ 文件 │▼ ▼ └──────┬───────┘
└───┬────┘ ┌──────────┐ 更多 │ 更多
│ │ 无 pkg, │ .py │ .ts
▼ │ 有 py │ │ │
┌────────────┐ │ 文件 → │ ▼ ▼
│ .py 仅 → │ │ PYTHON │ ┌──────┐ ┌──┐
│ PYTHON │ └──────────┘ │PYTHON│ │TS│
│ .ts 仅 → │ └──────┘ └──┘
│ TS │
│ 默认 → │
│ TS │
└────────────┘
```
## 开发工作流
```bash
npm run typecheck # 类型检查,无需编译
npm test # 构建 + 运行单元测试和集成测试
npm run lint # 运行 ESLint
npm run format:check # 检查 Prettier 格式化
```
## 故障排除
| 问题 | 解决方案 |
|---------|----------|
| `rg` 未找到 | 安装 ripgrep 并确保它在 `PATH` 上 |
| `symbol_search` PCRE2 错误 | 安装带有 PCRE2 支持的 ripgrep(大多数官方软件包都包含它) |
| `Request exceeds 1048576 bytes` | 分割大请求;最大传入 JSON-RPC 帧体为 1 MB |
| `truncated: true` | 增加 `maxMatches`/`maxResults`(达到上限),缩小查询范围,或添加 glob |
| `symbol_search` 无结果 | 检查响应中的 `projectType` — 检测可能选择了错误的语言;使用 `project_search_rg` 作为备用 |
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器