Skip to main content
Glama
README.md
# df mcp

[![Windows, macOS and Linux validation](https://github.com/raymondhuang1994/team-drive-mcp/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/raymondhuang1994/team-drive-mcp/actions/workflows/ci.yml)

给 AI 使用的本地团队文件读取工具,Skill 名称为 **`df-mcp`**,界面名称为 **df mcp**;GitHub 仓库仍使用 `team-drive-mcp`。架构:**Skill + MCP + SQLite 增量索引**。优先保证来源、版本和读取范围可核查,再优化定位速度。所有附带业务数据均为 **SIMULATED / 完全虚构**。

- [完整中文开发方案](docs/TEAM_AGENT_DEVELOPMENT_PLAN.md)
- [Skill 操作规范](skills/df-mcp/SKILL.md)
- [验证记录与限制](docs/VALIDATION.md)
- [Windows 只读边界与可选隔离部署](docs/WINDOWS_READ_ONLY.md)
- [Windows 临时修复迁移与并发验收](docs/WINDOWS_MIGRATION.md)
- [10 个固定评估任务](tests/evaluation.xml)

## 已实现的范围

- 本地 stdio MCP,10 个结构化工具;不调用模型 API、不访问网络。
- SQLite 文件清单与关键词索引,支持中文短词、项目代号及配置别名。
- TXT、Markdown、CSV、TSV、XLSX、DOCX、PPTX、文字 PDF。
- 启动扫描、运行期间定期增量核对、删除失效、失败记录和强制重试。
- 分页、结构导航、原文定位、读取前 SHA256 版本校验、受控 JSONL 导出。
- 安装时选择并确认读取目录;源文件只读,索引、日志、临时解析文件及导出与源目录分离。
- 多个 stdio 连接共享一个受管理的本地索引服务;状态目录禁止位于 `.codex` 或 `CODEX_HOME` 下。
- 授权根目录边界、符号链接/Windows junction 与 reparse 路径拒绝、压缩文件/XML 限制、超时、明确错误。

**运行平台:Windows、macOS / Linux,Node.js >=22,Python >=3.9。** Windows 本版面向固定本地磁盘上的普通目录,支持中文及空格路径;不支持 UNC/网络映射盘、可移动盘、设备路径、junction、符号链接及其他 reparse 路径。目标为 Windows 10/11;自动测试的实际环境与结果见验证记录,不能据此宣称所有公司电脑已经验收。

**当前未实现:** SharePoint 登录与下载、多用户身份权限、OCR、向量检索、原始文件下载工具、模型自我训练、无人值守云端部署。没有真实团队资料,也没有公司 PPT 模板。

## 安装:先选择允许读取的文件夹

把仓库与真实资料放在**互不包含的独立目录**,不要将运行安装放在会被定期清除的下载缓存或临时目录中。安装 Node.js 22+ 和 Python 3.9+,下载本仓库或执行下面的 clone 命令。Windows PowerShell、macOS 或 Linux 终端均可执行:

```sh
git clone https://github.com/raymondhuang1994/team-drive-mcp.git
cd team-drive-mcp
npm ci --ignore-scripts
npm run setup
npm run install:skill
```

`setup` 在仓库 `.venv` 安装 Python 依赖、编译 TypeScript,然后询问读取哪个文件夹。Windows 可通过文件夹选择窗口选取,也可按提示输入路径。向导展示读取目录与独立状态目录,确认后才保存配置;取消不保存新配置。它不在源目录创建测试文件,也不修改源目录权限。**索引在 MCP 客户端启动服务后才开始**,安装配置本身不读取整库正文。

无需模型 API key 或数据库服务器。Windows 安装脚本优先查找 `py -3`,再尝试可用的 `python`;系统商店跳转别名不作为可用解释器。支持与构建步骤遇到错误时应先解决该错误,不能把未成功的安装当作可用服务。

Skill 安装到个人 Codex 技能目录,名称为 `df-mcp`。同名目标或旧 `team-drive-read` 已存在时默认拒绝改动;明确更新或迁移旧 `team-drive-read` 可执行 `npm run install:skill -- --replace`,脚本先在目标磁盘逐文件复制并校验完整性,再备份原 Skill 到 Codex 配置目录中的 `skill-backups/` 并发布。复制失败不改动原安装;发布失败会尝试恢复原安装,无法自动恢复时保留备份并报告路径。支持中文/空格用户路径及仓库与用户目录位于不同磁盘的安装。Skill 只包含操作规范,MCP 连接按下一节配置。

### 配置位置与后续换目录

默认状态基目录:

| 平台 | 默认位置 |
|---|---|
| Windows | `%LOCALAPPDATA%\df-mcp` |
| macOS | `~/Library/Application Support/df-mcp` |
| Linux | `$XDG_STATE_HOME/df-mcp`,未设置时为 `~/.local/state/df-mcp` |

每个源目录使用独立的 `profiles/<root-hash>/config.json` 与 `profiles/<root-hash>/state/`。向导会输出完整配置路径。共享索引位于 `state/shared-v1/index/`,控制文件位于 `state/shared-v1/control/`;连接结束后保留已提交索引,下次连接复用。配置、正文缓存、数据库、日志和导出按源资料的敏感程度管理,不放在源目录、同步共享盘或公开 Git 仓库中。

状态路径不能包含 `.codex` 目录,也不能位于自定义 `CODEX_HOME` 内。安装器和服务都检查此边界及物理路径,不能用别名、符号链接或 junction 绕过。这样 Windows 状态目录的长期句柄不会固定 Codex 的配置目录。即使默认环境变量被重定向到 Codex 目录内,配置也会拒绝,应改用明确的外部 `--state-dir`。

换目录时运行 `npm run configure`,重新选择并确认,然后用向导给出的配置路径更新 MCP 连接。不会原地把旧索引绑定到新来源,也不会删除旧配置或资料。MCP 工具本身不能更改读取目录。

已明确路径时可非交互配置,例如 Windows PowerShell:

```powershell
npm run configure -- --root 'D:\团队资料' --yes
```

`--yes` 必须与明确的 `--root` 同用,表示确认该目录。可用 `--state-dir '<独立状态基目录>'` 自定义状态基目录;向导要求源目录、状态基目录与安装目录两两不重叠,任何一个都不能包含另一个。真实资料应放在程序目录外;仓库内的合成示例仅通过专用示例配置使用,不经过真实资料安装向导。无交互终端且未给出 `--root` 会失败,不会默认扫描主目录或示例库。

## 配置 MCP 客户端

**优先直接复制配置向导输出的注册命令。** 它使用当前安装的 Node 与专用 Python 环境的绝对路径,避免桌面应用与终端的 PATH 不同、或继承了另一套 Python 环境而启动失败。以下是手动配置的同等写法;将配置路径替换成向导的实际输出。

Windows PowerShell,在仓库目录执行:

```powershell
$repo = (Get-Location).Path
$node = (Get-Command node -CommandType Application).Source
$python = Join-Path $repo '.venv/Scripts/python.exe'
$config = '<向导输出的配置文件绝对路径>'
codex mcp add df_mcp -- $node (Join-Path $repo 'dist/index.js') --config $config --python $python
```

macOS / Linux:

```sh
node_bin="$(node -p 'process.execPath')"
codex mcp add df_mcp -- "$node_bin" "$PWD/dist/index.js" --config '<向导输出的配置文件绝对路径>' --python "$PWD/.venv/bin/python"
```

移动安装目录、删除旧 Node 版本或更换 Python 后,重新运行 setup/configure 并更新注册命令;不要沿用已不存在的解释器路径。`doctor --config ...` 会检查解释器与配置,实际连接仍需用 status 验证。

只有 Codex 桌面应用、没有 `codex` 命令时,也可在 Codex 的 `config.toml` 中配置同样的入口。未设置 `CODEX_HOME` 时,文件位于用户目录的 `.codex/config.toml`;已设置时使用该目录下的 `config.toml`。保留其他设置,将下面占位符替换为向导打印的真实绝对路径。如果 `df_mcp` 已存在,只更新原条目,不重复添加同名 TOML 区块:

```toml
[mcp_servers.df_mcp]
command = '<Node 可执行文件绝对路径>'
args = ['<安装目录>/dist/index.js', '--config', '<向导生成的配置文件绝对路径>', '--python', '<专用 Python 可执行文件绝对路径>']
```

Windows 的 Python 通常为 `<安装目录>\.venv\Scripts\python.exe`,Mac/Linux 为 `<安装目录>/.venv/bin/python`。这里的 Codex 配置文件只保存启动入口;JSON 内的 `state_dir` 仍必须在 `.codex` 之外。保存后完整退出并重新打开 Codex,以释放旧连接。

这里的 `df_mcp` 是客户端连接名称;Skill 仍为 `$df-mcp`,工具名保留 `team_drive_` 前缀兼容现有调用。旧版本用户应先关闭旧会话,在客户端移除旧 `team_drive` 连接,再添加新连接,避免保留重复注册。其他支持 stdio 的客户端参考 [examples/mcp.json](examples/mcp.json),替换路径占位符。启动新会话,让客户端发现 Skill 和工具。Windows 上已经使用临时 launcher 或修改过 `dist/index.js` 的用户,按[迁移说明](docs/WINDOWS_MIGRATION.md)检查、备份并替换。

多个 Codex 聊天使用同一份配置时,通过轻量 stdio 桥接连接同一个本地 broker,共享一个 Python 引擎、SQLite 索引和扫描调度。Mac/Linux 使用本机 Unix socket,Windows 使用 named pipe,不对外监听网络,也不安装系统服务。每个聊天有独立会话和分页游标;不能在聊天之间互换 cursor。

服务按需启动,最后一个客户端断开后空闲 60 秒退出。可用 JSON `"service": {"idle_seconds": 60, "max_clients": 64}` 配置空闲时间(1–3600 秒)和客户端上限(1–256)。达到上限时按错误提示释放不用的连接并重试,不为每个聊天复制配置或索引。`state_pool` 仅保留旧独立 worker 的兼容用途,普通 MCP 不再按聊天占索引槽。

`team_drive_status` 返回服务版本、source/config 身份、实例、健康状态、当前作业 ID(详见 job_status)和 `state_storage`。先看实际返回能力,不能凭 Skill 文件推定已连接新版。多个客户端共享刷新/取消作业:取消会影响同一来源其他会话;只有任务确实不再需要时才取消。配置在服务运行中发生变化时,按提示关闭相关连接并等待服务退出后重新连接,不混用配置。

修改启动入口后需重新连接旧聊天;已关闭的 stdio 管道不会被修改配置复活。手动 `npm start -- --config '<配置路径>'` 也只是一个桥接客户端。服务没有隐式源目录,不在协议会话中弹出目录选择框。

### 诊断当前连接

```sh
node scripts/doctor.mjs --config '<配置路径>'
node scripts/call-tool.mjs team_drive_status --config '<配置路径>'
node scripts/call-tool.mjs tools --config '<配置路径>'
```

`doctor` 仅离线读取指定配置、源码/构建版本与路径状态,不启动 worker、不扫描源文件、不创建或修复状态;其成功不能代替实时状态检查。它显示本机路径,分享前需脱敏。`call-tool` 明确连接指定配置;只有显式 `--demo` 才使用虚构样本,不会默认把模拟库当成用户资料库。status 立即返回,普通读取等待初次索引最多 60 秒;大库使用持久客户端观察进度。

Mac 升级时先用原连接的配置运行 doctor,核对实际来源和版本。若原连接使用仓库虚构示例,可继续保留同一示例配置;升级服务不会自动切换到真实资料或新根目录。源码副本、构建结果与 Codex 启动入口是三个不同位置,只有重新连接后的 status 才能确认实际运行版本。

示例请求:

```text
使用 $df-mcp 查指定资料目录里本月的正式预算及可用金额,说明口径并引用单元格;缺少资料时明确说明。
```

AI 应先检查索引状态,区分正式资料与草稿,读取证据,再用确定性程序计算。搜索结果不能证明业务数据完整。

### 升级、恢复与磁盘维护

0.3 从受管理源码构建服务,不直接导入 0.1/0.2 根层索引或 0.2.1 的 `pool-v1/`。这些旧缓存保留,首次启动共享索引会重建一次,随后所有聊天复用。来源身份不变、已有外部配置可继续使用;重新运行 configure 会按根目录/状态绑定复用配置,并原样保留自定义选项和键顺序。改变来源需要明确选择/确认并生成独立 profile,不会覆盖旧来源绑定。

共享服务使用磁盘工作数据库和已提交检查点。启动从已提交版本恢复;每次提交采用受控临时快照和原子替换,工作文件中断不会被当成新的完整版本。证据读取仍重新校验源 hash。索引是可重建缓存,不能取代源资料备份,也不能把进程强杀测试理解为所有磁盘故障/断电场景已验证。

稳定运行保留已提交库和工作库,提交时另需一个临时快照;若有损坏快照,至多另留一份隔离副本。因此应按最多约 3 份完整索引、含隔离副本时约 4 份预留空间;这是单个共享服务的空间预算,不随聊天数增加。已结束作业最多保留 100 条。解析临时文件只在独占租约下按受控规则回收,不递归删除未知内容。

```sh
node scripts/maintain-state.mjs --config '<配置路径>' --prune-exports-days 30
node scripts/maintain-state.mjs --config '<配置路径>' --prune-exports-days 30 --apply
```

维护默认预览,`--apply` 才删除选中的派生文件;`--reset-index` 可明确重建已提交/工作/临时/隔离数据库,保留导出、依据包和未知文件。来源目录身份确已更换时,只有明确的 `--reset-index --accept-source-replacement` 才接受新身份;不要为绕过错误自动加此参数。它获取与服务相同的租约并跳过忙状态。完成全量维护前关闭相关连接、等待 broker 空闲退出;不删除锁文件来强制释放服务。导出保留期只清理未被依据包引用的独立 JSONL;依据包清单及其引用的导出长期保留,不自动到期。无法核实清单引用时拒绝清理(BUNDLE_REFERENCES_UNVERIFIED)。旧缓存/profile 需核对后单独处理,源目录永远不属于清理范围。Windows 迁移及实机验收见[迁移说明](docs/WINDOWS_MIGRATION.md)。

### 只读的含义

源文件仅以读取权限打开,不提供修改、删除、重命名、移动或更改权限的 MCP 接口。解析快照、索引和生成结果写到独立状态目录。应用清理与 Skill 迁移不处理源资料。Windows 为固定目录身份而持有的句柄可能暂时阻止目录重命名或移除;需要整理源目录时先关闭服务。

这些保障约束本 MCP,**不能撤销 AI 宿主其他终端或文件工具的写权限**。需要操作系统强制只读时,由 IT 配置受限账户或隔离环境;普通安装不改变源目录 ACL。详见 [Windows 只读部署](docs/WINDOWS_READ_ONLY.md)。

Windows 不支持直接读取 OneDrive cloud reparse 文件:即使已经下载,有些文件仍可能被识别为云文件而跳过。在线占位文件不自动下载。当前请使用获准资料在普通、非同步本地文件夹中的副本;被排除或占用的文件会形成覆盖缺口,不能当作已读取。

## 测试与模拟演示

不配置个人目录、只构建并测试:

```sh
npm run setup -- --skip-config
npm test
npm run test:installer
npm run test:doctor
npm run test:backend
npm run test:mcp
npm run test:concurrency
npm run test:install
```

测试使用隔离临时目录和虚构资料。`--skip-config` 只跳过目录配置,不创建可用的个人读取连接。已有依赖和编译结果时可直接运行测试。

CI 在 Windows、macOS、Linux 的清洁检出中安装依赖并构建,覆盖 Python 3.9 与 3.13。`test:install` 另外使用临时用户目录运行真实配置、Skill 安装和诊断命令,再启动两份 MCP 客户端检查同文件读取、共享实例、关闭重开与来源不变。它验证默认路径与安装流程;不能代替每台电脑的企业策略、源 ACL 或 Codex 应用级验收。

新安装的最小验收:在两条聊天各自调用 status,确认版本为 0.3.0、`state_storage.mode=shared`、同一个 `instance_id`,再 inspect/read 同一文件。完整退出并重开 Codex 后重复一次。失败时保留结构化错误,用明确配置运行 doctor;不要创建随机状态目录或删除活动锁文件作为修复。

`npm run demo` 显式启动模拟目录的 stdio 服务;它不提供聊天界面,需 MCP 客户端发送协议请求。也可将客户端 `--config` 指向仓库 `examples/config.sample.json`,用 `$df-mcp` 查询样本。演示配置使用独立的 `.local/sample-v02-state/`,不会自动替换你的正式配置或复用 0.1 旧演示缓存。

## 工具与完整性

| 工具 | 用途 |
|---|---|
| `team_drive_status` | 覆盖范围、状态、限制、索引更新时间 |
| `team_drive_list` | 分页列出文件,包含失败/不支持的条目 |
| `team_drive_search` | 按名称与正文关键词发现候选;结果须回查 |
| `team_drive_inspect` | 校验版本,分页导航章节/工作表/页面结构 |
| `team_drive_read` | 按工作表/行范围/PDF页/幻灯片筛选分段,支持版本锁定与续读 |
| `team_drive_export` | 将指定版本已提取片段导出到受控 JSONL,保留提取缺口 |
| `team_drive_evidence_bundle` | 将指定文件版本汇集为依据包,返回来源清单、导出、观察时间窗与缺口 |
| `team_drive_refresh` | 排队增量更新;`force=true` 重试并重建 |
| `team_drive_job_status` | 查看更新任务与失败情况 |
| `team_drive_cancel` | 请求在安全文件边界取消更新 |

`inventory_complete` 是本次目录盘点完成;`all_present_files_indexed` 是盘点内文件均为 ready(可包含部分提取);`all_present_files_extracted_completely` 才同时要求没有文本提取缺口;`extraction_complete` 是该解析器完成支持内容的提取。它们**都不表示业务资料齐全或视觉内容全部理解**。必须查看 `format_warnings`。致命解析失败不提供成功正文;可明确划定的部分 PDF 提取会保留可读页并标出缺口,不能作为完整文件证据。

Excel 公式与保存值分开返回;保存值可能过期,没有自动重算。Word 页码不稳定,使用段落/表格引用。PPT 图形、PDF 复杂表格、扫描件等存在明确边界。完整限制见 [formats.md](skills/df-mcp/references/formats.md)。

完整汇总应先确定权威来源和业务范围,分页列出并处理全部相关文件,检查遗漏与版本,再用 evidence_bundle 保存文件清单、版本化导出和缺口,用确定性代码计算。依据包生成成功不代表输入总体完整或业务口径已批准。导出是服务状态目录中的 JSONL,不是原始二进制文件。`artifact_path` 是运行时返回给本地分析工具的绝对路径,不能将含该路径的完整工具轨迹直接公开发布。

## 更新、限制和性能

运行时默认每 30 秒核对文件元数据,仅解析新增或变化内容。每次证据读取会重新计算原文件 SHA256,故大文件读取仍有顺序 I/O 成本。关闭服务或休眠时不会继续更新,恢复启动后补查。原生操作系统文件事件监听不在本版中。

默认单文件 256 MiB、压缩包总展开体积 512 MiB、100000 个片段、每段 8000 字符、512 列、2000 PDF 页、解析超时 30 秒。超限返回错误,不静默截断。参数可配置,调整前应针对代表性文件验证内存和耗时。

Linux 解析子进程设置地址空间上限;macOS 和 Windows 没有相同的硬内存保证,依靠大小/展开限制和超时。长任务可取消和重启;重启复用已完成文件,单个中断文件重新解析,不承诺从中断行继续。

基准测试:

```sh
.venv/bin/python scripts/benchmark.py --files 1000 --rows 50000
```

Windows 可将命令中的 `.venv/bin/python` 换成 `.venv\Scripts\python.exe`。生成的结果只在 `.local/` 保存。用真实规模验收前,不应承诺任意文件“秒级准确”。

## 开发与发布

TypeScript MCP 适配层在 `src/`;Python 索引与解析在 `python/team_drive/`;Skill 在 `skills/`。业务来源与指标登记示例在 `examples/`,仅供业务层参考,不代表本工具已自动认证资料权威性。

公开发布前执行:

```sh
git add .
npm run check:public
```

检查器扫描 Git 跟踪文本中的凭证模式、私人主目录、邮箱、意外二进制和运行状态文件;它不能替代人工审查。不要提交真实资料、配置、导出、工具完整轨迹、索引或缓存。源码使用 MIT 许可证;依赖保留各自许可证。

TDQS

A3.8/5.0

Scored across 9 tools

Disambiguation4/5

Each tool targets a distinct stage of the index lifecycle, and the descriptions actively draw boundaries (status = inventory totals/limits, job_status = live job progress; inspect = structure/hash verification, read = content segments). The only mild overlaps are status vs job_status and inspect vs read, both of which are clarified but still plausibly confusable at a glance.

Naming Consistency5/5

All nine tools use a uniform team_drive_<action> snake_case pattern with predictable verbs (list, search, inspect, read, export, refresh, cancel). No mixed conventions or abbreviations; an agent can guess new tool names reliably.

Tool Count5/5

Nine tools is well within the ideal range and each maps to a necessary distinct operation in the index-and-read workflow. Nothing feels redundant or bolted on.

Completeness5/5

The surface covers the full lifecycle: triggering/cancelling/refreshing indexing, monitoring job and overall status, discovering files via list and search, verifying via inspect, reading content pages, and exporting a versioned artifact. Sources are intentionally read-only, so the absence of write tools is correct rather than a gap.

Maintenance

ActivityMaintained
ResponsivenessNo issues