fan-67/local-mcp

GitHub: fan-67/local-mcp

一个零依赖的轻量级 stdio/HTTP MCP 服务器,为 AI 助手提供高效的本地文件系统操作和渐进式工具发现机制。

Stars: 0 | Forks: 0

# local-mcp ![Version](https://img.shields.io/badge/version-1.1.1-blue) ![License](https://img.shields.io/badge/license-MIT-green) ![Node](https://img.shields.io/badge/node-%3E%3D22.0.0-brightgreen) ![Tests](https://img.shields.io/badge/tests-81%2F81-passing) ![Dependencies](https://img.shields.io/badge/dependencies-0-success) **零依赖的本地文件操作 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, 命令执行, 文件系统操作, 本地开发工具, 自定义脚本