内容
# Litos MCP
本地运行的 MCP 服务器,帮助编码代理通过更少的 token 找到代码。代理通过搜索**结构骨架索引**(符号、类型、作用域、行范围)并仅读取需要的部分,而不是遍历整个代码仓库或读取整个文件。
## 什么是 Litos MCP?
Litos MCP 在项目根目录下将您的代码仓库索引到一个小型 SQLite 数据库(`.lcn_cache.db`)。它提取定义 - 函数、类型、类、接口 - 而不是完整的源代码。代理通过 MCP 工具查询索引,获取紧凑的 JSON 搜索结果(默认为 ~10 个结果),然后拉取目标行范围。
它作为 **单个 Go 二进制文件** 在 Cursor、Claude Code 和其他 MCP 主机中通过 stdio 运行。所有操作都保留在您的机器上:无需云 API,无需嵌入式服务,无需遥测。
## 为什么使用 Litos MCP?
- **更少的 token** - 搜索返回路径和行号,而不是匹配的行或整个文件。读取量上限(每次调用 500 行 / 512KB)。
- **更快的发现** - FTS5 关键词搜索符号优于遍历大型 grep 转储来查找“X 在哪里实现?”
- **保持新鲜** - 在 `serve` 时,索引在启动时进行,监视代码仓库的保存(`fsnotify`),并在搜索前重新检查是否过时。正常编辑不需要手动重新索引。
- **私有和离线** - 仅本地缓存;尊重 `.gitignore` 和常见的跳过目录(`node_modules`、`.git`、构建输出)。
- **可选深度** - 安装 [Universal Ctags](https://github.com/universal-ctags/ctags) 以进行广泛的多语言符号提取,或使用内置的 Go、TS/JS 和 Python 的正则表达式索引。
## 工作原理
1. **`litos-mcp init`** (或第一次 `serve` 时自动初始化)爬取可索引的源文件,提取符号,并使用 FTS5 搜索索引写入 `.lcn_cache.db`。
2. **`litos-mcp serve`** 启动 MCP 服务器,补充自上次运行以来可能发生变化的部分,并在您工作时监视文件系统变化。
3. 代理调用 **`search_code_skeleton`**,并带有关键词(例如 `"jwt verification"`、`"payment handler"`)。
4. 对于有希望的搜索结果,代理调用 **`read_file_lines`**,并带有返回的 `file_path`、`start_line` 和 `end_line`。
搜索结果示例(无源代码 - 仅结构):
```json
[{
"file_path": "src/billing/billing.go",
"symbol": "ProcessPayment",
"kind": "function",
"start_line": 56,
"end_line": 69,
"scope": "BillingService",
"matched_in": "symbol"
}]
```
在大型树变化后(`git pull`、分支切换),调用 **`reindex_index`** 或再次运行 **`litos-mcp init`**。随时通过 **`litos://index/status`** MCP 资源检查同步状态。
## 不是什么
- **不是语义/嵌入式搜索** - 关键词和结构化 FTS 优于符号元数据,而不是“查找类似于此段代码的代码”。
- **不是 grep 替代品** - 当您需要在注释、字符串、配置文件或 litos 不索引的确切正则表达式模式中进行字面匹配时,请使用 grep。
- **不是托管服务** - 您安装二进制文件并将其连接到 Cursor、Claude Code 或另一个 MCP 主机。
## 安装
```bash
go install github.com/stubbies/litos-mcp/cmd/litos-mcp@latest
```
或从源代码构建:
```bash
git clone https://github.com/stubbies/litos-mcp.git
cd litos-mcp
go build -o bin/litos-mcp ./cmd/litos-mcp
```
可选:安装 Universal Ctags 以进行跨多种语言的更丰富的符号提取。如果没有安装,litos-mcp 将退回到 **Go、TypeScript/JavaScript 和 Python** (`.go`、`.ts`、`.tsx`、`.js`、`.jsx`、`.mjs`、`.cjs`、`.py`、`.pyw`)的内置正则表达式启发式。
### 语言支持
| 模式 | 索引扩展 |
|------|-------------------|
| **正则表达式回退** (无 ctags) | `.go`、`.ts`、`.tsx`、`.js`、`.jsx`、`.mjs`、`.cjs`、`.py`、`.pyw` |
| **Universal Ctags** | 所有可爬取的源扩展(Go、TS/JS、Python、Rust、Java/Kotlin、C/C++、C#、Ruby、PHP、Swift、Scala、Vue、Svelte、shell、SQL、Protobuf 等) |
爬取发现了许多文件类型,但正则表达式索引仅从第一行的扩展中提取符号。安装 ctags 后,将索引整个爬取集。
## 快速入门
1. **索引您的代码仓库** (在代码仓库根目录旁边创建 `.lcn_cache.db`):
```bash
cd /path/to/your/project
litos-mcp init
```
示例输出:
```
files=842 symbols=3912 indexer=regex elapsed_ms=1204 db_bytes=524288
```
2. **连接到您的 MCP 主机**
#### Cursor
复制 `.cursor/mcp.json` (或合并到现有的 MCP 配置中):
```json
{
"mcpServers": {
"litos-mcp": {
"command": "/path/to/litos-mcp",
"args": ["serve"],
"cwd": "${workspaceFolder}"
}
}
}
```
`cwd` 必须是工作区根目录,以便服务器解析与 `init` 相同代码仓库根目录。
#### Claude Code
在您要索引的**项目**(您的应用程序代码仓库,而不仅仅是 litos-mcp 本身)中创建 **`.mcp.json`**。Claude Code 忽略 MCP 配置中的 `cwd`;litos 自动使用 **`CLAUDE_PROJECT_DIR`**。
```json
{
"mcpServers": {
"litos-mcp": {
"type": "stdio",
"command": "litos-mcp",
"args": ["serve"]
}
}
}
```
在您的 `PATH` 上使用 `litos-mcp`,或替换绝对路径(例如 `$(go env GOPATH)/bin/litos-mcp` 或 `./bin/litos-mcp`)。
替代 CLI:
```bash
claude mcp add --scope project litos-mcp -- litos-mcp serve
```
配置更改后重启 Claude Code。通过 **`/mcp`** 或 `claude mcp list` 验证。首次项目范围的服务器可能需要在 UI 中获得批准。
3. **在代理会话中使用 MCP 工具**:
- `search_code_skeleton` - 按关键词查找符号(返回带有文件路径、行范围和 `matched_in` 的 JSON 搜索结果;可选 `match_mode`:`and` 或 `or`)
- `read_file_lines` - 在搜索确认目标后读取有界、按行编号的切片
- `reindex_index` - 大幅度更改后完全重新索引(例如 `git pull`);正常保存会自动同步
- **`litos://index/status`** (MCP 资源)- JSON 同步状态:文件/符号计数、索引器、`reconcile_needed`
- **`code_discovery_workflow`** (MCP 提示)- 代理的引导文本:先搜索,再窄范围读取
`litos-mcp serve` 自动运行 `init`,当缓存丢失时,然后在启动时**补充**索引(状态传递 + 启动爬取),并使用**文件系统监视器**保持索引新鲜,延迟单个文件的更新。搜索调用在 FTS 前运行轻量级过时检查。
## 命令
| 命令 | 描述 |
|---------|-------------|
| `litos-mcp init [--root PATH]` | 构建或刷新 `.lcn_cache.db` |
| `litos-mcp serve` | MCP stdio 服务器 + 启动补充 + fsnotify 同步 |
| `litos-mcp version` | 打印二进制文件、Go、索引器和 FTS5 状态 |
## 代理工作流
1. 调用 `search_code_skeleton(query="payment middleware")` 获取结构化搜索结果(默认为 ~10 个结果)。
2. 仅对搜索结果中的确认范围调用 `read_file_lines(file_path, start_line, end_line)`。
3. 当 litos-mcp 可用时,优先使用这些工具而不是 grep 或读取整个文件。
MCP 服务器公开了一个 **`code_discovery_workflow`** 提示,提供相同的指导。在 Cursor 中,从 MCP 提示选择器调用它,或在将代理引导到代码仓库时引用它。
### Claude Code(推荐)
在项目根目录下添加 **`CLAUDE.md`**,包含相同的工作流(搜索 → 读取切片 → grep 回退)。当服务器连接时,Claude Code 中的 MCP 提示 **`code_discovery_workflow`** 可用。
编辑后,等待 fsnotify 延迟(~300ms)或运行第二次搜索;在 `git pull` 后使用 **`reindex_index`**。
### Cursor 规则(推荐)
添加 `.cursor/rules/litos-code-discovery.mdc`,以便代理在工作区中默认使用 litos 工具:
```markdown
---
description: 优先使用 litos-mcp 结构化搜索而不是 grep 和整个文件读取
alwaysApply: true
---
# 使用 litos-mcp 进行代码发现
当 litos-mcp 连接时(search_code_skeleton, read_file_lines):
1. 使用任务中的功能关键词启动 search_code_skeleton。
2. 仅使用 read_file_lines 读取搜索返回的行范围。
3. 当 litos 工具可用时,不要使用 grep、ripgrep 或读取整个源文件进行发现。
4. 仅当 litos 返回没有搜索结果或您需要确切的正则表达式匹配时,才使用 grep 或整个文件读取。
使用先前搜索结果中的符号名称、类型、作用域和 matched_in 完善搜索查询。
```
## 缓存和隐私
- **`.lcn_cache.db`** 位于代码仓库根目录下,被 gitignore,可以随时删除;`init` 或 `serve` 会重新构建它。
- 索引跳过 `.gitignore`、`.git/info/exclude` 和内置跳过规则(例如 `node_modules`、`.git`、常见构建目录)覆盖的路径。
- 无源代码被发送到外部服务 - 只有您的本地代理在连接 MCP 服务器后读取文件。
## 开发
```bash
# 运行测试(包括固定装置的黄金指标、token/大小/延迟阈值)
go test ./...
# 搜索基准 + 回归保护(testdata/metrics.json 中的 2 倍基线)
go test -bench=BenchmarkFixtureSearch -benchtime=100ms ./internal/testutil/...
# 在此代码仓库中使用 Claude Code 的 litos-mcp
go build -o ./litos-mcp ./cmd/litos-mcp
# 然后将 .mcp.json 命令指向 ./litos-mcp 或 $(pwd)/litos-mcp
```
固定装置代码仓库:`testdata/fixture-repo/`,预期在 `testdata/metrics.json` 中。
## 许可证
MIT - 请参阅 [LICENSE](LICENSE)。