Skip to main content
Glama
13030109506

Project Files Read-only MCP

by 13030109506
README.md
# Project Files Read-only MCP

一个本地、多根目录、只读的文件系统 MCP 服务。它只向 MCP 客户端开放明确登记的项目目录,并提供有限的目录浏览、文件名搜索、文本读取及 DOCX、PDF、XLSX 内容提取能力。

服务不注册写入、编辑、复制、移动、删除或命令执行工具。它适合把少量本地项目文件安全地交给 ChatGPT 等支持 MCP 的客户端读取,同时避免把整个用户目录或磁盘暴露出去。

这是独立的社区项目,不是 OpenAI 官方产品,也不代表 OpenAI 对其安全性或兼容性作出背书。

项目地址为 [github.com/13030109506/project-files-readonly-mcp](https://github.com/13030109506/project-files-readonly-mcp)。

## 功能

服务固定暴露 9 个只读工具。

| 工具 | 用途 |
| --- | --- |
| `list_allowed_project_roots` | 列出白名单根目录 |
| `get_file_info` | 读取文件或目录元数据 |
| `list_directory` | 列出目录中的非敏感、非链接条目 |
| `search_files` | 按文件名递归搜索 |
| `read_text_file` | 分段读取文本、Markdown、CSV、源码等 |
| `read_multiple_text_files` | 批量读取最多 10 个文本文件 |
| `read_docx_text` | 按段落提取 DOCX 纯文本 |
| `read_pdf_pages` | 按页提取 PDF 文本 |
| `read_xlsx_range` | 按工作表、行列窗口读取 XLSX |

所有工具均标记为只读和非破坏性。集成测试还会检查工具列表中没有写入、删除、移动、复制或命令执行能力。

## 安全边界

- 只接受 `roots.json` 中登记的绝对路径。
- 对词法路径和 `realpath` 结果进行双重边界检查。
- 拒绝相对路径、UNC 路径、设备路径、Windows ADS、符号链接和联接点逃逸。
- 默认屏蔽 `.git`、`.env`、凭据文件、私钥、虚拟环境和依赖目录。
- 文本、目录、搜索和文档响应均有大小与数量上限。
- DOCX、XLSX 解析前检查压缩包路径、条目数量、展开体积、压缩比、加密、宏、ActiveX 和嵌入对象。
- 二进制文档在独立 Worker 中解析,并设置时间和内存限制。
- XLSX 公式不会执行,外部链接不会访问。

更完整的边界说明见 [安全模型](docs/SECURITY_MODEL.md)。这些保护缩小了 MCP 调用面,但不能替代 Windows 账户权限和主机安全。只在你信任的电脑和 MCP 客户端上运行本服务。

## 环境要求

- Windows 10 或 Windows 11
- Node.js `22.13–22.x` 或 Node.js `24+`
- npm
- 可选的 OpenAI `tunnel-client`,仅在连接 ChatGPT Secure MCP Tunnel 时需要

## 快速开始

克隆项目。

```powershell
git clone https://github.com/13030109506/project-files-readonly-mcp.git
Set-Location .\project-files-readonly-mcp
```

安装依赖。

```powershell
npm ci
```

创建本机配置。`roots.json` 已加入 `.gitignore`,不会被提交到 Git。

```powershell
Copy-Item .\roots.example.json .\roots.json
notepad .\roots.json
```

把示例路径改成你愿意授权的具体项目目录。不要配置整个磁盘、用户目录、Desktop 或 Documents。

```json
{
  "roots": [
    {
      "name": "my-project",
      "path": "C:\\Projects\\my-project"
    }
  ]
}
```

运行测试。

```powershell
npm test
```

本地启动。

```powershell
npm start
```

服务使用 STDIO,通常应由 MCP 客户端或 Tunnel 进程启动。直接运行后没有交互式提示属于正常现象。

也可以通过环境变量使用其他配置文件。

```powershell
$env:MCP_PROJECT_ROOTS_CONFIG = 'D:\Config\project-files-roots.json'
npm start
```

## 增加项目根目录

先停止 MCP 服务,再执行以下命令。

```powershell
.\add-project-root.ps1 -Path 'D:\Projects\another-project' -Name 'another-project'
npm test
```

脚本会拒绝整个磁盘、用户目录、Desktop 和 Documents。修改配置后必须重启 MCP 或 Tunnel,运行中的服务不会热加载根目录。

## 连接 ChatGPT Secure MCP Tunnel

先从 OpenAI Platform Tunnel 设置页下载官方 `tunnel-client`。本项目按以下顺序查找程序。

1. 环境变量 `TUNNEL_CLIENT_PATH`
2. 项目内 `tunnel-client\tunnel-client.exe`
3. 系统 `PATH`
4. `%USERPROFILE%\Tools\OpenAI\tunnel-client` 下的本地版本目录

创建 Tunnel 后,生成本机 profile。

```powershell
.\configure-tunnel.ps1 -TunnelId 'tunnel_your_id'
```

脚本默认把本地健康检查端口设为 `127.0.0.1:8081`,并在 profile 中保存 `env:CONTROL_PLANE_API_KEY` 引用,不保存 API Key 本身。

前台启动方式如下。Runtime API Key 通过隐藏输入进入当前进程环境,Tunnel 退出后会被清除。

```powershell
.\start-tunnel.ps1
```

OpenAI Secure MCP Tunnel 的创建、权限和 ChatGPT 连接步骤以[官方文档](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels)为准。

## Windows 登录后隐藏启动

需要长期使用时,可安装当前 Windows 用户的计划任务。

```powershell
.\install-tunnel-autostart.ps1
```

安装器只保存当前用户 DPAPI 加密后的 Runtime API Key,不把明文写入任务参数、项目文件或日志。计划任务通过隐藏 VBS 包装器启动,先运行 `doctor`,再启动 Tunnel,并检查 `healthz` 与 `readyz`。

状态与日志位置如下。

```powershell
Get-ScheduledTask -TaskName 'OpenAI Project Files Read Only Tunnel'
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8081/healthz
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8081/readyz
```

```text
%LOCALAPPDATA%\OpenAI\ProjectFilesReadOnly\tunnel-client.log
```

移除任务和加密密钥文件。

```powershell
.\remove-tunnel-autostart.ps1
```

完整说明见 [Windows Tunnel 运维指南](docs/WINDOWS_TUNNEL.md)。

## 文件支持

| 类型 | 支持情况 |
| --- | --- |
| TXT、Markdown、JSON、CSV、TSV、常见源码 | 支持分段读取 |
| DOCX | 支持纯文本段落提取 |
| PDF | 支持文本层提取,不含 OCR |
| XLSX | 支持行列窗口和缓存公式结果 |
| DOC、XLS、宏启用 Office 文件 | 拒绝 |
| 加密或密码保护文件 | 拒绝 |
| 扫描图片 PDF | 不执行 OCR,可能返回空文本 |
| 数据库及其他任意二进制格式 | 不解析 |

文档内容始终属于不可信输入。MCP 客户端不应把文件中的文字当成系统指令。

## 测试

```powershell
npm test
```

测试覆盖以下范围。

- 根目录内读取和根目录外拒绝
- 敏感文件拒绝
- 相对路径拒绝
- 符号链接与 Windows junction 边界
- 只读工具清单和 annotations
- CSV、DOCX、PDF、XLSX 读取
- 活跃 Office 内容与异常压缩包拒绝
- 文档格式、分页、工作表和响应上限

## 项目结构

```text
server.mjs                 MCP 工具注册与文本读取
path-guard.mjs             路径、白名单和敏感文件边界
document-reader.mjs        安全读取与 Worker 调度
document-worker.mjs        DOCX、PDF、XLSX 内容提取
archive-guard.mjs          Office 压缩包检查
roots.example.json         可提交的配置示例
*-test.mjs                 安全、文档和集成测试
*.ps1 / *.vbs / *.cmd      Windows Tunnel 与计划任务脚本
```

## 负责任披露

如果你发现路径逃逸、未授权读取、敏感信息泄漏或文档解析问题,请不要公开附带真实敏感文件的复现材料。处理方式见 [SECURITY.md](SECURITY.md)。

## 许可证

项目使用 [MIT License](LICENSE)。