{"id":"efc3040f-7097-4610-a6e5-d8f41772ae38","slug":"moka-mcpserver","kind":"mcp","name":"moka-mcpserver","summary":"Self-constructed moka mcp server based on OpenAPI of moka for inner agent test","owner":"mingyangsun-sketch","repoUrl":"https://github.com/mingyangsun-sketch/moka-mcpserver","license":"MIT","licenseTier":"permissive","trust":"community","stars":3,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-06-23T08:33:16.000Z","addedAt":"2026-10-21T17:36:12.405Z","logoUrl":"https://avatars.githubusercontent.com/u/289643592?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools","cloud-infra"],"tags":[],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T04:07:20.981Z","sample":false,"url":"https://conduits.dev/tools/moka-mcpserver","language":"Python","transports":["stdio"],"install":{"pypi":"moka-mcp-server"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# Moka MCP Server\n\n基于 [Moka](https://www.mokahr.com) 开放 API 的 [MCP](https://modelcontextprotocol.io) Server。让 Claude、Cursor 等 AI 助手能够直接查询 Moka 招聘系统中的候选人、职位、招聘流程、组织架构、Offer 字段与人才库等信息。\n\n> **第一阶段：只读。** 仅提供查询类能力，不涉及任何写入 / 删除等高危操作。\n\n## 功能（Tool 一览）\n\n> 下表的端点与版本均已对**生产环境实测校准**。Moka API 实际分布在三套基础路径上：\n> `v1`（多数）、`v2`（招聘流程/阶段）、`candidate/v1`（候选人申请记录）。\n\n| 模块 | Tool | 真实端点 | 方法/版本 |\n|------|------|----------|-----------|\n| 候选人 | `search_candidates` | `/data/ehrApplications` | GET v1 |\n| 候选人 | `get_candidate_detail` | `/data/ehrApplications?applicationId=` | GET v1 |\n| 候选人 | `get_candidate_applications` | `/getApplicationStates`（body: candidateId） | POST candidate/v1 |\n| 候选人 | `get_candidate_stage` | 复用候选人详情的 `stageName` | GET v1 |\n| 职位 | `list_jobs` | `/jobs/{orgId}`（**mode 必填**：social/campus） | GET v1 |\n| 职位 | `get_job_detail` | `/jobs/{orgId}/{jobId}` | GET v1 |\n| 职位 | `get_job_custom_fields` | 取自职位详情的 `customFields` | GET v1 |\n| 流程 | `list_pipelines` | `/pipelines/getPipelinesList` | GET **v2** |\n| 流程 | `list_stages` | `/stage/getStagesList` | GET **v2** |\n| 组织 | `list_departments` | `/departments` | GET v1 |\n| Offer | `get_offer_custom_fields` | `/offers/custom_fields`（返回 social/campus） | GET v1 |\n| 人才库 | `list_talent_pools` | `/talentPool/list` | GET v1 |\n| 人才库 | `list_talent_pool_candidates` | `/talentPool/candidates`（需 archivedAt 范围 + talentPoolIds） | GET v1 |\n\n> **环境说明**：当前 API Key 仅在**生产环境**有效（CSM 未开通 staging），故 `MOKA_ENV` 请用 `production`。所有 Tool 均为只读，首阶段不涉及任何写操作。\n\n## 安装\n\n要求 Python 3.10+。\n\n```bash\n# 推荐用 uv\nuv pip install -e .\n\n# 或者用标准 venv + pip\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -e .\n```\n\n## 配置\n\n复制 `.env.example` 为 `.env` 并填入真实值：\n\n```bash\ncp .env.example .env\n```\n\n| 变量 | 必填 | 说明 |\n|------|------|------|\n| `MOKA_API_KEY` | ✅ | Moka API Key（Basic Auth），由 CSM 发放 |\n| `MOKA_ORG_ID` | 职位接口需要 | 组织标识，由 CSM 提供 |\n| `MOKA_ENV` | | `production`（默认）/ `staging` |\n| `MOKA_BASE_URL` | | 显式覆盖 Base URL，一般留空 |\n| `MOKA_MASK_SENSITIVE` | | 是否脱敏手机号/身份证，默认 `true` |\n| `MOKA_TIMEOUT` | | HTTP 超时（秒），默认 30 |\n| `MOKA_MAX_ITEMS` | | 自动翻页累计上限，默认 200 |\n\n## 运行\n\n```bash\n# 直接以 stdio 方式启动（供 MCP 客户端拉起）\nmoka-mcp-server\n\n# 或\npython -m moka_mcp.server\n```\n\n## 接入 Claude Desktop\n\n编辑 `claude_desktop_config.json`（macOS 路径：\n`~/Library/Application Support/Claude/claude_desktop_config.json`）：\n\n```json\n{\n  \"mcpServers\": {\n    \"moka\": {\n      \"command\": \"/绝对路径/到/.venv/bin/moka-mcp-server\",\n      \"env\": {\n        \"MOKA_API_KEY\": \"your_api_key_here\",\n        \"MOKA_ORG_ID\": \"your_org_id\",\n        \"MOKA_ENV\": \"production\",\n        \"MOKA_MASK_SENSITIVE\": \"true\"\n      }\n    }\n  }\n}\n```\n\n## 接入 Cursor\n\n在 `.cursor/mcp.json` 中加入相同结构的配置即可。\n\n## 自托管 HTTP 端点（Hermes / mcporter 接入）\n\n除本地 stdio 外，本服务支持以 **streamable-http** 方式部署成一个 HTTP 端点，供\nHermes Agent 等通过 `url` + `X-API-Key` 请求头接入（与团队现有自研 MCP server 一致）。\n\n### 1）以 http 方式启动\n\n在 `.env` 中设置：\n\n```env\nMOKA_TRANSPORT=http\nMOKA_HTTP_HOST=0.0.0.0\nMOKA_HTTP_PORT=8000\nMOKA_HTTP_PATH=/mcp\nMOKA_MCP_API_KEY=请设置一个足够随机的访问密钥   # agent 接入凭证\n```\n\n然后启动：\n\n```bash\nmoka-mcp-server\n# 端点即为 http://<部署机IP>:8000/mcp\n```\n\n> 鉴权：开启 `MOKA_MCP_API_KEY` 后，所有请求必须携带请求头 `X-API-Key: <该值>`，\n> 否则返回 401。留空表示不校验（仅限完全可信的内网）。生产环境务必设置，\n> 并在外层用 HTTPS（反向代理）保护。\n\n### 2）mcporter / Hermes 配置\n\n在 mcporter 配置（如 `~/.mcporter/mcporter.json` 或项目 `config/mcporter.json`）中添加，\n结构与团队其他 server 完全一致：\n\n```json\n{\n  \"mcpServers\": {\n    \"moka-mcp\": {\n      \"url\": \"https://<你的域名>/mcp\",\n      \"headers\": {\n        \"X-API-Key\": \"与 MOKA_MCP_API_KEY 相同的值\"\n      }\n    }\n  }\n}\n```\n\n验证连通与工具列表：\n\n```bash\nmcporter list moka-mcp --schema\nmcporter call moka-mcp.list_pipelines\n```\n\n> 注意区分两套凭证：`MOKA_API_KEY` 是「本服务 → Moka」的认证；`MOKA_MCP_API_KEY`\n> 是「agent → 本服务」的认证（对应请求头 `X-API-Key`），两者互不相同。\n\n## 通过 uvx 作为 stdio 包接入（推荐）\n\n本服务可作为标准 **stdio MCP 包**，由 agent（Hermes/mcporter）以子进程方式拉起，\n无需常驻 HTTP 服务。宿主机需有 Python / uv。\n\nmcporter（stdio 形式）配置示例：\n\n```json\n{\n  \"mcpServers\": {\n    \"moka-mcp\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"git+ssh://git@github.com/mingyangsun-sketch/moka-mcpserver.git\", \"moka-mcp-server\"],\n      \"env\": {\n        \"MOKA_API_KEY\": \"组织级 Moka Key\",\n        \"MOKA_ORG_ID\": \"Antalpha\",\n        \"MOKA_ENV\": \"production\",\n        \"MOKA_ACTING_EMAIL\": \"该 Slack 用户的可信邮箱（Hermes 校验后注入）\"\n      }\n    }\n  }\n}\n```\n\n> 每个用户用各自的 `env`（角色 + 身份）拉起一个实例，即可实现按用户限权（见下）。\n\n## 权限控制（面向企业内部用户）\n\n由于 Moka 的 API Key 是**组织级**的（能读全量数据），按用户限权只能在本服务层实现。\n身份模型为**模型 A**：Hermes 解析 Slack 用户 → 决定角色/部门 → 用对应 env 拉起该\n用户的 MCP 实例。因此 stdio 下**每个实例即一个调用者**，角色由启动 env 决定。\n\n### 角色\n\n| 角色 | 对应人群 | 可用工具 | 数据范围 |\n|------|----------|----------|----------|\n| `hr_admin` | HR/招聘团队负责人 | 全部 | 全量 |\n| `recruiter` | 招聘专员 | 候选人/职位/流程/Offer/人才库/组织（读） | 全量 |\n| `hiring_manager` | 用人经理/部门负责人 | 候选人/职位/流程/组织（无人才库） | **仅本部门** |\n| `interviewer` | 面试官 | 候选人状态/详情/阶段 + 职位/流程（无人才库/Offer） | **仅自己参与面试的候选人** |\n| `viewer` | 普通员工 | 职位/流程/组织（**不含候选人 PII**） | 全量（公开信息） |\n\n### 身份与角色的确定方式（两种）\n\n**① 按邮箱自动派生（推荐）**：Hermes 校验 Slack 用户后，注入其可信邮箱\n`MOKA_ACTING_EMAIL`。本服务用组织 key 在 Moka 解析该用户（`POST /users/list`\n按 email 精确查询），再按其 Moka `role` 与 `department` 自动定档：\n\n| Moka role | 自动派生角色 |\n|-----------|--------------|\n| ≥30（HR / 管理员 / 超级管理员） | `hr_admin`（全量） |\n| 20 / 25（用人经理 / 高级用人经理） | `hiring_manager`（仅其所在部门） |\n| 10（面试官） | `interviewer`（仅自己参与面试的候选人） |\n| 5 / 0（前台 / 内推人） | `viewer` |\n\n> 邮箱在 Moka 找不到 → 退化为 `viewer`（最小权限）。无需手工维护角色表，\n> 人员/部门在 Moka 一改，权限自动跟随。\n\n**② 静态配置（兜底，未配 `MOKA_ACTING_EMAIL` 时生效）**：\n\n| env | 说明 |\n|-----|------|\n| `MOKA_ROLE` | 上表角色之一；默认 `hr_admin` |\n| `MOKA_DEPARTMENTS` | `hiring_manager` 必填：逗号分隔的本部门名 |\n| `MOKA_SCOPE` | 数据范围覆盖：`all` / `department` |\n| `MOKA_ALLOWED_TOOLS` | 工具白名单覆盖（逗号分隔，`*` 表示全部） |\n\n控制分两层：\n- **工具级**：角色决定可调用哪些 Tool（如 `viewer` 不能调用 `search_candidates`）。\n- **数据行级**：`hiring_manager` 的候选人/职位结果按其部门过滤到本部门。\n\n> ⚠️ `MOKA_ACTING_EMAIL` 必须是 **Hermes 校验过的可信邮箱**，不能由 LLM 或用户\n> 随意填入，否则可冒充他人。\n\n### 权限模型边界（重要）\n\n本服务的权限是**我们自行设计的近似管控**，**不等同于**用户登录 Moka 后台时的真实数据权限：\n\n- Moka 只提供**组织级**访问控制：这把 API Key 是全权的、不区分调用者，Moka 不会按用户过滤。\n- Moka 也**未开放**「查询某用户有效数据权限范围」的接口（`/users/*`、`/userGroup/*` 只给\n  角色、部门、分组成员等属性，不含数据可见范围规则）。\n- 因此本服务只能用用户的 **Moka `role` + `department`** 两个属性，套**我们自己定的规则**做近似——\n  可能与该用户在 Moka 实际能看到的范围有出入（看多或看少）。\n\n> 若业务/合规要求「AI 中看到的 = 本人在 Moka 能看到的」强一致，Moka 现有 API 无法支持\n> （用户级 OAuth 亦不可行，Moka 仅支持组织级）。当前定位为**面向可信内部场景的近似管控**。\n\n> ⚠️ **安全前提**：组织级 Key 会随实例分发，因此按用户限权只有在**可信后端\n> （Hermes）统一持有 Key、并为每个用户 spawn 对应角色 env 的实例**时才真正有效；\n> 终端用户不能自行查看/修改 env，否则可拿全量 Key 绕过限制。\n\n## 设计要点\n\n- **认证**：Basic Auth（`Authorization: Basic base64(api_key + \":\")`），无需处理 token 刷新。\n- **错误处理**：统一映射 401/403/404/429/500 为友好提示；特别地，按 `stage` 查询且该阶段无候选人时 Moka 返回 500，本服务会将其作为「空结果」处理。\n- **分页**：基于 `next` 游标自动翻页，受 `MOKA_MAX_ITEMS` 上限保护。\n- **脱敏**：默认对手机号、身份证号掩码（`138****1234` / `4103**********2910`）。\n- **重试**：429 与网络错误做有限次指数退避重试。\n\n## 项目结构\n\n```\nsrc/moka_mcp/\n├── server.py          # FastMCP 入口，注册全部 Tool\n├── config.py          # 配置（pydantic-settings）\n├── client.py          # Moka HTTP 客户端（Basic Auth / 错误 / 重试）\n├── errors.py          # 统一异常与状态码映射\n├── tools/             # 各模块 Tool\n│   ├── candidates.py\n│   ├── jobs.py\n│   ├── pipelines.py\n│   ├── departments.py\n│   ├── offers.py\n│   └── talent_pools.py\n└── utils/\n    ├── pagination.py  # next 游标自动翻页\n    └── sanitize.py    # 敏感字段脱敏\n```\n\n## 待办（第二阶段）\n\n写入类能力（推进阶段、归档、创建职位、人才库导入、组织/人事同步等）暂未实现，详见需求文档第 3.3 节。\n"}