用途 readonly-mcp-wrapper 面向这样的需求:把一个项目或笔记文件夹中的知识(文档、笔记、规格、导出的数据)以只读方式开放给 AI 助手。它生成一个小型 MCP 服务器,只负责列出、搜索和读取文件,不提供任何其他能力,从而避免手工编写服务器时常见的风险,例如多出一个“顺手”的写入工具、通过 .. 或符号链接逃逸出服务目录,或把日志打到 stdout 破坏协议。
所需输入 使用前需要明确:要服务的文件夹及其大致文件数量和大小;文件类型(Markdown、JSON 或两者,其他类型默认排除);目标客户端(Claude Code、Claude Desktop、Cursor 或其他 MCP 客户端);运行时(默认 Node,如需 Python 需另行说明);以及文件夹内绝不能开放的内容(草稿、私密笔记等),按路径排除。
主要输出
- 服务器代码:基于模板生成的完整文件,使用 stdio 传输,在 stdin/stdout 上以换行分隔的 JSON-RPC 2.0 通信,所有日志走 stderr;处理 initialize、ping、tools/list 和 tools/call,忽略通知,其他方法返回 -32601;服务根目录只解析一次 realpath,每个请求路径都解析并校验是否仍位于根目录内,使 .. 与符号链接无法逃逸;带有扩展名白名单和单文件大小上限;遍历文件时应用输入中的排除项。
- 工具定义:以表格和 JSON Schema 给出三个工具——list_documents(无输入,返回相对路径)、search_documents(query 至少 2 个字符,可选 limit 最大 50,返回每处匹配的路径与摘录)、read_document(输入取自 list_documents 的 path,返回全文),三者均标记只读提示;错误作为工具结果返回,isError: true,且消息不包含绝对路径。
- 客户端配置:针对指定客户端给出确切片段和绝对路径占位符,例如 Claude Code 的 claude mcp add 命令,以及 Claude Desktop 或 Cursor 的 mcpServers JSON 块。
- 安全说明:一段可直接粘贴到 README 的声明,确认服务器只暴露三个只读工具、没有写入/删除/重命名/移动文件的代码、没有网络代码(无 HTTP 客户端、套接字、子进程)、路径(含符号链接)无法逃出服务文件夹、只返回白名单类型且不超过大小上限的文件;随后给出验证命令,例如在服务器代码中搜索写入、删除、网络和进程相关 API 应无结果,以及运行测试。
- 测试脚本:通过管道发送 JSON-RPC 请求,验证 initialize 成功、列出三个工具、文档可列出/搜索/读取、../ 穿越被拒绝、指向外部的符号链接被拒绝、不允许的扩展名被拒绝、未知工具返回错误。
质量检查与反模式 质量检查包括:恰好三个工具且均带 readOnlyHint: true;服务器不含写入、删除、重命名、网络或子进程调用;stdout 只写协议消息;.. 与外部符号链接均被拒绝;仅提供白名单扩展名且不超大小上限;错误消息不泄露绝对路径;客户端片段使用绝对路径和对应客户端的准确命令;测试覆盖所有拒绝情形。反模式包括:加一个写入工具(应另建服务器)、用 console.log 调试(应写 stderr)、仅用字符串前缀检查路径(需 realpath)、把文件夹内所有文件都开放(应做类型白名单,因为密钥和 .env 可能与文档混放)。
适用场景与限制 适合将 Obsidian 笔记、文档文件夹或 JSON 文件集合以只读 MCP 工具开放给 Claude Code、Claude Desktop、Cursor 等客户端,让代理能搜索和阅读但无法修改。限制方面:资料未提供具体安装命令以外的部署细节、性能数据、支持的客户端完整列表及收费信息,暂未提供。