# 加班提报 MCP 工具

这是一个用于 **自动发起加班申请** 的小型 MCP（Master Control Program）脚本，负责根据加班日期自动完成以下工作：

- 检查该时间段是否已经存在未完成的加班记录，避免重复提报。
- 从个人日报中自动读取当天工作内容和项目信息。
- 按公司既有流程要求，组装并发起一条加班申请流程。
- 将执行结果记录到日志文件，方便排查问题。

整个过程通过 MCP 主控程序调度，不需要手动点页面、手动填加班单。

## 目录结构

- `config.py`
  全局配置中心，负责：
  - 加班相关接口的基础地址、鉴权信息
  - 日报模板 ID
  - 固定加班时间段（开始/结束时间）
  - 日志目录、日志文件名
  - 请求超时时间、日志级别等

- `overtime_task.py`
  加班提报子任务，实现实际的「业务动作」：
  - 校验加班日期格式是否正确
  - 统一计算加班开始时间/结束时间（基于配置）
  - 调用后端服务检查是否已存在有效加班记录
  - 从个人日报列表中查找指定日期的记录，提取内容与项目信息
  - 自动拼接加班原因（例如「日报内容 + 修改其 bug」）
  - 组装流程数据并调用后端服务发起加班流程
  - 以统一结构返回任务执行结果（成功/失败/跳过等）

- `mcp_core.py`
  MCP 主控程序：
  - 初始化全局配置和加班子任务
  - 初始化日志系统（控制台 + 文件双输出）
  - 提供命令行交互模式：只需输入加班日期即可触发加班提报
  - 调度子任务执行，并统一记录执行日志

- `.env`
  环境变量配置文件（不纳入版本控制），用于存放：
  - 接口基础地址
  - 鉴权 token
  - 日报模板 ID
  - 日志级别等敏感或与环境相关的配置

## 工作原理（高层描述）

> 本节只描述行为逻辑，不涉及具体接口路径和报文格式。

当你在命令行中运行 MCP 并输入某一天作为加班日期时，程序会按如下步骤执行：

1. **参数与格式校验**
   - 检查加班日期是否符合 `YYYY-MM-DD` 的格式；
   - 不合法时立即返回错误结果，不会发起任何接口调用。

2. **重复加班检查**
   - 根据该日期及预设的固定加班时间段，调用后端的「加班记录校验」服务；
   - 如果后端判断这个时间段内已经有未完成的加班记录，则任务返回「跳过」状态，不再继续提报。

3. **自动获取日报内容与项目**
   - 调用后端的「个人日报列表」服务，按配置的模板 ID 读取最近一段时间内的日报；
   - 在返回的列表中，找到 **日期等于加班日期** 的那一条记录；
   - 从该记录中读取工作内容字段，将其与固定后缀（例如「修改其 bug」）拼接成当次加班申请的内容；
   - 同时，如果日报中包含项目名称、项目编号等信息，则一并写入加班申请，作为本次加班归属的项目；
   - 如果当天没有对应日报，或读取失败，则回退使用配置中的默认加班内容和默认项目信息。

4. **发起加班流程**
   - 在通过重复校验且准备好加班内容/项目之后，构造一份符合流程引擎要求的数据结构（包含申请人、部门、加班日期、起止时间、原因、项目、审批状态等字段）；
   - 调用后端的「流程启动」服务，提交这份数据以发起一条新的加班流程；
   - 后端返回流程实例相关信息（例如流程实例 ID、创建时间等），会作为任务结果的一部分返回并写入日志。

5. **日志记录**
   - MCP 会在控制台和日志文件中记录每次任务的执行情况，包括：
     - 任务是否成功、是否因为重复记录被跳过、或因异常失败；
     - 后端返回的关键响应内容（在日志级别允许的前提下）。

## 配置说明

所有配置集中在 `config.py` 和 `.env` 中：

- 接口基础地址
  - 通过环境变量配置，用于拼出所有后端服务的完整地址；
  - 修改后无需改动代码即可切换环境（测试/生产等）。

- 鉴权信息
  - 通过环境变量保存访问后端服务所需的 token；
  - MCP 在调用所有子任务接口时，会自动带上该鉴权信息。

- 日报模板 ID
  - 指定用于读取个人日报列表的模板标识；
  - 如果企业内部模板调整，只需更新配置即可。

- 固定加班时间段
  - 配置每日加班起止时间（例如 18:30:00 到 20:30:00）；
  - MCP 会以此时间段作为「重复检查」和提报流程中的加班时间。

- 日志相关
  - 日志目录与文件名；
  - 日志级别（如 INFO/DEBUG），可通过环境变量控制输出详细程度。

- 其他
  - 请求超时时间；
  - 默认加班内容（在无法从日报自动获取内容时使用）。

## 使用方法

> 以下示例以本地开发环境为例，实际命令可根据你的 Python 管理方式微调。

