@vrs-soft/wecom-aibot-mcp 1.5.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,257 +5,212 @@ description: 当用户说「现在开始通过微信联系」时触发,进入
5
5
 
6
6
  # Headless 微信交互模式
7
7
 
8
- ## 重要说明
8
+ **触发词**:「现在开始通过微信联系」「我要离开电脑前」「切换到微信模式」
9
9
 
10
- **本模式使用 `wecom-aibot` MCP 服务器与企业微信通信,不使用其他任何通信方式。**
10
+ ## 进入微信模式流程
11
11
 
12
- MCP 服务器地址:`http://127.0.0.1:18963/mcp`
12
+ > **关键原则**:模式决定 MCP 前缀。Channel 模式全程用 `mcp__wecom-aibot-channel__`,HTTP 模式全程用 `mcp__wecom-aibot__`。**必须先确定模式,再进行后续操作。**
13
13
 
14
- 所有消息收发、长轮询、审批通知均通过 wecom-aibot MCP 工具完成。
14
+ ### 1. 确定运行模式
15
15
 
16
- ## 触发词
16
+ **必须首先用 AskUserQuestion 让用户选择**(或读取 `.claude/wecom-aibot.json` 中已保存的 mode):
17
17
 
18
- 「现在开始通过微信联系」「我要离开电脑前」「切换到微信模式」
18
+ - **Channel 模式**:消息自动推送唤醒,需要用以下命令启动 Claude(研究预览阶段):
19
+ `claude --dangerously-load-development-channels server:wecom-aibot-channel`
20
+ - **HTTP 模式**:心跳轮询,兼容所有环境(API Key、中转服务均可)
19
21
 
20
- ---
21
-
22
- ## 启动时自动恢复
23
-
24
- **检查文件**:`项目目录/.claude/wecom-aibot.json`
22
+ > 如果当前会话是通过 `--dangerously-load-development-channels` 启动的,默认选 Channel 模式。
25
23
 
26
- 如果该文件存在且 `autoApprove: true`,说明用户期望通过微信交互:
27
-
28
- ```
29
- 1. 读取 wecom-aibot.json 获取 robotName(用于选择机器人)
30
- 2. 调用 enter_headless_mode(agent_name, robot_id=robotName)
31
- 3. 服务端返回新的 ccId(如 cc-1)
32
- 4. 发送消息:【进度】已自动恢复微信模式
33
- 5. 开始长轮询
34
- ```
24
+ 根据选择,确定后续所有工具调用的 **MCP 前缀**:
25
+ - Channel 模式 → `MCP = mcp__wecom-aibot-channel__`
26
+ - HTTP 模式 → `MCP = mcp__wecom-aibot__`
35
27
 
36
- **注意**:ccId 由服务端生成,每次进入微信模式都会获得新的 ccId。
28
+ ### 2. 检查配置文件
37
29
 
38
- ---
30
+ 检查项目目录 `.claude/wecom-aibot.json`:
39
31
 
40
- ## MCP 协议说明
32
+ **a) 文件存在**
33
+ - 读取 robotName 和 ccId,直接跳到步骤 4
41
34
 
42
- **重要**:所有 wecom-aibot 工具通过 MCP (Model Context Protocol) HTTP Transport 调用,**不是直接 HTTP 请求**。
35
+ **b) 文件不存在**
36
+ - 执行以下准备步骤:
43
37
 
44
- ### 工具调用方式
38
+ #### 2.1 生成 ccId
45
39
 
46
- Claude Code 调用 MCP 工具时,会自动处理以下细节:
47
- - **sessionId**: MCP HTTP Transport 要求在 `initialize` 请求时获取 sessionId,后续所有请求必须在 `mcp-session-id` header 中传递。Claude Code **自动处理** sessionId,智能体无需手动管理。
48
- - **工具命名**: 所有工具名称格式为 `mcp__wecom-aibot__<tool_name>`(例如 `mcp__wecom-aibot__send_message`)
40
+ 格式:`${项目名}`(如 `wecom-aibot-mcp`)
49
41
 
50
- ### 智能体无需关心的事项
42
+ **禁止自动编号**,如有冲突提示用户改名。
51
43
 
