# 飞书项目 MCP 接入完整指南

> 最后更新: 2026-07-09 · Token: m-abfb29e8-3104-434f-9944-8d0bb592f8cd

## 凭证

```
MCP Server URL: https://project.feishu.cn/mcp_server/v1
Auth Header: X-Mcp-Token: m-abfb29e8-3104-434f-9944-8d0bb592f8cd
```

## 三个核心空间

| 空间 | project_key | simple_name | 用途 |
|------|------------|-------------|------|
| 销售管理 | 6593cd71471290e3cc6be6e6 | xsguanli | 13种工作项: story活动 + xsdd销售订单 + kh客户 + story商机 |
| 客户项目管理 | 658bb60520ea78a2125f1b99 | csrw | 407条客户项目跟踪 |
| 售后管理 | 658288abfb8bd616b17025f1 | br-shgl | 24条客诉工单(客户反馈单) |

## 工作项类型（销售管理·13种）

| 名称 | api/type_key | 用途 | 数据量 |
|------|-------------|------|--------|
| 商机 | story | 全部销售活动 | 3,104条 |
| 销售订单 | 662612aea6bb7089fea044ef / xsdd | 含金额+货号 | 47,709条 |
| 客户 | 65ae1e403c87b152f3365ca6 / kh | 客户档案 | — |
| 活动 | 65ae1e5d44338dbe7c39a29a / sj | 活动记录 | — |
| 联系人 | lxr | — | — |
| 线索 | customermanagement | — | — |
| 任务 | sub_task | — | — |
| 图表 | chart | — | — |
| 年销售目标 | nxsmb | — | — |
| 月销售目标 | yj | — | — |

## MQL 查询语法

### 正确格式
```
SELECT `字段1`, `字段2` FROM `项目名`.`工作项类型` ORDER BY `字段` DESC LIMIT N OFFSET M
```

### 必须同时传 project_key 参数
```json
{"project_key": "6593cd71471290e3cc6be6e6", "mql": "SELECT ..."}
```

### Story(商机)可用字段
- ✅ `名称` / `name`
- ✅ `description` / `描述`
- ✅ `创建时间`
- ✅ `创建者` / `owner`
- ✅ `work_item_id` / `工作项id`
- ❌ `活动关联客户` — 关系字段
- ❌ `活动对应销售订单` — 同上
- ❌ `SELECT *` — 不支持通配符
- ❌ `status` — 不在MQL字段中

### 销售订单(xsdd)可用字段
- ✅ `单据编号` — e.g. ZHBR260709013
- ✅ `货号#` — e.g. FE04-2-036001-10（注意含#号）
- ✅ `金额` — double_value，真实金额
- ✅ `单价` — 单价
- ✅ `销售数量` — 数量
- ✅ `创建时间`
- ✅ `创建者`
- ✅ `work_item_id` — 用于关联查询
- ✅ `description` → 反馈结果(销售)
- ❌ `关联客户` — 需通过关系查询
- ❌ `产品名称` — 不存在
- ❌ `规格` — 不存在

## 客户/销售员获取（关键突破）

### 销售员 → get_workitem_brief → role_members
```python
brief = mcp("get_workitem_brief", {"project_key": PK, "work_item_id": wid})
roles = brief['work_item_attribute']['role_members']
for role in roles:
    if role['name'] == '销售员':
        name = role['members'][0]['name']  # e.g. 陈溪子
```

### 客户 → list_workitem_relations → list_related_workitem
```python
# Step 1: 找到"销售订单-客户关联"的 relation_id
relations = mcp("list_workitem_relations", {"project_key": PK})
CUSTOMER_REL_ID = "6593cd71471290e3cc6be6e6:work_item_relation:relation_1713785263022"

# Step 2: 按订单查关联客户
related = mcp("list_related_workitem", {
    "project_key": PK,
    "work_item_id": "7044249225",
    "relation_id": CUSTOMER_REL_ID
})
customer_name = related['list'][0]['name']  # e.g. 成都普利泰生物科技有限公司
```

### 其他重要 relation_id
| 关系 | ID |
|------|-----|
| 销售订单→客户 | relation_1713785263022 |
| 销售订单→商机 | relation_1715302203273 |
| 活动→销售订单 | relation_1715284999934 |

## 分页策略

- 使用 `LIMIT 50 OFFSET N`（可靠，不循环）
- ❌ 不要用 session_id 分页（会循环重复，150%+数据）
- 大批量场景设上限（如150页=7500条）
- 客户补全每订单一次API调用 → 仅对近期数据做

## 业务线分类规则

销售管理3104条story自动分为:
- **生命科学销售部**: 名称含「课题组」→ PI lab
- **诊断原料销售部**: 其余 → IVD公司/项目

## URL构造

| 类型 | URL模板 |
|------|--------|
| Story/商机 | `https://project.feishu.cn/xsguanli/story/detail/{id}` |
| 销售订单 | `https://project.feishu.cn/xsguanli/xsdd/detail/{id}` |
| 售后管理 | `https://project.feishu.cn/br-shgl/detail/{id}` |
| 客户项目管理 | `https://project.feishu.cn/csrw/detail/{id}` |

⚠️ **URL中的类型名用 `story` 不是 `sj`**。导出模板Excel中URL用 `sj`（商机缩写），但前端路由用 `story`。验证工具: `meegle url decode <url>`

## 数据管道脚本

| 脚本 | 输出 | 数据量 |
|------|------|--------|
| `数据/mcp_pipeline.py` | feishu_complaints.json + feishu_blockers.json | 客诉24 + 阻塞42 |
| `数据/mcp_activities_pipeline.py` | daily_activities_mcp.json | 活动3104(459天) |
| `数据/mcp_sales_pipeline.py` | daily_sales_mcp.json | 订单7500(近90天明细) |

## Pitfalls

1. MQL的 project_key 是独立参数，不在MQL字符串里
2. OFFSET 分页比 session_id 更可靠（session_id会循环）
3. 中文字段名（创建时间、创建者、单据编号、货号#）
4. `SELECT *` 不支持，必须显式列出字段
5. `transition_node` action 只能是 `confirm` 或 `rollback`
6. 待办 node_name 不是当前阻塞节点，需 `get_node_detail` 验证
7. `sj/detail` URL打不开 → 必须用 `story/detail`
8. 客户/销售员不直接暴露在MQL → 用关系查询或workitem brief
9. 客户补全开销大（每单一次API），仅用于近期明细
10. Python脚本用 `subprocess.run(['curl', ...])` 直接调MCP，不走Hermes agent