1. **准备环境**

   - 安装 Python 3.10+；
   - 在项目根目录创建并激活虚拟环境（可使用 `uv` 或 `venv` 等工具）；
   - 安装依赖：
     - `requests`
     - `python-dotenv`

2. **配置 .env**

   在项目根目录创建 `.env` 文件，配置：

   - 接口基础地址；
   - 鉴权 token；
   - 日报模板 ID；
   - 日志级别等。

3. **运行 MCP 交互模式**

   在虚拟环境中执行：

   ```bash
    .venv\Scripts\activate
   python mcp_core.py
   ```

   然后按照提示输入加班日期（例如 `2026-01-05`）：

   - 程序会自动：
     - 校验日期；
     - 检查是否已有加班记录；
     - 从对应日期的日报中抽取内容和项目；
     - 发起加班流程；
     - 在控制台和日志文件中输出执行结果。

## 行为约定与边界情况

- 当加班日期当天没有日报时：
  - 不会直接失败；
  - 会回退为使用默认加班内容与默认项目信息继续提报。

- 当后端校验发现已存在未完成的加班记录时：
  - 当前任务不会再次发起加班流程；
  - 任务结果标记为「跳过」，并记录原因。

- 当调用后端服务发生网络或接口异常时：
  - 任务结果标记为失败；
  - 错误信息会记录到日志，方便排查。

## 二次开发建议

如果需要扩展本工具（例如支持更多类型的流程或不同的加班规则），建议：

- 保持 `config.py` 为唯一配置入口，将所有可变参数写在这里；
- 在 `overtime_task.py` 中增加新的任务类或方法，避免与现有流程强耦合；
- 在 `mcp_core.py` 中增加新的调度分支或命令行入口，而不是直接修改原有逻辑。

## 打包与安装

本工具已经适配标准 Python 打包方式，可以通过 `pyproject.toml` 打成安装包，在其他环境中直接安装使用。

### 本地构建安装包

1. 在本机安装构建工具：

   ```bash
   pip install build
   ```

2. 在项目根目录执行构建：

   ```bash
   python -m build
   ```

   构建完成后，会在 `dist/` 目录下生成安装包文件（包括 `.whl` 和源代码压缩包）。

3. 发布到 PyPI

   ```bash
   python -m twine upload dist/*
   ```

4. 安装构建好的包：

   ```bash
   pip install dist/jabanmcp-0.1.0-py3-none-any.whl
   ```

   或者在项目根目录直接本地安装：

   ```bash
   pip install .
   ```

   如果你习惯使用 `uv`，也可以：

   ```bash
   uv pip install .
   ```

### 安装后的使用方式

安装成功后，系统中会注册一个命令行入口：

```bash
jabanmcp
```

执行该命令等价于在项目目录中运行：

```bash
python mcp_core.py
```

也就是：

- 初始化 MCP 主控程序；
- 进入命令行交互模式；
- 只需输入加班日期，后续流程由程序自动完成。

## 在 IDE 中以 MCP 方式调用（JSON 配置示例）

可以为本工具增加一条自定义配置，方便在 IDE 中直接调用。


可以为加班提报 MCP 增加一段类似的配置：

```jsonc
{
  "servers": {
    "Overtime MCP": {
      "command": "uvx",
      "args": ["jabanmcp"],
      "env": {
        "OVERTIME_API_URL": "https://oa.chinawinddata.com:18380/8089",
        "OVERTIME_API_TOKEN": "XXX",
        "MCP_LOG_LEVEL": "INFO",
        "PROJECT_NAME": "XXXXXX",
        "PROJECT_ID": "XM-XS-XXXXX"
      }
    }
  }
}
```

使用说明：

- `command`
  - 对应已经通过 `pip install .` 或安装 wheel 之后注册的命令行入口 `jabanmcp`。
  - 如果你没有全局安装命令，也可以改成：
    - `command`: `"python"`
    - `args`: `["-m", "mcp_core"]`

- `args`
  - 留空数组表示不额外传入参数；
  - 如果改用 `python -m mcp_core` 方式，这里需要填上对应的模块参数。

- `env`
  - 将原 `.env` 中的关键配置显式写到 IDE 的环境变量中，常见字段包括：
    - `OVERTIME_API_URL`：加班相关接口的基础地址；
    - `OVERTIME_API_TOKEN`：访问后端服务所需的鉴权 token；
    - `DAILY_TEMPLATE_ID`：个人日报模板 ID；
    - `MCP_LOG_LEVEL`：日志级别（如 `INFO`、`DEBUG`）。
  - 这样即使不加载 `.env` 文件，只要 IDE 启动该 MCP 进程时带上这些环境变量，工具就可以正常工作。

- `type`
  - 一般保持为 `stdio`，表示通过标准输入/输出与 IDE 通信。

实际落地时，你只需要在 IDE 对应的 MCP 配置文件里，把上面的片段合并进去，并根据自己的环境替换 env 里的具体值即可。
