内容
# 文档编辑服务
文档编辑服务是一个核心实现单一的服务,提供三种暴露方式:
- FastAPI JSON API;
- STDIO上的MCP服务器,用于本地MCP客户端;
- 流式HTTP上的MCP服务器。
## 范围和状态
该项目旨在成为一个完整的文件敏感数据保护MCP套件,专注于文档的检查、去标识和去敏感化。它将支持多种文档格式,如PDF、PPT、DOCX、TIFF等。该MCP服务器的范围是为Ai代理和Agentic工作流提供SDP功能。
以下是该项目的粗略路线图:
- [x] 初始项目结构设置
- [x] PDF文档编辑引擎实现
- [x] 核心编辑服务的实现
- [x] 作为Fast API服务器的服务暴露(用于测试)
- [x] STDIO模式下的MCP服务器实现
- [x] HTTP模式下的MCP服务器实现
- [ ] DOCX文档编辑引擎实现
- [ ] PPT文档编辑引擎实现
- [ ] TIFF文档编辑引擎实现
- [ ] 核心数据替换服务的实现
## 要求
- Python 3.12 或更新版本
- [uv](https://docs.astral.sh/uv/)(推荐)或已安装依赖的Python环境
安装应用程序和开发依赖:
```bash
uv sync --extra dev
```
运行测试套件:
```bash
uv run python -m pytest --cov=src --cov-report=html
```
## 运行服务
### FastAPI
在8080端口启动HTTP API:
```bash
uv run python -m uvicorn src.server.main:app --port 8080
```
运行后,交互式OpenAPI文档可在`http://127.0.0.1:8080/docs`访问。
端点:
| 方法 | 路径 | 目的 |
| --- | --- | --- |
| `GET` | `/health` | 健康检查,返回`{"status":"ok"}`。 |
| `POST` | `/redact` | 编辑PDF并以base64返回结果。 |
### STDIO上的MCP
当MCP客户端启动编辑服务作为本地子进程时使用:
```bash
uv run redaction-mcp-stdio
```
例如,MCP客户端命令可以使用:
```json
{
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/redaction", "redaction-mcp-stdio"]
}
```
服务器提供一个名为`redact`的工具,其请求和响应模式与FastAPI API相同。
### HTTP上的MCP
启动流式HTTP MCP服务器:
```bash
uv run redaction-mcp-http
```
它默认监听`127.0.0.1:8000`,并在`/mcp`上公开MCP。配置绑定地址或端口使用`MCP_HOST`和`MCP_PORT`:
```bash
MCP_HOST=0.0.0.0 MCP_PORT=8000 uv run redaction-mcp-http
```
## 文档输入契约
每个请求都有`document`、`targets`和可选的`options`字段。必须提供恰好一个文档源:
| 字段 | 用例 | 备注 |
| --- | --- | --- |
| `path` | 本地服务器端文件 | 路径在API/MCP服务器上解析,而不是客户端机器上。 |
| `url` | 远程文件 | 服务器在处理前下载URL。 |
| `base64data` | JSON/MCP有效载荷 | 标准base64编码的文档内容。这是推荐的HTTP输入。 |
不接受`data`。`base64data`使二进制编码显式,并保持API安全地序列化为JSON。
可选的文档元数据:
```json
{
"filename": "contract.pdf",
"mime_type": "application/pdf"
}
```
响应包含`filename`、`mime_type`和`base64data`。解码最后一个字段以检索编辑后的PDF。
## FastAPI示例
### 编辑base64编码的PDF内容
在Linux上,不带换行编码文件并提交:
```bash
PDF_BASE64=$(base64 -w0 input.pdf)
curl --request POST http://127.0.0.1:8080/redact \
--header 'Content-Type: application/json' \
--data "{
\"document\": {
\"base64data\": \"${PDF_BASE64}\",
\"filename\": \"input.pdf\",
\"mime_type\": \"application/pdf\"
},
\"targets\": [{
\"type\": \"text\",
\"values\": [\"Confidential\"]
}]
}" > response.json
jq -r '.base64data' response.json | base64 --decode > redacted.pdf
```
### 编辑服务器可访问的PDF
```bash
curl --request POST http://127.0.0.1:8080/redact \
--header 'Content-Type: application/json' \
--data '{
"document": {"path": "/srv/documents/input.pdf"},
"targets": [{"type": "text", "values": ["Confidential"]}]
}'
```
不要在远程托管的API中使用客户端本地路径;请改用`base64data`或URL。
## 编辑目标
### 文本
编辑所有精确出现的内容,可选地限制在页面上:
```json
{
"type": "text",
"values": ["Jane Doe", "123-45-6789"],
"pages": [0, 2]
}
```
### 正则表达式
```json
{
"type": "regex",
"patterns": ["[A-Z]{2}\\d{6}"],
"ignore_case": false,
"only_first_match": false,
"allow_unicode": false
}
```
正则表达式针对提取的单词进行评估,因此每个匹配项都会编辑匹配单词的矩形。目前不支持跨单词或多行表达式。
### 边界框
```json
{
"type": "bounding_box",
"values": [{
"page": 0,
"x": 0.1,
"y": 0.2,
"width": 0.3,
"height": 0.05,
"units": "normalized"
}]
}
```
`normalized`坐标是页面宽度和高度的比例。`inches`转换为PDF点(每英寸72点);`pixels`直接用作PDF点。
### 多边形和页面
```json
{
"type": "polygon",
"values": [{
"page": 0,
"points": [{"x": 72, "y": 72}, {"x": 180, "y": 72}, {"x": 72, "y": 120}]
}]
}
```
多边形点目前会产生一个覆盖多边形包围矩形的编辑。对于整个页面,使用:
```json
{"type": "page", "values": [0, 3]}
```
## 选项
```json
{
"fill_color": "#000000",
"fill_opacity": 1.0,
"permanent_redaction": true
}
```
`fill_color`必须是六位十六进制颜色。启用`permanent_redaction: true`(默认值)后,将应用编辑注释,从输出PDF中删除编辑区域的内容。仅在需要可审查的基于注释的结果时,将其设置为`false`。
## 架构
```text
FastAPI / MCP STDIO / MCP HTTP
|
v
src.core.services.redaction_service
|
v
src.core.engines.pdf_redaction (PyMuPDF)
```
传输层共享`RedactionRequest`和`RedactionResponse`;核心返回已编辑的`Document`或类型化的`RedactionError`。
## 安全说明
- 将永久编辑视为不可逆。保留源文档,并在分发前验证输出。
- `path`或`url`使服务器读取该资源。仅向受信任的调用者公开此服务,或在公开部署之前添加身份验证和源访问控制。
- Base64会使有效载荷大小增加约三分之一;使用合理的请求限制和大文档的文件存储工作流。
## 问题?
- 如果您有任何疑问或需要任何改进/修复,请在GitHub上提出新问题并说明上下文。
- 我将尽快跟进,但对于某些人来说,这可能仍然不够快。请给我时间,`me slow` :)
---
### 编程愉快!!!