# Python MCP Gateway 这是一个轻量的 Python MCP Gateway,用来把 Workbuddy 的 MCP 工具调用转发到现有 ThinkPHP 授权接口和工具接口。 ## 当前状态 当前仓库已经具备一个可运行的 stdio MCP 入口,以及一套经过测试的核心模块,覆盖: - `.env` 优先的配置加载 - Redis token 存储,按员工本机 `session_key` 隔离 - 文件型 token 存储兜底 - `auth_code` 换票、续期、失效的认证客户端 - `bind_auth_code` 授权绑定工具 - 工具 HTTP 转发客户端 - `query_order` 工具注册 - Gateway 运行时会话管理 - MCP `initialize` / `tools/list` / `tools/call` 请求处理 - 本地命令模式下的 stdio MCP 启动入口 当前实现仍然保持“薄网关”原则: - 业务认证和权限判断仍然留在 ThinkPHP 项目中 - Gateway 只负责协议适配、会话管理和 HTTP 转发 - 第一阶段只开放查询型工具,当前从 `query_order` 开始 ## Workbuddy 配置 员工侧 Workbuddy 使用网络 UNC 路径启动 Gateway: ```json { "mcpServers": { "fms": { "command": "python", "args": [ "\\\\192.168.1.241\\mcp\\app.py", "serve-stdio" ] } } } ``` 不要把 `Y:\mcp\app.py` 写进 Workbuddy 配置;那只是开发机映射盘视角。 ## 常用命令 以下命令在 `mcp/` 目录下执行。 ### 查看工具列表 ```powershell python app.py list-tools ``` ### 绑定授权码(开发/排障) ```powershell python app.py bind --auth-code AUTH123 ``` 员工正式使用时不需要执行这条命令。Workbuddy 拉起 `serve-stdio` 后,员工应在 Workbuddy 中调用 `bind_auth_code` 工具完成绑定。 ### 直接调用 query_order(开发/排障) ```powershell python app.py call --tool query_order --keyword SO20260706001 --page 1 --limit 20 ``` ### 启动 MCP stdio 服务 ```powershell python \\192.168.1.241\chenjiacheng\mcp\app.py serve-stdio ``` 这个命令可作为 Workbuddy 本地命令模式下的 MCP 服务入口,由 Workbuddy 自动拉起,不要求员工手动执行。 ## 环境变量 当前代码直接支持以下文档口径的配置键: - `FMS_API_BASE` - `FMS_AUTH_BASE` - `FMS_TOOLS_BASE` - `FMS_CLIENT_TYPE` - `FMS_TIMEOUT_MS` - `FMS_TIMEOUT_SECONDS` - `FMS_REFRESH_SKEW_SECONDS` - `FMS_LOG_LEVEL` - `FMS_TOKEN_STORE` - `FMS_TOKEN_STORE_PATH` - `FMS_REDIS_HOST` - `FMS_REDIS_PORT` - `FMS_REDIS_DB` - `FMS_REDIS_PASSWORD` - `FMS_REDIS_PREFIX` - `FMS_SESSION_KEY` 同时兼容早期实现中的这些键名: - `MCP_AUTH_BASE_URL` - `MCP_TOOLS_BASE_URL` - `MCP_CLIENT_TYPE` - `MCP_TIMEOUT_SECONDS` - `MCP_REFRESH_SKEW_SECONDS` - `MCP_LOG_LEVEL` - `MCP_TOKEN_STORE` - `MCP_TOKEN_STORE_PATH` - `MCP_REDIS_HOST` - `MCP_REDIS_PORT` - `MCP_REDIS_DB` - `MCP_REDIS_PASSWORD` - `MCP_REDIS_PREFIX` - `MCP_SESSION_KEY` 说明: - `config.py` 会自动尝试读取 `mcp/.env`。 - 同名配置以 `.env` 优先,系统环境变量只在 `.env` 缺少该配置时兜底。 - 如果只提供 `FMS_API_BASE`,当前实现会同时把它作为 auth 和 tools 的基础地址。 - 如果 `base` 与 `fmsoperate` 部署在不同域名,应分别提供 `FMS_AUTH_BASE` 与 `FMS_TOOLS_BASE`。 ## .env 文件 当前 `mcp/` 目录建议使用 `.env` 保存共享 Gateway 配置。 推荐配置如下: ```dotenv FMS_AUTH_BASE=http://chenjiacheng.base.dahuo.fudingri.com FMS_TOOLS_BASE=http://chenjiacheng.fmsoperate.dahuo.fudingri.com FMS_CLIENT_TYPE=workbuddy FMS_TIMEOUT_SECONDS=10 FMS_REFRESH_SKEW_SECONDS=120 FMS_LOG_LEVEL=info FMS_TOKEN_STORE=redis FMS_REDIS_HOST=192.168.1.241 FMS_REDIS_PORT=6379 FMS_REDIS_DB=20 FMS_REDIS_PASSWORD= FMS_REDIS_PREFIX=fms:mcp:workbuddy: ``` 不要在共享 `.env` 中写死 `FMS_SESSION_KEY`。默认情况下 Gateway 会用员工本机的 `COMPUTERNAME` / `USERNAME` 自动生成稳定 `session_key`,Redis key 形如: ```text fms:mcp:workbuddy:{session_key} ``` 这样多个员工通过同一个 `\\192.168.1.241\chenjiacheng\mcp\app.py` 启动时,也不会共用同一个 token。 ## Token 存储 当前推荐使用 Redis: ```dotenv FMS_TOKEN_STORE=redis ``` Redis 存储行为: - `bind_auth_code` 成功后把 `mcp_token` 写入 Redis - Redis key 使用 `FMS_REDIS_PREFIX + session_key` - `session_key` 优先读取 `FMS_SESSION_KEY`,未配置时自动从员工本机信息生成 - token 过期时间会同步设置为 Redis TTL - `revoke` 成功后会删除当前 session 的 Redis key 文件存储仍保留为兜底方式: ```dotenv FMS_TOKEN_STORE=file FMS_TOKEN_STORE_PATH=C:/fms-mcp/.mcp_token.json ``` 如果使用网络共享 `app.py`,不要把 `FMS_TOKEN_STORE_PATH` 指向 `\\192.168.1.241\chenjiacheng\mcp\` 共享目录。 ## 本地接入建议 当前员工正式使用路径是: 1. 员工在后台获取一次性 `auth_code` 2. Workbuddy 自动通过 `python \\192.168.1.241\chenjiacheng\mcp\app.py serve-stdio` 拉起 Gateway 3. 员工在 Workbuddy 中调用 `bind_auth_code`,输入授权码完成绑定 4. Gateway 调用 `exchange` 时带上 `session_key` 5. token 保存到 Redis 当前员工对应的 key 6. 后续直接使用 `query_order` 等工具 `python app.py bind --auth-code ...` 仅保留给开发、联调和排障使用。 ## 测试命令 ```powershell python -m unittest discover -s tests -p "test_*.py" ``` ## 当前边界 当前 Gateway 已可作为本地 stdio MCP 进程使用,但仍保持最小边界: - 不在 Python 中沉淀额外业务规则 - 不直接连接业务数据库 - 不做动态插件加载 - 第一阶段不开放写入型工具