内容
# 代码导航 MCP
代码导航 MCP 是一个用于探索代码库的远程模型上下文协议服务器。它通过 `agents/mcp` 在 Cloudflare Workers 上运行,并提供工具,允许 MCP 客户端列出文件、读取源代码、搜索文本、检查导入和导出、查找函数和类、检测可能未使用的代码,并总结项目结构。
服务器端点是:
```text
/mcp
```
## 本项目的作用
本项目将一个仓库转化为一组 MCP 工具。连接的客户端可以提出以下问题:
- 项目中有哪些文件?
- 读取 `src/index.ts`。
- 搜索所有的 TODO。
- 查找导出的函数。
- 显示一个文件的导入。
- 统计文件类型。
- 查找从已知入口点无法到达的文件。
工具返回 JSON 作为 MCP 文本内容,因此客户端可以直接显示它或解析它以进行后续调用。
## 项目布局
```text
src/
index.ts MCP 服务器入口点和工具注册
schema.ts 已注册工具共享的 Zod 输入模式
tools.ts 公共工具实现
utils.ts 文件系统遍历、解析、搜索和辅助逻辑
types.ts 共享 TypeScript 结果和选项类型
constants.ts 支持的扩展、忽略的文件夹和默认入口点
```
一步一步:
1. `src/index.ts` 创建 `CodeNav MCP` 服务器,并使用 `this.server.registerTool(...)` 注册每个工具。
2. `src/schema.ts` 定义可重用的 Zod 模式,用于常见的选项,如 `rootDir`、`includeExtensions` 和 `excludeDirs`。
3. `src/tools.ts` 包含执行实际工作的函数。每个导出的函数映射到一个 MCP 工具。
4. `src/utils.ts` 包含用于路径安全、目录遍历、AST 解析、导入解析、搜索和结果格式化的低级助手。
5. `src/types.ts` 保留结果形状显式,如 `FileReadResult`、`ImportInfo`、`FunctionInfo` 和 `TodoInfo`。
6. `src/constants.ts` 定义了解的文件扩展名和默认情况下忽略的目录。
## 需求
- Node.js
- npm
- Cloudflare 账户(如果要部署)
- MCP 客户端,如 Claude Desktop、Cursor、Windsurf 或 Cloudflare AI Playground
安装依赖:
```bash
npm install
```
## 开发命令
```bash
npm run dev
```
启动本地 Wrangler 开发服务器。
```bash
npm run type-check
```
运行 TypeScript 而不发出文件。
```bash
npm run format
```
使用 `oxfmt` 格式化项目。
```bash
npm run lint:fix
```
运行 `oxlint` 并应用自动修复。
```bash
npm run deploy
```
使用 Wrangler 部署 Worker。
## 在本地运行文件系统工具
当您想要 CodeNav 检查此仓库中的文件时,请使用本地 Node.js stdio 服务器:
```bash
npm run mcp:local
```
MCP 客户端通常会为您从其配置中启动此命令。本地入口点是 `src/local.ts`,它具有对工作区文件系统的正常 Node.js 访问权限。
## 运行 Worker
启动服务器:
```bash
npm run dev
```
Wrangler 通常在以下地址提供 Worker:
```text
http://localhost:8787/mcp
```
如果 Wrangler 选择不同的端口,请使用终端中打印的 URL。
重要:Cloudflare Workers 不提供可读的本地文件系统。如果您通过 Worker 端点调用需要 `fs` 的 CodeNav 工具,服务器会返回一个明确的 MCP 错误,而不是更低级的 `[unenv] fs.readdir is not implemented yet!` 运行时错误。
## 连接 Claude Desktop
对于本地代码导航,请将 Claude Desktop 指向 Node.js stdio 入口点。
示例 Claude Desktop 配置:
```json
{
"mcpServers": {
"codenav": {
"command": "npm",
"args": ["run", "mcp:local"],
"cwd": "/Users/chukwudi/Documents/codenav-mcp"
}
}
}
```
保存配置后,重启 Claude Desktop。CodeNav 工具应该出现在 `codenav` 服务器下。
## 连接 VS Code
VS Code 可以使用工作区级别的 MCP 配置。此仓库包含:
```text
.vscode/mcp.json
```
配置将 VS Code 指向本地 Node.js stdio 服务器:
```json
{
"servers": {
"codenav-mcp": {
"command": "npm",
"args": ["run", "mcp:local"]
}
}
}
```
要使用它:
1. 在 VS Code 中打开此仓库。
2. 确保已使用 `npm install` 安装依赖。
3. 使用 VS Code 的 MCP 服务器控件启动或刷新 `codenav-mcp` 服务器。
如果您特别希望 VS Code 连接到 Worker 端点,请使用 `mcp-remote`:
```json
{
"servers": {
"codenav-mcp": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:8787/mcp"]
}
}
}
```
Worker 连接对于测试远程 MCP 传输很有用,但它无法读取本地项目文件。
## 部署
部署到 Cloudflare Workers:
```bash
npm run deploy
```
部署后,您的 MCP 端点将如下所示:
```text
https://<worker-name>.<account-subdomain>.workers.dev/mcp
```
在任何远程 MCP 客户端中使用已部署的 `/mcp` URL。
## 常见工具选项
大多数工具接受一个或多个共享选项。
| 选项 | 类型 | 含义 |
| --- | --- | --- |
| `rootDir` | `string` | 要检查的项目根目录。默认为 `process.cwd()`。 |
| `includeExtensions` | `string[]` | 限制扫描到特定扩展名,如 `[".ts", ".tsx"]`。 |
| `excludeDirs` | `string[]` | 要跳过的额外目录名称。 |
| `recursive` | `boolean` | 是否遍历嵌套目录。大多数扫描工具默认为递归行为。 |
| `includeHidden` | `boolean` | 包括点文件和点目录。默认为隐藏路径在目录遍历中被跳过。 |
| `maxResults` | `number` | 限制搜索样式的结果计数。支持的默认为 `100`。 |
| `maxBytes` | `number` | 限制文件读取大小。文件读取默认为 `256000` 字节。 |
路径在 `rootDir` 内解析。如果请求的路径尝试逃离根目录,服务器会返回 MCP 错误结果。
## 默认忽略目录
目录遍历默认跳过以下文件夹:
```text
.git
.next
.turbo
build
coverage
dist
node_modules
```
使用 `excludeDirs` 添加更多忽略的目录名称。
## 支持的扩展名
一般的代码读取和搜索支持:
```text
.cjs, .css, .cts, .go, .html, .js, .jsx, .json, .mjs,
.mts, .py, .svelte, .ts, .tsx, .vue
```
导入图分析专注于可导入的源文件:
```text
.ts, .tsx, .mts, .cts, .js, .jsx, .mjs, .cjs, .go, .json, .py
```
TypeScript 家族文件使用 TypeScript 编译器 API 进行解析。Go 和 Python 有轻量级的导入和函数声明解析支持。
## 已注册工具
### `list_files`
列出目录下的文件。
输入:
```json
{
"directoryPath": ".",
"recursive": true,
"includeExtensions": [".ts"]
}
```
返回文件路径、绝对路径、大小和扩展名。
### `list_directories`
列出目录下的目录。
输入:
```json
{
"directoryPath": "src",
"recursive": true
}
```
返回项目相对路径和绝对目录路径。
### `get_project_tree`
返回目录的嵌套树。
输入:
```json
{
"directoryPath": ".",
"maxDepth": 3
}
```
返回具有 `name`、`path`、`type` 和可选 `children` 的节点。
### `find_file`
按 basename 或项目相对路径查找文件。
输入:
```json
{
"query": "utils",
"maxResults": 10
}
```
设置 `exact: true` 以要求精确的 basename 或路径匹配。
### `read_file`
读取文件为文本。
输入:
```json
{
"filePath": "src/index.ts",
"maxBytes": 12000
}
```
返回路径、绝对路径、大小、截断状态和内容。
### `read_file_range`
从文件中读取 1-based 行范围。
输入:
```json
{
"filePath": "src/index.ts",
"startLine": 1,
"endLine": 80
}
```
在完整的文件读取太大的情况下使用此功能。
### `read_multiple_files`
一次读取多个文件。
输入:
```json
{
"filePaths": ["src/index.ts", "src/tools.ts"],
"maxBytes": 20000
}
```
返回一个文件读取结果数组。
### `read_code`
读取支持的代码文件并添加语言元数据。
输入:
```json
{
"filePath": "src/tools.ts"
}
```
返回正常的文件内容以及 `language` 和 `lineCount`。
### `search_text`
在代码文件中搜索纯文本。
输入:
```json
{
"query": "registerJsonTool",
"caseSensitive": false,
"maxResults": 20
}
```
返回文件、行、列、行文本和匹配文本。
### `search_regex`
使用正则表达式搜索代码文件。
输入:
```json
{
"pattern": "export async function \\w+",
"flags": "i",
"maxResults": 20
}
```
实现在缺少全局标志时添加它。
### `find_imports`
查找一个文件或整个项目中的导入。
输入:
```json
{
"filePath": "src/index.ts"
}
```
如果省略 `filePath`,则工具会扫描支持的项目源文件。结果包括导入说明符、种类、导入名称、解析的项目路径(如果为本地)、行和列。
### `find_exports`
查找一个文件或整个项目中的导出。
输入:
```json
{
"filePath": "src/tools.ts"
}
```
检测常见的 TypeScript/JavaScript 导出形式和 Python 的 `__all__` 条目。
### `find_functions`
查找函数和方法。
输入:
```json
{
"filePath": "src/tools.ts",
"includeClasses": false
}
```
返回名称、文件、行、列、导出状态和声明种类。
### `find_classes`
查找类声明。
输入:
```json
{
"filePath": "src/index.ts"
}
```
返回函数声明结果的类子集。
### `find_unused_functions`
查找似乎未使用的函数。
输入:
```json
{
"includeExported": false
}
```
默认情况下,导出声明被忽略,因为它们可能在本地项目外部被使用。这是一个静态启发式方法,因此在删除代码之前请查看结果。
### `find_unused_files`
查找从入口点无法到达的源文件。
输入:
```json
{
"entrypoints": ["src/index.ts"]
}
```
如果省略 `entrypoints`,则工具会尝试使用常见的默认值,如 `src/index.ts`、`src/main.ts`、`main.py` 和 `__main__.py`,以及 `package.json` 的 `main` 和 `bin` 条目。
### `find_todos`
查找 TODO 样式的注释。
输入:
```json
{
"tags": ["TODO", "FIXME"],
"maxResults": 50
}
```
支持的标签是 `TODO`、`FIXME`、`HACK` 和 `NOTE`。
### `get_file_metadata`
获取文件或目录的文件系统元数据。
输入:
```json
{
"filePath": "src/index.ts"
}
```
返回大小、扩展名、创建时间、修改时间和文件/目录布尔值。
### `find_entry_points`
查找可能的项目入口点。
输入:
```json
{}
```
使用默认入口点名称和可用的 `package.json` 字段。
### `count_file_types`
按扩展名计算文件。
输入:
```json
{
"recursive": true
}
```
返回按计数排序的扩展名,然后按扩展名排序。
## 结果形状
每个工具返回一个类似的 MCP 结果:
```json
{
"content": [
{
"type": "text",
"text": "{ ...pretty printed JSON... }"
}
]
}
```
当工具失败时,服务器返回:
```json
{
"isError": true,
"content": [
{
"type": "text",
"text": "错误消息"
}
]
}
```
## 安全注意事项
- 工具路径相对于 `rootDir` 解析。
- 尝试逃离 `rootDir` 的路径被拒绝。
- 目录遍历默认跳过常见生成的依赖文件夹。
- 文件读取被 `maxBytes` 截断。
- 未使用的代码检测是启发式的,应将其视为审查辅助工具,而不是自动删除信号。
## 扩展服务器
要添加新工具:
1. 将实现添加到 `src/tools.ts`。
2. 从 `src/schema.ts` 添加或重用输入模式。
3. 在 `src/register-tools.ts` 中使用 `registerJsonTool` 注册它。
4. 将任何新结果类型添加到 `src/types.ts`。
5. 运行 `npm run type-check`。
示例注册:
```ts
this.registerJsonTool(
"tool_name",
"Short description.",
{
filePath: z.string(),
...projectOptions,
},
({ filePath, ...options }) => tools.someTool(filePath as string, options),
);
```
## 当前包脚本
包当前公开:
```json
{
"deploy": "wrangler deploy",
"dev": "wrangler dev",
"format": "oxfmt --write .",
"lint:fix": "oxlint --fix",
"start": "wrangler dev",
"cf-typegen": "wrangler types",
"type-check": "tsc --noEmit"
}
```
## 快速使用流程
1. 使用 `npm run dev` 启动 Worker。
2. 将 MCP 客户端连接到 `http://localhost:8787/mcp`。
3. 调用 `get_project_tree` 以了解仓库结构。
4. 使用 `find_file` 或 `search_text` 定位代码。
5. 使用 `read_file_range` 或 `read_code` 检查特定文件。
6. 使用 `find_imports`、`find_exports`、`find_functions` 和 `find_classes` 进行代码智能。
7. 使用 `find_unused_functions`、`find_unused_files` 和 `find_todos` 进行审查工作。