52
- - 不需要手动获取 sessionId
53
- - ❌ 不需要手动传递 HTTP headers
54
- - ❌ 不需要了解 MCP 协议细节
55
- - ✅ 只需调用 MCP 工具,Claude Code 自动处理底层通信
44
+ #### 2.2 选择机器人
56
45
 
57
- ---
46
+ 调用 `${MCP}list_robots`:
58
47
 
59
- ## MCP 工具调用方式
48
+ - 机器人数量 = 1 → 直接使用
49
+ - 机器人数量 > 1 → **必须用 AskUserQuestion 让用户选择**
60
50
 
61
- | 功能 | MCP 工具名称 | 必需参数 |
62
- |------|-------------|----------|
63
- | 进入微信模式 | `mcp__wecom-aibot__enter_headless_mode` | agent_name, project_dir |
64
- | 发送消息 | `mcp__wecom-aibot__send_message` | cc_id, content |
65
- | 获取消息(长轮询默认30秒间隔) | `mcp__wecom-aibot__get_pending_messages` | cc_id |
66
- | 退出微信模式 | `mcp__wecom-aibot__exit_headless_mode` | cc_id, project_dir |
51
+ ### 3. 调用 enter_headless_mode
67
52
 
68
- ---
53
+ 使用步骤 1 确定的 MCP 前缀:
69
54
 
70
- ## 进入流程
55
+ ```
56
+ ${MCP}enter_headless_mode(
57
+ cc_id="<项目名>",
58
+ robot_id="<机器人名称>",
59
+ mode="<channel 或 http>",
60
+ project_dir="<项目目录>"
61
+ )
62
+ ```
71
63
 
72
- ### 1. 检查配置文件和机器人选择(必须首先执行)
64
+ 例如 Channel 模式:
65
+ ```
66
+ mcp__wecom-aibot-channel__enter_headless_mode(cc_id="知识库", robot_id="CC", mode="channel", project_dir="...")
67
+ ```
73
68
 
74
- **第一步:检查项目配置文件**
69
+ 例如 HTTP 模式:
70
+ ```
71
+ mcp__wecom-aibot__enter_headless_mode(cc_id="知识库", robot_id="CC", mode="http", project_dir="...")
72
+ ```
75
73
 
76
- 检查项目目录下的 `.claude/wecom-aibot.json`:
77
- - **文件存在且有 robotName** → 直接使用该 robotName,跳过机器人选择
78
- - **文件不存在或没有 robotName** → 需要用户选择机器人
74
+ ### 2. 处理返回结果
79
75
 
80
- **第二步:获取机器人列表**
76
+ **返回字段**:
77
+ - `status: 'entered'` → 进入成功(重连时直接覆盖,无需改名)
81
78
 
82
- 调用 `mcp__wecom-aibot__list_robots` 获取所有可用机器人。
79
+ ### 3. HTTP 模式:立即执行心跳
83
80
 
84
- **第三步:处理机器人选择**
81
+ **强制步骤,必须执行**:
85
82
 
86
- - **机器人数量 = 1** → 直接使用该机器人
87
- - **机器人数量 > 1 且配置文件中没有 robotName** → **必须使用 AskUserQuestion 让用户选择**
83
+ 1. 执行定时任务:
84
+ ```
85
+ /loop 1m mcp__wecom-aibot__heartbeat_check
86
+ ```
88
87
 
89
- ```
90
- 使用 AskUserQuestion 让用户选择机器人:
91
- question: "检测到多个机器人,请选择要使用的机器人"
92
- options: 每个机器人的名称(从 list_robots 返回的 robots 数组获取)
93
- ```
88
+ 返回示例:
89
+ ```
90
+ 已创建定时任务,job ID: abc12345
91
+ 1 分钟执行一次
92
+ ```
94
93
 
95
- **完整流程示例**:
96
- ```
97
- 1. 检查项目目录下的 .claude/wecom-aibot.json 是否存在
98
- - 存在 → 读取 robotName
99
- - 不存在 → robotName = null
100
- 2. 调用 list_robots 获取机器人列表
101
- 3. 判断:
102
- - 如果 robotName 存在 → 使用该 robotName
103
- - 如果机器人数量 = 1 → 使用该机器人
104
- - 如果机器人数量 > 1 且没有 robotName → 使用 AskUserQuestion 让用户选择
105
- 4. 调用 enter_headless_mode(agent_name, robot_id=确定的机器人名称)
106
- ```
94
+ 2. 提取返回中的 job ID(如 `abc12345`)
107
95
 
