Skip to main content
Glama
daomengKJ
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