Leave MCP Server
by daomengKJ
README.md
# 请假流程 MCP 服务
将 Dify 请假流程封装为 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 服务,让 LLM 客户端(Claude Desktop、Trae 等)通过标准 MCP 协议调用工具完成请假申请。
## 功能特性
- **6 个业务流程层工具**:覆盖请假全流程(初始化、选岗、计算天数、附件检查、上传、提交)
- **环境切换**:通过 `API_ENV` 环境变量一键切换 UAT/PRD 环境,所有接口统一域名
- **业务校验内置**:年假/调休假余额校验、丧假 ≤3 天限制、7 类附件要求
- **附件上传**:支持 base64 编码和本地文件路径两种方式
- **无状态设计**:MCP 服务无状态,状态由 LLM 上下文保存,确认后再执行
- **流程引导 Prompt**:内置 `leave_flow_guide` 提示词,指导 LLM 按序调用工具
## 安装
```bash
# 克隆项目后安装(包含开发依赖)
pip install -e ".[dev]"
```
### 环境变量配置
复制 `.env.example` 为 `.env` 并按需修改:
```bash
copy .env.example .env
```
| 变量 | 说明 | 默认值 |
|------|------|--------|
| `API_ENV` | 环境切换:`uat` 或 `prd` | `uat` |
| `API_BASE_UAT` | UAT 域名 | `https://zhgr-mp-uat.huanhuigroup.cn` |
| `API_BASE_PROD` | PRD 域名 | `https://zhgr-mp.huanhuigroup.cn` |
切换生产环境只需设置 `API_ENV=prd`,所有接口自动指向 PRD 域名。
## 使用方式
### 1. MCP Inspector(开发调试)
```bash
mcp dev src/leave_mcp/server.py
```
浏览器打开 Inspector 界面,可手动触发每个工具并查看返回结构。
### 2. Claude Desktop 配置
在 Claude Desktop 配置文件(`claude_desktop_config.json`)中添加:
```json
{
"mcpServers": {
"leave-service": {
"command": "python",
"args": ["-m", "leave_mcp.server"],
"cwd": "D:\\子公司AI大赛PPT\\003",
"env": {
"PYTHONPATH": "D:\\子公司AI大赛PPT\\003\\src",
"API_ENV": "uat"
}
}
}
}
```
> `API_ENV` 设为 `uat` 或 `prd`,不设置默认 `uat`。切换到生产环境改为 `"prd"` 即可。
### 3. 直接运行
```bash
python -m leave_mcp.server
```
## 工具列表
| # | 工具名 | 功能 | 封装接口 |
|---|--------|------|---------|
| 1 | `init_leave_flow` | 初始化流程:获取用户信息、检查未销假、获取请假类型和余额 | 接口 1+4+2+3 |
| 2 | `select_organization` | 从岗位列表中选择指定岗位(边界校验) | 无 |
| 3 | `calculate_leave_days` | 计算实际休假天数 + 年假/调休假余额校验 | 接口 5 |
| 4 | `check_attachment_requirement` | 根据请假类型检查附件要求(7 类规则 + 丧假 ≤3 天) | 无 |
| 5 | `upload_attachment` | 批量上传附件(支持 base64 编码或文件路径) | 接口 7 |
| 6 | `submit_leave_application` | 提交请假申请,返回申请单号 | 接口 8 |
### Prompt
- `leave_flow_guide`:请假流程引导,指导 LLM 按 `init → select → calculate → check_attachment → (upload) → submit` 顺序调用工具。
## 工具调用流程
```
用户发起请假请求
│
▼
init_leave_flow(user_token)
│
├── has_pending_leave=true → 提示用户先销假,结束
│
▼
select_organization(user_orgs, selected_index) [多岗位时]
│
▼
calculate_leave_days(...)
│
├── balance_sufficient=false → 提示余额不足
│
▼
check_attachment_requirement(leave_type, leave_days, has_attachment)
│
├── action=reject → 提示拒绝原因(如丧假超3天)
├── action=upload → upload_attachment(...) → submit_leave_application(...)
└── action=submit → submit_leave_application(...)
```
## 附件要求速查
| 请假类型 | 所需附件 |
|----------|---------|
| 病假 | 诊断证明或病假条(二选一) |
| 产假 | 产检证明 |
| 工伤假 | 工伤情况证明 |
| 婚假 | 结婚证 |
| 丧假 | 死亡证明(且时长 ≤ 3 天) |
| 流产假 | 诊断证明或病假条(二选一) |
| 年休假 | 无需附件(但需校验余额) |
| 调休假 | 无需附件(但需校验余额) |
## 测试
```bash
# 运行所有测试
pytest tests/ -v
# 运行特定测试类
pytest tests/test_tools.py::TestCalculateLeaveDays -v
```
测试覆盖:
- `test_client.py`:8 个 REST 接口封装(respx mock httpx)
- `test_tools.py`:6 个工具的正常/异常分支(未销假拦截、余额不足、丧假超限、7 类附件规则、base64 解码)
## 项目结构
```
├── pyproject.toml # 项目配置 + 依赖
├── .env.example # 环境变量示例
├── src/leave_mcp/
│ ├── server.py # FastMCP 实例 + 6 个工具 + prompt
│ ├── config.py # 环境切换配置(API_ENV 控制 uat/prd)
│ ├── models.py # Pydantic 输入输出模型
│ ├── client.py # httpx 异步客户端,8 接口封装
│ ├── exceptions.py # 自定义异常
│ └── prompts.py # 流程引导提示词
└── tests/
├── conftest.py # pytest fixtures
├── test_client.py # 接口封装测试
└── test_tools.py # 工具逻辑测试
```
## 关键设计决策
1. **环境切换**:通过 `API_ENV` 变量控制(`uat`/`prd`),所有 8 个接口统一域名,UAT 用 `zhgr-mp-uat.huanhuigroup.cn`,PRD 用 `zhgr-mp.huanhuigroup.cn`。
2. **错误分层**:业务可恢复结果(余额不足等)返回 `{success: false, message}` 不中断对话;系统异常抛错。
3. **无状态**:MCP 服务不保存会话状态,所需状态(如 `selected_org`、`leave_types`)由 LLM 在上下文中保存并作为参数传入。
4. **Token 传参**:`user_token` 通过工具参数传入,不在服务端存储。
5. **Prompts 替代编排**:Dify 的 22 节点状态机靠 `leave_flow_guide` prompt 指导 LLM 按序调用。
6. **附件双模式上传**:支持 `file_base64`(跨客户端通用)和 `file_path`(本地直读),优先 `file_path`。
## 技术栈
- Python ≥ 3.10
- [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) v1.0+
- [httpx](https://www.python-httpx.org/)(异步 HTTP 客户端)
- [Pydantic](https://docs.pydantic.dev/) v2.0+(数据验证)
- [pytest](https://docs.pytest.org/) + [respx](https://github.com/lundberg/respx)(测试)
TDQS
A4.3/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a clear, distinct purpose: initialization, leave calculation, attachment check, organization selection, upload, and submission. No overlapping functionality.
Naming Consistency5/5
All tools follow a consistent verb_noun pattern in snake_case, e.g., calculate_leave_days, upload_attachment. No deviations.
Tool Count5/5
With 6 tools, the server covers the essential steps of a leave application process without unnecessary bloat or missing critical operations.
Completeness4/5
The tool set covers the full leave application workflow: init, calculate, check, select, upload, submit. Minor gaps like viewing or canceling existing leave are absent but not critical for the core flow.
Maintenance
ActivityInactive
ResponsivenessNo issues