108
- **禁止的行为**:
109
- - ❌ 在多机器人场景下自动选择第一个
110
- - ❌ 直接调用 enter_headless_mode 不传 robot_id
111
- - ❌ 假设只有一个机器人而不检查
112
- - ❌ 忽略项目配置文件中的 robotName
96
+ 3. 调用 MCP 工具保存 job ID:
97
+ ```
98
+ mcp__wecom-aibot__update_heartbeat_job_id(cc_id="<ccId>", job_id="abc12345")
99
+ ```
113
100
 
114
- ### 2. 调用 enter_headless_mode
101
+ **注意**:此步骤必须在进入微信模式后立即执行,否则无法接收消息。
115
102
 
116
- **重要**:`agent_name` `project_dir` 必须由智能体生成,格式为项目名称或任务名称,不要让 MCP 生成。
103
+ ### 4. 开始轮询
117
104
 
105
+ **HTTP 模式**:
118
106
  ```
119
- mcp__wecom-aibot__enter_headless_mode(agent_name="<项目名称>", robot_id="<机器人名称>", project_dir="<项目目录>")
107
+ while (true):
108
+ result = mcp__wecom-aibot__get_pending_messages(timeout_ms=30000)
109
+ if result.messages → 处理消息,回复,继续轮询
110
+ if result.timeout → 立即重新调用
120
111
  ```
121
112
 
122
- **参数说明**:
123
- - `agent_name`: **必填**,智能体名称(使用当前项目名称或任务名称,如 "wecom-aibot-mcp"、"ModuleStudio")
124
- - `robot_id`: **必填**(多机器人场景),指定机器人名称
125
- - `project_dir`: **必填**,项目目录路径(用于写入 `.claude/wecom-aibot.json` 配置文件)
113
+ **Channel 模式**:等待推送,无需轮询。消息到达时 Claude 会被自动唤醒。
126
114
 
127
- **处理返回值**:
128
- - `entered` → 返回 `ccId`(服务端生成),继续下一步
129
-
130
- **注意**:
131
- - ccId 由 MCP Server 自动生成(如 `cc-1`),无需手动指定
132
- - 如果正确执行了步骤 1(机器人选择),不会收到 `select_robot` 状态
133
- - **进入微信模式时,MCP 会自动写入 `.claude/wecom-aibot.json`,设置 `wechatMode: true` 和 `robotName`**
115
+ ---
134
116
 
135
- ### 3. 写入项目级 Hook(可选)
117
+ ## 消息处理
136
118
 
137
- **注意**:VSCode 扩展可能不完全支持 PermissionRequest Hook。如果审批不生效,可跳过此步骤。
119
+ ### 收到消息后
138
120
 
139
- 读取当前工作目录的 `.claude/settings.json`(不存在则创建),合并写入:
121
+ **HTTP 模式**:
122
+ 1. 立即发送确认:`mcp__wecom-aibot__send_message(cc_id, "收到...", target_user=<chatid>)`
123
+ 2. 执行操作(Bash/Edit/Write)
124
+ 3. 发送结果:`mcp__wecom-aibot__send_message(cc_id, "【完成】...", target_user=<chatid>)`
125
+ 4. 继续轮询
140
126
 
141
- ```json
142
- {
143
- "hooks": {
144
- "PermissionRequest": [
145
- {
146
- "matcher": "",
147
- "hooks": [{ "type": "command", "command": "~/.wecom-aibot-mcp/permission-hook.sh" }]
148
- }
149
- ]
150
- }
151
- }
152
- ```
127
+ **Channel 模式**(收到 `<channel>` 标签时):
128
+ 1. 立即发送确认:`mcp__wecom-aibot-channel__send_message(cc_id, "收到...", target_user=<chatid>)`
129
+ 2. 执行操作(Bash/Edit/Write)
130
+ 3. 发送结果:`mcp__wecom-aibot-channel__send_message(cc_id, "【完成】...", target_user=<chatid>)`
153
131
 
