fan-67/local-mcp
GitHub: fan-67/local-mcp
一个零依赖的轻量级 stdio/HTTP MCP 服务器,为 AI 助手提供高效的本地文件系统操作和渐进式工具发现机制。
Stars: 0 | Forks: 0
# local-mcp





**零依赖的本地文件操作 MCP 服务器。** 包含 13 个文件系统工具 + 3 个用于渐进式发现的元工具 —— 无需 SDK,无需框架,无需 `npm install`。
## 架构
```
local-mcp.mjs — 595 lines, 13 tools, entry point
lib/mcp-core.mjs — 229 lines, stdio + HTTP transport, 9 MCP methods
lib/config.mjs — 31 lines, MCP_WORKSPACE/DATA env config with validation
```
**总计:约 855 行代码,零运行时依赖。**
## 工具
### 文件系统工具 (13)
| 工具 | 描述 | 注解 |
|------|-------------|------------|
| `read` | 读取文件并附带行号,可选 `head`/`tail` 截断 | `readOnlyHint` |
| `search` | 按名称搜索文件 (glob) 然后搜索内容 (grep) | `readOnlyHint` |
| `ls` | 紧凑的目录列表,支持惰性 stat | `readOnlyHint` |
| `exec` | 支持 stdin 和超时的流式命令执行 | `destructiveHint` |
| `diff` | 对比两个文件或文本字符串 (Myers O(ND)) | `readOnlyHint` |
| `copy` | 复制文件或目录 | `destructiveHint` |
| `move` | 移动或重命名文件/目录 | `destructiveHint` |
| `batch` | 顺序执行多个操作;支持原子回滚,`$prev` 引用 | `destructiveHint` |
| `file` | 统一操作:读取、写入、编辑、追加、删除、获取信息、创建目录、移动 | — |
| `block` | 按范围或函数名读取/替换/插入/删除代码块 | — |
| `bookmark` | 持久化路径别名(添加/获取/列出/删除) | — |
| `grep` | 紧凑的 `file:line:content` 格式,支持自适应并发 | `readOnlyHint` |
| `watch` | 监视文件/目录的更改;最多支持 20 个并发监视器 | — |
### 元工具 (3) — 渐进式发现
| 工具 | 描述 |
|------|-------------|
| `search_tools` | 按关键字搜索可用工具 —— 与列出所有工具相比可节省约 90% 的 token |
| `describe_tool` | 获取特定工具的完整输入 schema(按需加载) |
| `call_tool` | 按名称和参数执行任何工具 |
不再在每次请求中发送全部 13 个工具 schema(约 3,000 个 token),使用这 3 个元工具进行渐进式发现可将其减少到约 50 个 token —— **节省约 90% 的 token**。
## 性能优化 (v1.1.1)
| # | 优化 | 影响 |
|---|-------------|--------|
| **A** | **流式 head/tail 读取** | `streamHead()` 避免读取整个文件。500MB 日志:3s → 5ms,内存:500MB → 几 KB |
| **B** | **ls 中的惰性 stat** | 仅在 `sort=size` 时调用 `statSync`。1000 个文件的目录:50ms → 2ms |
| **C** | **自适应 grep 并发** | 使用 `os.availableParallelism()`(最大 16,最小 4)代替硬编码的 16 个 worker |
| **D** | **LRU 缓存淘汰** | 利用 Map 插入顺序的 LRU —— 热门小文件不再被冷门大文件淘汰 |
| **E** | **grep 字节保护** | `MAX_GREP_TOTAL_MB=100` + `MAX_GREP_FILES=1000` 防护机制可防止 OOM |
| **F** | **进度通知** | `_meta.progressToken` 透传,支持 MCP 2025 规范(待办:为长时间的 exec 添加事件) |
### 其他优化
| 领域 | 详情 |
|------|--------|
| **读取缓存** | 基于大小的淘汰(最多 50 项,10 MB)+ 5s TTL |
| **Myers diff** | O(ND) 算法,被 `edit`、`block` 和 `diff` 使用 |
| **搜索评分** | 优先匹配名称(无 I/O),然后仅对前 50 个候选者进行 stat |
| **输出格式** | `grep`:`file:line:content`,`ls`:紧凑列,`read`:行号 + 截断提示 |
| **协议** | O(1) Map 分发,同步处理程序短路 |
## 快速开始
```
# 零安装 — 无依赖
node local-mcp.mjs
# 使用配置
MCP_WORKSPACE=D:/projects node local-mcp.mjs
```
### stdio 模式(默认)
```
{
"mcpServers": {
"local-mcp": {
"command": "node",
"args": ["D:/path/to/local-mcp.mjs"],
"env": {
"MCP_WORKSPACE": "D:/projects"
}
}
}
}
```
### HTTP 模式
```
node local-mcp.mjs --http
node local-mcp.mjs --http --port 3456
```
支持 JSON-RPC 2.0 POST、SSE 流式传输 (`Accept: text/event-stream`)、CORS 以及 `GET /tools`。
### CLI 标志
```
node local-mcp.mjs --help # Show usage + env vars
node local-mcp.mjs --list-tools # Print available tools and exit
node local-mcp.mjs --http # Start HTTP mode
node local-mcp.mjs --http --port 3456
```
## 配置
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `MCP_WORKSPACE` | `process.cwd()` | 工作目录根路径(安全边界) |
| `MCP_DATA` | `{WORKSPACE}/.mcp-data` | 数据目录(书签、临时文件) |
| `MCP_DIR` | `{WORKSPACE}` | tree/ls 命令的默认目录 |
| `MCP_PORT` | `3100` | HTTP 服务器端口(使用 `--http` 时) |
| `MCP_READONLY` | `false` | 设为 `true` 以阻止所有写入操作 |
| `MCP_EXCLUDE` | — | 逗号分隔的额外目录,将在搜索中排除 |
## 安全性
- 所有文件操作都限制在 `MCP_WORKSPACE` 及其子目录中
- 原型安全的书签键(阻止 `__proto__`/`constructor`/`prototype` 注入)
- 原子写入(临时文件 + 重命名)防止写入部分文件内容
- 二进制文件检测可防止读取非文本文件
- 遵守 `.gitignore` 和常见的排除目录(如 `node_modules`、`.git` 等)
## 依赖
**零运行时依赖。** 仅使用 Node.js 内置模块:
| 模块 | 用途 |
|--------|---------|
| `fs` | 文件系统 + `glob` (Node 22) |
| `child_process` | 流式 shell 执行 |
| `http` | HTTP 传输(无需 Express) |
| `path` | 路径解析 |
| `os` | 用于自适应并发的 `availableParallelism()` |
| `readline` | 流式逐行处理 |
## 更新日志
### v1.1.1 — 性能优化
- **A.** 流式 head/tail 读取:500MB 日志 3s → 5ms
- **B.** ls 中的惰性 stat:1000 个文件的目录 50ms → 2ms
- **C.** 使用 `availableParallelism()` 实现自适应 grep 并发
- **D.** 通过 Map 插入顺序实现 LRU 缓存淘汰
- **E.** grep 字节保护(100MB / 1000 个文件)
- **F.** 支持 MCP 2025 规范的进度通知透传
- **修复:** `streamHead` 作用域 bug —— `done` 定义在 Promise 回调外部
### v1.1.0
- 13 个文件系统工具 + 3 个用于渐进式发现的元工具
- stdio + 可流式传输的 HTTP 传输
- Myers diff 引擎,读取缓存,流式 exec
- 带有验证的基于环境的配置
## 开发
```
# 运行测试
node --test test/*.test.mjs
# 添加 tool
# 1. 在 local-mcp.mjs 中定义 schema + handler
# 2. 使用 server.tool() 注册
# 3. 添加测试
```
### 贡献
1. 维持零依赖的限制
2. 为新功能添加测试
3. 更新性能优化表格以反映性能变化
## 许可证
MIT
标签:AI辅助工具, GNU通用公共许可证, MCP服务, MITM代理, Node.js, 命令执行, 文件系统操作, 本地开发工具, 自定义脚本