内容
# CRUDoc MCP 服务器
**通过模型上下文协议为 AI 助手提供文档 CRUD 操作。**
CRUDoc 使您的 AI 工具能够创建、读取、更新、删除、存档、列出和检查所有常见格式的文档 — 内置安全功能。
## 支持的格式
| 格式 | 扩展名 | 功能 |
|--------|-----------|----------|
| **纯文本** | `.md`, `.txt`, `.log`, `.csv`, `.tsv`, `.xml`, `.html`, `.rst`, `.adoc`, `.tex` | 行级读取、修补、追加、prepend |
| **YAML** | `.yaml`, `.yml` | 结构感知验证、键内省 |
| **JSON** | `.json` | 追加时智能合并(字典/列表感知)、验证 |
| **Word** | `.docx` | 标题/列表检测、运行感知修补(保留格式)、敏感性标签保留 |
| **PDF** | `.pdf` | 文本提取、通过 fpdf2 创建、通过 DOCX 中间体更新 |
## 安装
### GitHub Copilot CLI(插件)
```bash
copilot plugin install MSFTTracyP/crudoc-mcp
```
就这样。服务器将在下一次会话中自动加载。
### VS Code
克隆仓库,然后添加到工作区(或用户设置)的 `.vscode/mcp.json` 中:
```bash
git clone https://github.com/MSFTTracyP/crudoc-mcp.git
cd crudoc-mcp
pip install -r requirements.txt
```
`.vscode/mcp.json`:
```json
{
"servers": {
"crudoc": {
"command": "python",
"args": ["server.py"],
"cwd": "C:/path/to/crudoc-mcp"
}
}
}
```
### 其他 MCP 客户端(Claude Desktop 等)
添加到您的 MCP 客户端配置(例如 `claude_desktop_config.json`)中:
```json
{
"mcpServers": {
"crudoc": {
"command": "python",
"args": ["server.py"],
"cwd": "/path/to/crudoc-mcp"
}
}
}
```
### 先决条件
- Python 3.10+
- 安装依赖项:`pip install -r requirements.txt`
## 工具(7)
### `doc_create`
创建新文档。如果文件已存在,则失败。
```
参数:
path (必填)— 新文档的完整绝对路径
content (必填)— 文档内容
title (可选)— 标题元数据(用于 .docx 和 .pdf)
```
**示例:**
```json
{
"path": "/home/user/docs/meeting-notes.md",
"content": "# 冲刺计划\n\n- 审查待办事项\n- 分配故事\n- 设置冲刺目标"
}
```
---
### `doc_read`
读取文档内容。为所有格式(包括二进制格式,如 .docx、.pdf)返回提取的文本。
```
参数:
path (必填)— 文档的完整绝对路径
start_line (可选)— 从此行开始读取(基于 1 的索引)
end_line (可选)— 在此行停止读取(包括在内)
```
**示例:**
```json
{
"path": "/home/user/docs/config.yaml",
"start_line": 10,
"end_line": 25
}
```
---
### `doc_update`
使用四种模式更新现有文档。
```
参数:
path (必填)— 文档的完整绝对路径
mode (必填)— 以下之一:replace、patch、append、prepend
content (必填)— 新内容或替换文本
find (patch 模式必填)— 要查找的文本(必须有且仅有一个匹配)
backup (可选)— 修改前创建时间戳 .bak(默认:true)
```
**模式:**
| 模式 | 行为 |
|------|----------|
| `replace` | 完全内容替换 |
| `patch` | 查找确切文本并替换它(需要且仅需要 1 个匹配) |
| `append` | 将内容添加到末尾(JSON:字典/列表的智能合并) |
| `prepend` | 在开头插入内容(DOCX:保留原始格式) |
**示例 - patch 模式:**
```json
{
"path": "/home/user/docs/readme.md",
"mode": "patch",
"find": "版本:1.0.0",
"content": "版本:1.1.0"
}
```
**示例 - JSON 追加(智能合并):**
```json
{
"path": "/home/user/config.json",
"mode": "append",
"content": "{\"newKey\": \"newValue\"}"
}
```
---
### `doc_archive`
将文档移动到存档目录(`~/.crudoc/archive/`)并添加时间戳。需要确认。
```
参数:
path (必填)— 文档的完整绝对路径
confirm (必填)— 必须为 true 才能继续
reason (可选)— 存档原因(敏感性标记文档必填)
```
**示例:**
```json
{
"path": "/home/user/docs/old-spec.docx",
"confirm": true,
"reason": "被 v2 规格取代"
}
```
存档文件会以时间戳 + UUID 重命名:`20260611-123000_a1b2c3_old-spec.docx`
---
### `doc_delete`
永久删除文档。不可逆转。需要确认。
```
参数:
path (必填)— 文档的完整绝对路径
confirm (必填)— 必须为 true 才能继续
```
**示例:**
```json
{
"path": "/home/user/docs/temp-scratch.txt",
"confirm": true
}
```
> **注意:** 具有“机密+”敏感性标签的文档无法删除。请改用 `doc_archive`。
---
### `doc_list`
列出目录中的文档,可选过滤。
```
参数:
directory (必填)— 要列出的目录路径
extension (可选)— 按扩展名过滤(例如 `.md`、`.docx`)
recursive (可选)— 搜索子目录(默认:false)
```
**示例:**
```json
{
"directory": "/home/user/docs",
"extension": ".md",
"recursive": true
}
```
返回:每个文件的 filename、size(KB)和 last modified date。
---
### `doc_info`
获取文档元数据为 JSON。
```
参数:
path (必填)— 文档的完整绝对路径
```
**返回:**
```json
{
"path": "/home/user/docs/report.docx",
"filename": "report.docx",
"extension": ".docx",
"size_bytes": 45230,
"size_kb": 44.2,
"modified": "2026-06-11T10:30:00",
"created": "2026-05-01T09:00:00",
"paragraphs": 42,
"tables": 3,
"words": 1580,
"characters": 8942,
"format": "docx",
"sensitivity_label": {
"label_name": "一般",
"sensitivity_level": 1,
"is_encrypted": false,
"is_protected": false
}
}
```
---
## 安全功能
### 路径沙盒
所有文件操作都限制在允许的目录内。默认情况下,仅允许您的主目录(`~`)。
通过环境变量配置:
```bash
export CRUDOC_ALLOWED_ROOTS="/home/user/docs,/home/user/projects"
```
拒绝的操作:
- 相对路径
- 允许的根目录外部路径
- 指向允许的根目录外部的符号链接
### 敏感性标签检测(MIP)
CRUDoc 检测 `.docx` 和 `.pdf` 文件上的微软信息保护(MIP)标签:
| 标签级别 | 读取 | 更新 | 存档 | 删除 |
|-------------|------|--------|---------|--------|
| 公共 / 一般 | ✅ | ✅ | ✅ | ✅ |
| 机密 | ✅ | ✅(警告) | ✅(需要原因) | 🚫 阻止 |
| 高度机密 | ✅ | ✅(警告) | ✅(需要原因) | 🚫 阻止 |
**关闭行为:** 如果标签检测失败(文件损坏,解析错误),破坏性操作将被阻止,直到问题解决。
### 原子写入
所有文件修改都使用写入临时文件 → fsync → 原子替换。文件永远不会处于部分或损坏状态,即使在崩溃时。
### 时间戳备份
更新会创建备份文件,如 `file.md.bak.20260611-123000.a1b2c3` — 不会覆盖,不会冲突。
---
## 配置(环境变量)
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `CRUDOC_ALLOWED_ROOTS` | `~`(主目录) | 以逗号分隔的允许目录根路径 |
| `CRUDOC_ARCHIVE_DIR` | `~/.crudoc/archive` | 存档文件存储位置 |
| `CRUDOC_MAX_FILE_SIZE` | `52428800`(50 MB) | 读取/写入操作的最大文件大小 |
| `CRUDOC_MAX_LIST_RESULTS` | `5000` | `doc_list` 返回的最大文件数 |
| `CRUDOC_MAX_RECURSION_DEPTH` | `10` | 递归列出的最大目录深度 |
---
## 架构
```
crudoc-mcp/
├── .claude-plugin/
│ └── plugin.json ← Copilot CLI 插件清单
├── .mcp.json ← MCP 服务器定义(VS Code 兼容)
├── server.py ← 主 MCP 服务器(工具注册 + 调度)
├── handlers/
│ ├── __init__.py
│ ├── safe_io.py ← 路径验证,原子写入,限制
│ ├── text_handler.py ← 纯文本格式
│ ├── yaml_handler.py ← YAML 验证
│ ├── json_handler.py ← JSON 智能合并
│ ├── docx_handler.py ← Word 文档,标签保留
│ ├── pdf_handler.py ← PDF 创建/读取/更新
│ └── label_detector.py ← MIP 敏感性标签检测
├── requirements.txt
├── package.json
└── README.md
```
---
## 许可证
MIT