154
- 保留文件中已有的其他配置,只合并 `hooks.PermissionRequest` 字段。
132
+ ### 回复路由
155
133
 
156
- **重要**:不要添加 `timeout` 字段,VSCode 扩展不支持该配置。超时控制由 hook 脚本内部的轮询机制处理。
134
+ `get_pending_messages` 返回的每条消息包含:
135
+ - `from`:发送者用户 ID
136
+ - `chatid`:会话 ID(单聊=用户ID,群聊=群ID,如 `wr0Q...`)
137
+ - `chattype`:`single` 或 `group`
157
138
 
158
- ### 4. 发确认消息
139
+ **回复时必须将 `chatid` 作为 `target_user` 传入**,确保回复到正确的会话:
159
140
 
160
141
  ```
161
- mcp__wecom-aibot__send_message("【进度】已进入微信模式,所有交互将通过企业微信进行。")
142
+ msg = messages[0]
143
+ send_message(cc_id, content, target_user=msg.chatid)
162
144
  ```
163
145
 
164
- ### 5. 开始长轮询
146
+ - 单聊:`chatid` = 发送者的用户 ID,等同于默认目标,可省略
147
+ - 群聊:`chatid` = 群 ID,**必须传入**,否则会发到默认的单聊用户
165
148
 
166
- **核心原则**:轮询永不退出,除非收到明确结束指令(「结束微信模式」「我回来了」)。
149
+ ### 消息格式
167
150
 
168
- ```
169
- while (true):
170
- result = mcp__wecom-aibot__get_pending_messages(timeout_ms=30000)
171
- if result.messages 处理消息,然后继续轮询
172
- if result.timeout → 立即重新调用(不需要 sleep,不需要任何等待)
173
- ```
174
-
175
- **timeout 不是停止信号**:
176
- - `timeout: true` 只表示"这 30 秒内没有消息"
177
- - 收到 timeout 后立即重新调用 `get_pending_messages`
178
- - 长轮询会阻塞等待,有消息立即唤醒,无消息等满超时后才消耗 token
179
- - 比短轮询节省约 6 倍 token
151
+ - `【进度】` - 里程碑汇报
152
+ - `【完成】` - 任务完成
153
+ - `【问题】` - 需用户决策
154
+ - `【需要确认】` - 二次确认
180
155
 
181
156
  ---
182
157
 
183
- ## 处理用户消息
158
+ ## 任务完成检查
184
159
 
185
- 1. **收到指令后先应答**:立即发送简短确认(如「收到,开始处理...」),让用户知道指令已被接收
186
- 2. 理解意图
187
- 3. 执行操作(Bash/Edit/Write 等)— Hook 自动处理审批,Claude 阻塞等待用户点击
188
- 4. 用 `mcp__wecom-aibot__send_message` 汇报结果
189
- 5. 继续轮询
160
+ **每次完成任务后必须执行**:
190
161
 
191
- **群聊回复**:`mcp__wecom-aibot__send_message(content, target_user=chatid)`
162
+ 1. 检查 `.claude/wecom-aibot.json`
163
+ 2. 如果 `autoApprove: true`:
164
+ - 发送结果到微信
165
+ - 恢复轮询(HTTP 模式)
192
166
 
193
167
  ---
194
168
 
195
- ## 任务完成检查(必须执行)
196
-
197
- **每次完成用户任务后,必须执行以下检查:**
198
-
199
- ```python
200
- def on_task_complete():
201
- # 步骤 1: 检查配置文件
202
- config = read_file(".claude/wecom-aibot.json")
203
-
204
- if config and config.get("autoApprove") == True:
205
- # 步骤 2: 必须通过 MCP 发送结果
206
- send_message("【完成】任务结果...")
207
-
208
- # 步骤 3: 必须恢复轮询
209
- while True:
210
- msg = get_pending_messages(timeout_ms=60000)
211
- if msg:
212
- handle_message(msg)
213
- # timeout 后立即重新调用,不需要 sleep
214
- ```
169
+ ## 退出微信模式
215
170
 
