内容
<div align="center">
<img src="assets/image.webp" alt="SymbolPeek — 请求你需要的符号,而不是整个文件" width="100%">
### 面向 AI 编程代理的语义代码智能
请求你需要的符号,而不是整个文件。
<p>
<code>.ts</code>
<code>.tsx</code>
<code>.js</code>
<code>.jsx</code>
</p>
<p>
<a href="#快速开始">快速开始</a> ·
<a href="#连接到Codex">连接到Codex</a> ·
<a href="#连接到Claude Code">连接到Claude Code</a> ·
<a href="MCP_TOOLS.md">工具参考</a>
</p>
</div>
SymbolPeek帮助AI编程代理在不阅读不必要代码的情况下理解大型TypeScript和JavaScript代码库。它不返回整个文件,而是仅返回请求的符号及其语义关系,使用官方TypeScript编译器API和语言服务。这样可以减少令牌使用量,尽量减少无关上下文,并为代理提供精确的信息用于导航、分析和重构。
对于代理来说,这意味着在上下文窗口中拉取的整个文件更少,并且在手动查找和验证符号上花费的往返次数更少。
## 为什么选择SymbolPeek?
传统的 文件检索 强制LLM读取它不需要的代码。符号感知的请求可以返回确切的相关声明及其附近的上下文:
```text
read_symbol_context(path, "sendMessage")
→ sendMessage
→ validateInput
→ Message
→ MAX_LENGTH
```
SymbolPeek围绕四个原则设计:
- **语义检索** — 符号从AST中发现,而不是文本匹配。
- **最小上下文** — 仅返回请求的符号和显式请求的关联关系。
- **新鲜结果** — 每个请求都读取当前文件快照,并从空的全局AST缓存开始。
- **可扩展架构** — MCP层独立于语言解析器,可以在不依赖语言特定MCP代码的情况下支持未来的提供者。
## 它在哪里有帮助(以及在哪里没有帮助)
SymbolPeek不会取代读取文件或文本搜索。它取代了代理在真实代码库中遇到的最昂贵的模式:*查找符号,找到所有使用它的地方,并了解其类型 — 跨导入别名和重新导出。*
**它真正节省代理工作和令牌的地方**
- **一个符号来自一个大文件。** `read_symbol` / `read_symbol_context` 返回一个声明,而不是整个文件。对于大文件,这大部分是令牌节省。
- **无需grep循环的影响分析。** `find_references` 返回已解析的位置,而 `find_callers` 还在一次调用中标识封闭函数。两者都使用项目的模块解析,包括路径别名(`@app/...`)和桶重新导出,而文本搜索则不可靠地遵循这些。
- **已解析类型。** `get_type` 返回实例化的签名(例如 `useAsync<FeedPermission, Error>`),而文本搜索无法产生这些。
- **作用域发现。** `search_symbols` 按名称和种类查找声明(例如“与 `conversation` 匹配的钩子”),而不会产生注释和无关代码中的字符串匹配噪音。
**代理仍应使用普通工具的地方**
- 普通文本、注释、配置或非TS/JS文件 — `grep`更快。
- 了解一个函数内部的完整控制流 — 直接阅读。
- 非常大的monorepos — 每个调用都会产生一个短-lived worker并重建一个TypeScript程序(没有缓存),因此延迟是真实的;对于单个查找,目标`grep`可能更快。
**是什么让结果值得信赖**
- 解析、源范围、类型信息和跨文件导航来自TypeScript编译器和AST。诸如`hook`和`react_component`之类的语义标签还使用显式命名和JSX约定。
- 跨文件结果仅在模块解析允许的范围内完整:使用有效的`tsconfig.json`,它们使用其配置的源集;没有它,它们涵盖目标文件和递归解析的静态导入、导出和`require(...)`调用。
- 编译器选项来自项目`tsconfig.json`。工作线程本身使用`SYMBOLPEEK_TYPESCRIPT_ROOT`选择的TypeScript运行时;发布包装器将其指向SymbolPeek的锁定运行时。
## 功能一览
### 导航
| 工具 | 它回答的问题 |
| --- | --- |
| `read_symbol` | “给我这个符号的精确源代码。” |
| `list_symbols` | “这个文件中的顶级符号是什么?” |
| `search_symbols` | “这个符号在工作区中定义在哪里?” |
| `go_to_definition` | “这个用法背后的定义是什么?” |
| `read_symbol_context` | “给我这个符号加上它的最小本地上下文。” |
### 代码智能
| 工具 | 它回答的问题 |
| --- | --- |
| `find_references` | “这个符号在项目中被哪些地方引用?” |
| `find_callers` | “哪些函数或方法调用这个符号?” |
| `find_callees` | “这个符号调用哪些项目符号?” |
| `find_dependencies` | “这个符号依赖哪些本地符号?” |
| `get_call_hierarchy` | “围绕这个符号的调用者和被调用者是什么?” |
### 类型分析
| 工具 | 它回答的问题 |
| --- | --- |
| `get_type` | “这个位置的推断类型或签名是什么?” |
| `find_implementations` | “哪些类实现了这个接口或契约?” |
| `get_document_outline` | “这个文件的嵌套声明结构是什么?” |
| `get_diagnostics` | “影响这个文件或符号的TypeScript编译器诊断信息是什么?” |
扁平边界工具(`list_symbols`、引用、调用者、被调用者、实现和诊断)支持`offset`分页。截断的页面包含`next_offset`;将其传递给下一个请求。跨文件页面使用页面本地的`files[]`表格,因此在合并页面之前连接`fileIdx`。工作区`search_symbols`、嵌套大纲和调用图故意保持边界,不支持偏移分页。
### 统计信息
| 工具 | 它回答的问题 |
| --- | --- |
| `get_statistics` | “SymbolPeek避免了多少源上下文?” |
## 支持的源
第一个版本仅支持:
- `.ts`
- `.tsx`
- `.js`
- `.jsx`
TypeScript提供者检测以下符号:
- 函数声明、异步函数、生成器和箭头函数;
- 导出和嵌套函数;
- React组件和钩子;
- 类和类方法;
- 对象方法;
- 接口、类型别名、枚举、变量和常量。
解析由官方TypeScript编译器API执行。SymbolPeek不使用正则表达式、括号计数、tree-sitter、SWC或手写解析器。React组件和钩子分类遵循命名和JSX约定;在编译器派生的语法树上应用标签。
目前故意不支持其他语言。Rust、C++、Swift、Go和Python可以作为独立的语言提供者稍后添加。
## 快速开始
需求:
- Rust 1.82 或更新版本;
- Node.js;
- npm。
从存储库的checkout:
```sh
sh scripts/build-release.sh
cargo test
node scripts/smoke-test.mjs target/release/symbolpeek
```
`scripts/build-release.sh`安装锁定的npm依赖并构建两个发布的可执行文件:
```text
target/release/symbolpeek 规范命令
target/release/sym 便捷的简短别名
```
SymbolPeek作为MCP服务器运行时,通过stdio进行通信。它通常不打印终端界面;MCP客户端启动它并通过stdin/stdout交换JSON-RPC消息。
## 全局安装命令别名
在macOS或Linux上,将发布二进制文件安装到`PATH`上的目录:
```sh
mkdir -p ~/.local/bin
ln -sf "$(pwd)/target/release/symbolpeek" ~/.local/bin/symbolpeek
ln -sf "$(pwd)/target/release/sym" ~/.local/bin/sym
export PATH="$HOME/.local/bin:$PATH"
```
将`export PATH=...`行添加到shell配置文件中,以便在未来的终端中生效。
相同的两个Rust二进制文件由以下命令安装:
```sh
cargo install --path .
```
`stats`命令是自成体系的。语义MCP操作还需要npm TypeScript运行时:使用`scripts/run-release.sh`,或将`SYMBOLPEEK_TYPESCRIPT_ROOT`设置为SymbolPeek的checkout,其中已运行`npm ci`。`cargo install`不安装JavaScript依赖。
在文档和自动化中使用`symbolpeek`。在需要简短命令时使用`sym`:
```sh
symbolpeek stats
sym stats
symbolpeek --help
sym --help
```
## CLI统计信息
CLI显示生命周期上下文避免统计信息:
```sh
symbolpeek stats
symbolpeek stats --reset
```
`--reset`仅重置生命周期总数。会话计数器属于正在运行的MCP进程,并可通过`get_statistics()`获得。
所有数字都与反事实的全源基线进行比较:
- **请求** — 成功语义调用;
- **避免的文件** — 每个结果表示的独立源文件,在调用中求和(一个`find_callers`请求可以计算多个文件);
- **避免的字节/行** — 完整文件内容减去语义结果的紧凑序列化;不包括响应大小估计中的单个`文件`路径字段,而interned `files[]`表格仍被包括在内;
- **估计令牌节省** — 在固定的~4字节/令牌启发式下,避免字节数,而不是特定模型的令牌化;
- **平均上下文减少** — 按请求加权的大小。
`get_statistics`返回会话和生命周期范围以及描述此基础的`note`。将它们视为定向上下文减少估计,而不是确切的模型令牌计数或计费数据。它们不模拟MCP信封序列化、主机缓存、特定令牌化器或代理是否会使用目标文本搜索而不是读取每个代表的文件。
生命周期数据存储为人类可读的JSON,位于平台配置目录中:
| 平台 | 默认位置 |
| --- | --- |
| Linux | `~/.config/symbolpeek/stats.json` 或 `$XDG_CONFIG_HOME/symbolpeek/stats.json` |
| macOS | `~/Library/Application Support/SymbolPeek/stats.json` |
| Windows | `%APPDATA%/SymbolPeek/stats.json` |
持久性失败会禁用运行时磁盘更新;内存计数器和语义工具继续正常运行。
## 使用工具
从外部MCP客户端使用绝对文件路径最安全。相对路径相对于MCP进程的工作目录或显式设置的`SYMBOLPEEK_WORKSPACE_ROOT`解析。支持的文件是为每个请求从其当前内容解析的。
每个工具的请求形状、选项和响应格式都在 **MCP工具参考** 中记录。
不支持的扩展名返回 `{ "supported": false }`。缺少文件、解析器失败和未知符号作为MCP无效参数错误返回。
## 连接到Codex
首先构建SymbolPeek,然后注册发布包装器:
```sh
PROJECT_ROOT="$(pwd)"
codex mcp add symbolpeek -- \
sh "$PROJECT_ROOT/scripts/run-release.sh"
codex mcp list
```
重启Codex并尝试:
```text
使用symbolpeek MCP服务器。列出绝对路径/project/src/dashboard.tsx中的符号,然后为Dashboard读取symbol_context。然后,为useAuth查找引用并为其中一个用法查找定义。
```
已签入的Codex配置模板可在 [`config/codex-mcp.toml.example`](config/codex-mcp.toml.example) 中找到。
## 连接到Claude Code
在用户范围内注册相同的stdio服务器:
```sh
PROJECT_ROOT="$(pwd)"
claude mcp add \
--transport stdio \
--scope user \
symbolpeek -- sh "$PROJECT_ROOT/scripts/run-release.sh"
claude mcp list
claude mcp get symbolpeek
```
在Claude Code内部,运行 `/mcp` 以检查连接。使用 `--scope project` 时,应仅为当前项目配置服务器。
已签入的Claude配置模板可在 [`config/claude-mcp.json.example`](config/claude-mcp.json.example) 中找到。
## 配置
发布包装器自动设置TypeScript运行时根。这些环境变量可用于高级设置:
| 变量 | 目的 |
| --- | --- |
| `SYMBOLPEEK_WORKSPACE_ROOT` | 可选的工作区根,用于解析相对源路径。 |
| `SYMBOLPEEK_TYPESCRIPT_ROOT` | 包含安装的TypeScript运行时的目录。 |
| `SYMBOLPEEK_NODE` | 显式Node.js可执行文件,用于启动解析器工作线程。 |
| `SYMBOLPEEK_STATS_PATH` | 重写生命周期统计信息的JSON路径。 |
对于全局MCP安装,不要将 `SYMBOLPEEK_WORKSPACE_ROOT` 设置为固定项目。使用绝对路径,或让MCP客户端启动SymbolPeek,并将活动项目作为其工作目录。仅为故意按项目范围启动时设置 `SYMBOLPEEK_WORKSPACE_ROOT`。单独将 `SYMBOLPEEK_TYPESCRIPT_ROOT` 设置为包含SymbolPeek `node_modules` 运行时的目录。
例如,当SymbolPeek安装在一个checkout中并分析另一个项目时:
```sh
export SYMBOLPEEK_WORKSPACE_ROOT=/absolute/path/to/your/project
export SYMBOLPEEK_TYPESCRIPT_ROOT=/absolute/path/to/symbolpeek
```
## 架构与开发
SymbolPeek围绕语言中立的MCP层和可交换的TypeScript提供者构建,没有数据库或持久AST缓存;每个请求都读取当前源。完整的设计、请求生命周期、源布局和贡献者验证套件位于 **[ARCHITECTURE.md](ARCHITECTURE.md)** 中。
## 路线图
当前基础是有意关注的。自然而然的下一个功能包括:
- 符号级编辑和替换;
- 深入的类型扩展,超出`get_type`悬停签名(完全解析的嵌套和泛型类型);
- JSX组件树和道具流分析;
- 项目索引和增量解析;
- 额外的语言提供者。
这些功能可以在提供者边界后面添加,而不会将MCP逻辑耦合到特定的语言语法。