216
- **为什么必须执行**:
217
- - 配置文件存在且 `autoApprove: true` = 用户期望通过微信接收结果
218
- - 不执行 = 用户收不到结果,CC 被判定为离线
171
+ **触发词**:「结束微信模式」「我回来了」
219
172
 
220
- **注意**:即使是"compact"、"compacting"等内部任务,完成后也必须检查配置文件并恢复轮询。系统自动触发的 compacting 操作结束后,同样需要执行此检查。
173
+ 1. **停止心跳定时任务**(HTTP 模式)
174
+
175
+ a) 读取 `.claude/wecom-aibot.json` 中的 `heartbeatJobId`
176
+
177
+ b) 执行删除:
178
+ ```
179
+ /loop stop <heartbeatJobId>
180
+ ```
181
+
182
+ c) 删除配置文件中的 `heartbeatJobId` 字段
221
183
 
222
- ---
184
+ 2. 调用 `mcp__wecom-aibot__exit_headless_mode(cc_id, project_dir)`
223
185
 
224
- ## 退出流程
186
+ 3. 删除 PermissionRequest hook
225
187
 
226
- **触发词**:「结束微信模式」「我回来了」「我回电脑了」
188
+ 4. 发送退出通知
227
189
 
228
- 1. 调用 `mcp__wecom-aibot__exit_headless_mode(cc_id, project_dir)`
229
- 2. **MCP 自动更新 `.claude/wecom-aibot.json` 的 `wechatMode` 为 `false`**
230
- 3. 从 `.claude/settings.json` 删除 `hooks.PermissionRequest` 字段(如果之前配置了)
231
- 4. 发送 `mcp__wecom-aibot__send_message("【进度】已退出微信模式,恢复终端交互。")`
232
190
  5. 停止轮询
233
191
 
234
- **「我已经回到电脑旁了」** → 先确认:
235
- ```
236
- mcp__wecom-aibot__send_message("【需要确认】是否结束微信模式?回复「是」退出,「否」继续。")
237
- ```
238
-
239
192
  ---
240
193
 
241
- ## 消息格式
242
-
243
- **正确格式**:`【标签】消息内容`
194
+ ## MCP 工具列表
244
195
 
245
- | 标签 | 用途 |
246
- |------|------|
247
- | `【进度】` | 里程碑汇报、收到指令确认 |
248
- | `【完成】` | 任务完成,继续等待 |
249
- | `【问题】` | 需用户决策 |
250
- | `【需要确认】` | 二次确认 |
251
-
252
- **ccId 路由**:
253
- - 消息前缀由 MCP Server 自动添加(格式:`【ccId】`)
254
- - CC 场景下,用户引用回复时需包含 ccId(如 `【cc-1】`)
196
+ | 工具 | 用途 | 参数 |
197
+ |------|------|------|
198
+ | `get_setup_requirements` | 获取配置需求 | 无 |
199
+ | `enter_headless_mode` | 进入微信模式 | cc_id, robot_id, mode, project_dir |
200
+ | `send_message` | 发送消息 | cc_id, content, target_user(可选) |
201
+ | `get_pending_messages` | 获取消息(HTTP模式) | cc_id, timeout_ms |
202
+ | `heartbeat_check` | 心跳检查(HTTP模式) | 无 |
203
+ | `update_heartbeat_job_id` | 保存心跳 job ID(HTTP模式) | cc_id, job_id |
204
+ | `get_skill` | 获取 skill 文件 | 无(远程部署用) |
205
+ | `exit_headless_mode` | 退出微信模式 | cc_id, project_dir |
255
206
 
256
207
  ---
257
208
 
258
- ## 多 CC 消息路由
209
+ ## 运行模式对比
259
210
 
260
- - **单 CC**:消息直接推送
261
- - **多 CC**:用户需引用回复(引用内容含 `【cc-1】` 等标记路由)
211
+ | 特性 | Channel 模式 | HTTP 模式 |
212
+ |------|-------------|----------|
213
+ | 消息接收 | SSE 自动推送 | 主动轮询 |
214
+ | 唤醒方式 | notification 自动 | heartbeat + 轮询 |
215
+ | 启动要求 | `--dangerously-load-development-channels server:wecom-aibot-channel` | 无特殊要求 |
216
+ | 适用 LLM | 仅 Claude | 所有 LLM |