@wecom/wecom-openclaw-plugin 2026.3.25 → 2026.3.30-beta.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.
@@ -70,3 +70,5 @@ export declare const EVENT_ENTER_CHECK_UPDATE = "event.enter_check_update";
70
70
  export declare const CMD_ENTER_EVENT_REPLY = "ww_ai_robot_enter_event";
71
71
  /** WSClient scene 参数:企微 OpenClaw 场景 */
72
72
  export declare const SCENE_WECOM_OPENCLAW = 1;
73
+ /** 合法的模板卡片 card_type 列表 */
74
+ export declare const VALID_CARD_TYPES: string[];
@@ -33,6 +33,22 @@ export interface MessageState {
33
33
  deliverCalled?: boolean;
34
34
  /** 流式回复是否已过期(errcode 846608,>6分钟),需降级为主动发送 */
35
35
  streamExpired?: boolean;
36
+ /** 是否已成功发送过模板卡片 */
37
+ hasTemplateCard?: boolean;
38
+ }
39
+ /** 从文本中提取的模板卡片 */
40
+ export interface ExtractedTemplateCard {
41
+ /** 原始 JSON 对象(已验证 card_type 合法) */
42
+ cardJson: Record<string, unknown>;
43
+ /** card_type 值 */
44
+ cardType: string;
45
+ }
46
+ /** extractTemplateCards 返回值 */
47
+ export interface TemplateCardExtractionResult {
48
+ /** 提取到的合法模板卡片列表 */
49
+ cards: ExtractedTemplateCard[];
50
+ /** 移除卡片代码块后的剩余文本 */
51
+ remainingText: string;
36
52
  }
37
53
  /**
38
54
  * WebSocket 请求消息基础格式
@@ -68,20 +84,20 @@ export interface WeComSubscribeRequest extends WeComRequest {
68
84
  * 企业微信推送消息格式
69
85
  */
70
86
  export interface WeComCallbackMessage {
71
- cmd: WeComCommand.AIBOT_CALLBACK;
87
+ cmd: WeComCommand.AIBOT_CALLBACK | "aibot_event_callback";
72
88
  headers: {
73
89
  req_id: string;
74
90
  };
75
91
  body: {
76
92
  msgid: string;
77
93
  aibotid: string;
78
- chatid: string;
94
+ chatid?: string;
79
95
  chattype: "single" | "group";
80
96
  from: {
81
97
  userid: string;
82
98
  };
83
99
  response_url: string;
84
- msgtype: "text" | "image" | "voice" | "video" | "file" | "stream" | "mixed";
100
+ msgtype: "text" | "image" | "voice" | "video" | "file" | "stream" | "mixed" | "event";
85
101
  text?: {
86
102
  content: string;
87
103
  };
@@ -123,6 +139,22 @@ export interface WeComCallbackMessage {
123
139
  stream?: {
124
140
  id: string;
125
141
  };
142
+ event?: {
143
+ eventtype: string;
144
+ template_card_event?: {
145
+ card_type?: string;
146
+ event_key?: string;
147
+ task_id?: string;
148
+ selected_items?: {
149
+ selected_item?: Array<{
150
+ question_key?: string;
151
+ option_ids?: {
152
+ option_id?: string[];
153
+ };
154
+ }>;
155
+ };
156
+ };
157
+ };
126
158
  };
127
159
  }
128
160
  /**
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 业务错误码检查拦截器
3
+ *
4
+ * 检查 tools/call 返回结果中是否包含需要清理缓存的业务错误码。
5
+ * MCP Server 可能在正常的 JSON-RPC 响应中返回业务层错误,
6
+ * 这些错误被包裹在 result.content[].text 中,需要解析后判断。
7
+ *
8
+ * 此拦截器对所有 call 调用生效。
9
+ */
10
+ import type { CallInterceptor } from "./types.js";
11
+ export declare const bizErrorInterceptor: CallInterceptor;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * MCP call 拦截器注册表与调度入口
3
+ *
4
+ * 所有 call 拦截器在此注册,按注册顺序执行。
5
+ * 新增拦截器只需:
6
+ * 1. 在 interceptors/ 目录下新建文件,实现 CallInterceptor 接口
7
+ * 2. 在下方 interceptors 数组中注册
8
+ *
9
+ * tool.ts 的 handleCall 无需任何改动。
10
+ */
11
+ import type { CallContext } from "./types.js";
12
+ import type { SendJsonRpcOptions } from "../transport.js";
13
+ export type { CallContext, CallInterceptor, BeforeCallOptions } from "./types.js";
14
+ /** resolveBeforeCall 的返回值 */
15
+ export interface ResolvedBeforeCall {
16
+ /** 合并后的 sendJsonRpc 选项(如超时时间) */
17
+ options?: SendJsonRpcOptions;
18
+ /** 替换后的 args(如从本地文件读取的请求体) */
19
+ args?: Record<string, unknown>;
20
+ }
21
+ /**
22
+ * 收集匹配的 beforeCall 配置,合并后返回
23
+ *
24
+ * 合并策略:
25
+ * - timeoutMs: 取所有拦截器返回值中的最大值
26
+ * - args: 后注册的拦截器覆盖前者(一般同一调用只有一个拦截器会返回 args)
27
+ */
28
+ export declare function resolveBeforeCall(ctx: CallContext): Promise<ResolvedBeforeCall>;
29
+ /**
30
+ * 依次执行匹配的 afterCall 拦截器,管道式传递 result
31
+ *
32
+ * 前一个拦截器的返回值作为下一个拦截器的输入。
33
+ * 拦截器若不需要修改 result,应原样返回。
34
+ */
35
+ export declare function runAfterCall(ctx: CallContext, result: unknown): Promise<unknown>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * get_msg_media 响应拦截器
3
+ *
4
+ * 核心逻辑:
5
+ * 1. beforeCall: 设置延长的超时时间(120s),因为 base64 数据可达 ~27MB
6
+ * 2. afterCall: 从 MCP result 的 content[].text 中提取 base64_data,
7
+ * 解码为 Buffer 并通过 saveMediaBuffer 保存到本地媒体目录,
8
+ * 替换响应中的 base64_data 为 local_path,避免大模型被 base64 数据消耗 token
9
+ */
10
+ import type { CallInterceptor } from "./types.js";
11
+ export declare const mediaInterceptor: CallInterceptor;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * smartpage_create 请求拦截器
3
+ *
4
+ * 核心逻辑:
5
+ * smartpage_create 的 pages 数组中,每个 page 可能包含 page_filepath 字段
6
+ * (指向本地 markdown 文件),用于避免在命令行传递大段文本内容。
7
+ * 本拦截器在 beforeCall 阶段遍历 pages 数组,逐个读取 page_filepath
8
+ * 指向的本地文件内容,填入 page_content 字段,并移除 page_filepath。
9
+ *
10
+ * 入参约定:
11
+ * wecom_mcp call doc smartpage_create '{
12
+ * "title": "主页标题",
13
+ * "pages": [
14
+ * {"page_title": "页面1", "page_filepath": "/tmp/page1.md", "content_type": "markdown"},
15
+ * {"page_title": "页面2", "page_filepath": "/tmp/page2.md", "content_type": "markdown"}
16
+ * ]
17
+ * }'
18
+ *
19
+ * 拦截器行为:
20
+ * 1. 检测 args.pages 数组
21
+ * 2. 校验文件大小:单文件不超过 10MB,所有文件总计不超过 20MB
22
+ * 3. 遍历每个 page,若存在 page_filepath 则读取本地文件内容
23
+ * 4. 将文件内容填入 page_content 字段,移除 page_filepath
24
+ * 5. 返回修改后的完整 args
25
+ *
26
+ * 传给 MCP Server 的格式:
27
+ * { "title": "...", "pages": [{"page_title": "...", "page_content": "...", "content_type": "..."}] }
28
+ */
29
+ import type { CallInterceptor } from "./types.js";
30
+ export declare const smartpageCreateInterceptor: CallInterceptor;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * smartpage_get_export_result 响应拦截器
3
+ *
4
+ * 核心逻辑:
5
+ * MCP Server 返回的 smartpage_get_export_result 响应中,当 task_done=true 时
6
+ * 会包含 content 字段(markdown 文本内容)。该内容可能很大,直接返回给 LLM
7
+ * 会消耗大量 token。
8
+ *
9
+ * 本拦截器在 afterCall 阶段:
10
+ * 1. 检测 task_done=true 且存在 content 字段
11
+ * 2. 将 content 保存到本地文件(使用与 msg-media 一致的媒体目录)
12
+ * 3. 用 content_path(文件路径)替换 content 字段
13
+ *
14
+ * 这样 LLM 只看到轻量的文件路径信息,Skill 可通过文件路径读取完整内容。
15
+ */
16
+ import type { CallInterceptor } from "./types.js";
17
+ export declare const smartpageExportInterceptor: CallInterceptor;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * MCP call 拦截器类型定义
3
+ *
4
+ * 拦截器用于在 tools/call 调用前后注入特殊逻辑,
5
+ * 如修改超时配置、变换响应结果等,避免在 tool.ts 中堆积 if/else。
6
+ */
7
+ import type { SendJsonRpcOptions } from "../transport.js";
8
+ /** MCP call 调用的上下文 */
9
+ export interface CallContext {
10
+ /** MCP 品类,对应 mcpConfig 中的 key,如 doc、contact */
11
+ category: string;
12
+ /** 调用的 MCP 方法名 */
13
+ method: string;
14
+ /** 调用 MCP 方法的参数 */
15
+ args: Record<string, unknown>;
16
+ }
17
+ /**
18
+ * beforeCall 返回的选项
19
+ *
20
+ * 扩展 SendJsonRpcOptions,允许拦截器在调用前替换 args(如从本地文件读取请求体)。
21
+ */
22
+ export interface BeforeCallOptions extends SendJsonRpcOptions {
23
+ /** 替换后的 args(可选,不返回则使用原 args) */
24
+ args?: Record<string, unknown>;
25
+ }
26
+ /**
27
+ * call 拦截器接口
28
+ *
29
+ * 每个拦截器通过 match 判断是否对当前调用生效,
30
+ * 生效时可在调用前(beforeCall)和调用后(afterCall)注入逻辑。
31
+ */
32
+ export interface CallInterceptor {
33
+ /** 拦截器名称(用于日志) */
34
+ name: string;
35
+ /**
36
+ * 判断是否对当前调用生效
37
+ *
38
+ * 返回 true 时才会执行 beforeCall / afterCall
39
+ */
40
+ match(ctx: CallContext): boolean;
41
+ /**
42
+ * 在 sendJsonRpc 调用前修改请求选项和参数(可选)
43
+ *
44
+ * 如 get_msg_media 需要延长超时时间,
45
+ * 如 smartpage_create 需要从本地文件读取请求体替换 args。
46
+ * 返回的选项会与其他拦截器的结果合并(timeoutMs 取最大值,args 后者覆盖前者)。
47
+ */
48
+ beforeCall?(ctx: CallContext): BeforeCallOptions | Promise<BeforeCallOptions> | undefined;
49
+ /**
50
+ * 在 sendJsonRpc 返回后处理/变换结果(可选)
51
+ *
52
+ * 多个拦截器的 afterCall 按注册顺序管道式执行,
53
+ * 前一个的返回值作为下一个的输入。
54
+ */
55
+ afterCall?(ctx: CallContext, result: unknown): Promise<unknown> | unknown;
56
+ }
@@ -9,6 +9,7 @@ export interface MessageBody {
9
9
  chatid?: string;
10
10
  chattype: "single" | "group";
11
11
  from: {
12
+ corpid?: string;
12
13
  userid: string;
13
14
  };
14
15
  response_url?: string;
@@ -56,6 +57,22 @@ export interface MessageBody {
56
57
  aeskey?: string;
57
58
  };
58
59
  };
60
+ event?: {
61
+ eventtype?: string;
62
+ template_card_event?: {
63
+ card_type?: string;
64
+ event_key?: string;
65
+ task_id?: string;
66
+ selected_items?: {
67
+ selected_item?: Array<{
68
+ question_key?: string;
69
+ option_ids?: {
70
+ option_id?: string[];
71
+ };
72
+ }>;
73
+ };
74
+ };
75
+ };
59
76
  }
60
77
  export interface ParsedMessageContent {
61
78
  textParts: string[];
@@ -66,7 +83,7 @@ export interface ParsedMessageContent {
66
83
  quoteContent: string | undefined;
67
84
  }
68
85
  /**
69
- * 解析消息内容(支持单条消息、图文混排和引用消息)
86
+ * 解析消息内容(支持单条消息、图文混排、事件回调和引用消息)
70
87
  * @returns 提取的文本数组、图片URL数组和引用消息内容
71
88
  */
72
89
  export declare function parseMessageContent(body: MessageBody): ParsedMessageContent;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 模板卡片解析器
3
+ *
4
+ * 从 LLM 回复文本中提取 markdown JSON 代码块,验证其是否为合法的企业微信模板卡片,
5
+ * 返回提取到的卡片列表和剩余文本。
6
+ *
7
+ * 同时提供 maskTemplateCardBlocks 函数,用于在流式中间帧中隐藏正在构建的卡片代码块,
8
+ * 避免 JSON 源码暴露给终端用户。
9
+ */
10
+ import type { TemplateCardExtractionResult } from "./interface.js";
11
+ /**
12
+ * 从文本中提取模板卡片 JSON 代码块
13
+ *
14
+ * 匹配规则:
15
+ * 1. 匹配所有 ```json ... ``` 或 ``` ... ``` 格式的代码块
16
+ * 2. 尝试 JSON.parse 解析代码块内容
17
+ * 3. 检查解析结果中是否包含合法的 card_type 字段
18
+ * 4. 合法的卡片从原文中移除,不合法的保留
19
+ *
20
+ * @param text - LLM 回复的完整文本
21
+ * @returns 提取结果,包含卡片列表和剩余文本
22
+ */
23
+ export declare function extractTemplateCards(text: string, log?: (...args: any[]) => void): TemplateCardExtractionResult;
24
+ /**
25
+ * 遮罩文本中的模板卡片代码块(用于流式中间帧展示)
26
+ *
27
+ * 在 LLM 流式输出过程中,累积文本可能包含:
28
+ * 1. 已闭合的模板卡片 JSON 代码块 → 替换为友好提示文本
29
+ * 2. 正在构建中的未闭合代码块 → 截断隐藏,避免 JSON 源码暴露
30
+ *
31
+ * 此函数仅做文本替换,不做 JSON 解析验证(中间帧性能优先)。
32
+ * 只要代码块内容中出现 "card_type" 关键词就认为是模板卡片并遮罩。
33
+ *
34
+ * @param text - 当前累积文本
35
+ * @returns 遮罩后的展示文本
36
+ */
37
+ export declare function maskTemplateCardBlocks(text: string, log?: (...args: any[]) => void): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wecom/wecom-openclaw-plugin",
3
- "version": "2026.3.25",
3
+ "version": "2026.3.30-beta.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wecom-doc-manager
3
- description: 企业微信文档管理技能。提供文档的创建、读取和编辑能力,支持通过 docid 或文档 URL 操作企业微信文档(doc_type=3)和智能表格(doc_type=10)。适用场景:(1) 以 Markdown 格式导出获取文档完整内容(异步轮询) (2) 新建文档或智能表格 (3) 用 Markdown 格式覆写文档内容。当用户需要查看文档内容、创建新文档、编辑文档正文时触发此 Skill。
3
+ description: 企业微信文档管理技能。提供文档和智能主页的创建、读取和编辑能力。支持通过 docid 或文档 URL 操作企业微信文档(doc_type=3)和智能表格(doc_type=10),以及创建智能主页和导出其内容。适用场景:(1) 以 Markdown 格式导出获取文档完整内容(异步轮询) (2) 新建文档或智能表格 (3) 用 Markdown 格式覆写文档内容 (4) 将本地 Markdown 文件创建为智能主页 (5) 异步导出智能主页内容为 Markdown 文件。当用户需要查看文档内容、创建新文档、编辑文档正文、创建智能主页、或获取智能主页内容时触发此 Skill。
4
4
  ---
5
5
 
6
6
  # 企业微信文档管理
@@ -9,11 +9,27 @@ description: 企业微信文档管理技能。提供文档的创建、读取和
9
9
 
10
10
  > ⚠️ **前置条件**:首次调用 `wecom_mcp` 前,必须按 `wecom-preflight` 技能执行前置条件检查,确保工具已加入白名单。
11
11
 
12
- 管理企业微信文档的创建、读取和编辑。所有接口支持通过 `docid` 或 `url` 二选一定位文档。
12
+ 管理企业微信文档和智能主页的创建、读取和编辑。文档接口支持通过 `docid` 或 `url` 二选一定位文档。
13
+
14
+ ## URL 品类识别与接口路由
15
+
16
+ 企业微信文档有三种品类,**URL 格式不同,读取内容所用的接口也不同**,切勿混用:
17
+
18
+ | URL 模式 | 品类 | 读取内容接口 |
19
+ |---|---|---|
20
+ | `https://doc.weixin.qq.com/doc/*` | **文档**(doc_type=3) | `get_doc_content` |
21
+ | `https://doc.weixin.qq.com/smartsheet/*` | **智能表格**(doc_type=10) | `get_doc_content` |
22
+ | `https://doc.weixin.qq.com/smartpage/*` | **智能主页** | `smartpage_export_task` → `smartpage_get_export_result` |
23
+
24
+ **判断规则**:
25
+ - URL 路径以 `/doc/*` 开头 → 文档 → 用 `get_doc_content`
26
+ - URL 路径以 `/smartsheet/*` 开头 → 智能表格 → 用 `get_doc_content`
27
+ - URL 路径以 `/smartpage/*` 开头 → 智能主页 → 用 `smartpage_export_task`
28
+
13
29
 
14
30
  ## 调用方式
15
31
 
16
- 通过 `wecom_mcp` tool 调用,品类为 `doc`:
32
+ 通过 `wecom_mcp` tool 调用,子工具名为 `doc`:
17
33
 
18
34
  使用 `wecom_mcp` tool 调用 `wecom_mcp call doc <tool_name> '<json_params>'` 调用指定技能
19
35
 
@@ -28,6 +44,22 @@ description: 企业微信文档管理技能。提供文档的创建、读取和
28
44
 
29
45
  当 `errcode` 不为 `0` 时,说明接口调用失败,可重试 1 次;若仍失败,将 `errcode` 和 `errmsg` 展示给用户。
30
46
 
47
+ ### 特殊错误码
48
+
49
+ | errcode | errmsg | 含义 | 处理方式 |
50
+ |---------|--------|------|----------|
51
+ | `851002` | `incompatible doc type` | 文档品类与所调用的接口不匹配 | 换用另一种导出方式重试:若当前使用 `get_doc_content` 则改用 `smartpage_export_task`,若当前使用 `smartpage_export_task` 则改用 `get_doc_content` |
52
+
53
+ ## 文档
54
+
55
+ 适用品类:文档(doc_type=3)和智能表格(doc_type=10)
56
+ 适用 URL:`/doc/*`、`/smartsheet/*`
57
+
58
+ 适用场景:
59
+ 1. 以 Markdown 格式导出获取文档完整内容(异步轮询)
60
+ 2. 新建文档(doc_type=3)或智能表格(doc_type=10)
61
+ 3. 用 Markdown 格式覆写文档内容
62
+
31
63
  ### get_doc_content
32
64
 
33
65
  获取文档完整内容数据,只能以 Markdown 格式返回。采用**异步轮询机制**:首次调用无需传 `task_id`,接口返回 `task_id`;若 `task_done` 为 false,需携带该 `task_id` 再次调用,直到 `task_done` 为 true 时返回完整内容。
@@ -57,8 +89,55 @@ description: 企业微信文档管理技能。提供文档的创建、读取和
57
89
 
58
90
  参见 [API 详情](references/api-edit-doc-content.md)。
59
91
 
92
+ ## 智能主页
93
+
94
+ 适用品类:智能主页
95
+ 适用 URL:`/smartpage/*`
96
+
97
+ 适用场景:
98
+ 1. 将本地 Markdown 文件创建为智能主页
99
+ 2. 异步导出智能主页内容为 Markdown 文件
100
+
101
+ ### smartpage_create
102
+
103
+ 创建智能主页,支持传入标题和多个子页面。每个子页面可指定标题、内容类型和本地文件路径。响应透传 mcp 回包,返回 docid 和 url。
104
+
105
+ - 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc smartpage_create '{"title": "项目概览", "pages": [{"page_title": "需求文档", "content_type": 1, "page_filepath": "/path/to/requirements.md"}]}'`
106
+
107
+ **注意**:
108
+ - `content_type` **必须与文件实际内容匹配**:`.md` 文件或包含 Markdown 语法的内容必须传 `1`(Markdown),仅纯文本才传 `0`。绝大多数场景应传 `1`
109
+ - docid 仅在创建时返回,需妥善保存
110
+ - 每个子页面的 Markdown 文件大小不得超过 **10MB**,超过会导致创建失败。如果文件过大,需先拆分为多个子页面再创建
111
+
112
+ 参见 [API 详情](references/api-smartpage-create.md)。
113
+
114
+ ### smartpage_export_task
115
+
116
+ 发起智能主页内容导出任务(异步)。传入 docid 和 content_type,返回 task_id。这是异步导出的第一步,需配合 `smartpage_get_export_result` 轮询获取导出结果。
117
+
118
+ - 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc smartpage_export_task '{"docid": "DOCID", "content_type": 1}'`
119
+
120
+ 参见 [API 详情](references/api-smartpage-export-task.md)。
121
+
122
+ ### smartpage_get_export_result
123
+
124
+ 查询智能主页导出任务进度。传入 task_id 进行轮询,当 `task_done` 为 `true` 时返回 `content_filepath`(导出内容的本地文件路径)。
125
+
126
+ - 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc smartpage_get_export_result '{"task_id": "TASK_ID"}'`
127
+
128
+ 当 `task_done` 为 `true` 时,使用 Read 工具读取 `content_filepath` 指向的文件即可获取导出的 Markdown 内容。
129
+
130
+ 参见 [API 详情](references/api-smartpage-get-export-result.md)。
131
+
60
132
  ## 典型工作流
61
133
 
62
- 1. **读取文档** → 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc get_doc_content '{"docid": "DOCID", "type": 2}'`,若 `task_done` 为 false 则携带 `task_id` 继续轮询
134
+ > **关键提示**:读取内容前先看 URL 判断品类。`/doc/` 或 `/smartsheet/` → `get_doc_content`;`/smartpage/` → `smartpage_export_task`。
135
+
136
+ 1. **读取文档/智能表格内容**(URL 含 `/doc/` 或 `/smartsheet/`) → 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc get_doc_content '{"docid": "DOCID", "type": 2}'`,若 `task_done` 为 false 则携带 `task_id` 继续轮询
63
137
  2. **创建新文档** → 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc create_doc '{"doc_type": 3, "doc_name": "文档名"}'`,保存返回的 docid
64
138
  3. **编辑文档** → 先 get_doc_content 了解当前内容,再 edit_doc_content 覆写
139
+ 4. **创建智能主页** → 使用 `wecom_mcp` tool 调用 `wecom_mcp call doc smartpage_create '{"title": "标题", "pages": [{"page_title": "子页面", "content_type": 1, "page_filepath": "/path/to/file.md"}]}'`,保存返回的 docid
140
+ 5. **获取智能主页内容**(URL 含 `/smartpage/`,异步两步):
141
+ - **第一步**:使用 `wecom_mcp` tool 调用 `wecom_mcp call doc smartpage_export_task '{"docid": "DOCID", "content_type": 1}'`,获取 `task_id`
142
+ - **第二步**:使用 `wecom_mcp` tool 调用 `wecom_mcp call doc smartpage_get_export_result '{"task_id": "TASK_ID"}'`,若 `task_done` 为 `false` 则继续轮询,直到 `task_done` 为 `true`
143
+ - **第三步**:使用 Read 工具读取 `content_filepath` 指向的本地文件,获取 Markdown 内容
@@ -0,0 +1,108 @@
1
+ # smartpage_create API
2
+
3
+ 创建智能主页。支持传入多个子页面,每个子页面可指定标题、内容类型和文件路径。创建成功后返回文档访问链接和 docid。
4
+
5
+ ## 技能定义
6
+
7
+ ```json
8
+ {
9
+ "name": "smartpage_create",
10
+ "description": "创建智能主页。支持传入标题和多个子页面配置,每个子页面可指定标题、内容类型(Text/Markdown)和本地文件路径。创建成功后返回 docid 和 url(docid 仅在创建时返回,需妥善保存)。",
11
+ "inputSchema": {
12
+ "properties": {
13
+ "title": {
14
+ "description": "智能主页标题",
15
+ "title": "Title",
16
+ "type": "string"
17
+ },
18
+ "pages": {
19
+ "description": "子页面列表",
20
+ "title": "Pages",
21
+ "type": "array",
22
+ "items": {
23
+ "type": "object",
24
+ "properties": {
25
+ "page_title": {
26
+ "description": "子页面标题",
27
+ "title": "Page Title",
28
+ "type": "string"
29
+ },
30
+ "content_type": {
31
+ "description": "内容类型。1: Markdown(包含Markdown语法的内容),0: Text(纯文本,不含任何Markdown语法)",
32
+ "enum": [0, 1],
33
+ "default": 1,
34
+ "title": "Content Type",
35
+ "type": "integer"
36
+ },
37
+ "page_filepath": {
38
+ "description": "子页面内容对应的本地文件路径",
39
+ "title": "Page Filepath",
40
+ "type": "string"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ },
46
+ "required": ["pages"],
47
+ "title": "smartpage_createArguments",
48
+ "type": "object"
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## 参数说明
54
+
55
+ | 参数 | 类型 | 必填 | 说明 |
56
+ |---|---|---|---|
57
+ | title | string | 否 | 智能主页标题 |
58
+ | pages | array | 是 | 子页面列表 |
59
+ | pages[].page_title | string | 否 | 子页面标题 |
60
+ | pages[].content_type | integer | 否 | 内容类型:1-Markdown,0-Text(纯文本)。**默认应传 1**,仅纯文本内容才传 0 |
61
+ | pages[].page_filepath | string | 否 | 子页面内容对应的本地文件路径 |
62
+
63
+ ## ContentType 枚举
64
+
65
+ | 值 | 含义 | 适用场景 |
66
+ |---|---|---|
67
+ | 1 | Markdown | 文件内容包含 Markdown 语法(标题、列表、链接、代码块等) |
68
+ | 0 | Text(纯文本) | 文件内容为纯文本,不含任何 Markdown 语法 |
69
+
70
+
71
+ ## 请求示例
72
+
73
+ ```json
74
+ {
75
+ "title": "项目概览",
76
+ "pages": [
77
+ {
78
+ "page_title": "需求文档",
79
+ "content_type": 1,
80
+ "page_filepath": "/path/to/requirements.md"
81
+ },
82
+ {
83
+ "page_title": "设计说明",
84
+ "content_type": 1,
85
+ "page_filepath": "/path/to/design.md"
86
+ }
87
+ ]
88
+ }
89
+ ```
90
+
91
+ ## 响应示例
92
+
93
+ ```json
94
+ {
95
+ "errcode": 0,
96
+ "errmsg": "ok",
97
+ "docid": "DOCID",
98
+ "url": "https://doc.weixin.qq.com/smartpage/a1_xxxxxx"
99
+ }
100
+ ```
101
+
102
+ ## 注意事项
103
+
104
+ - 响应透传 mcp 回包
105
+ - `docid` 仅在创建时返回,后续无法再获取,务必保存
106
+ - `page_filepath` 指向本地文件,需确保文件存在且可读
107
+ - **`content_type` 必须与文件实际内容格式匹配**:`.md` 文件或包含 Markdown 语法的内容必须传 `1`,不要传 `0`
108
+ - 每个子页面的 Markdown 文件大小不得超过 **10MB**,超过会导致创建失败;如果文件过大,需先拆分为多个子页面
@@ -0,0 +1,62 @@
1
+ # smartpage_export_task API
2
+
3
+ 发起智能主页内容导出任务。该接口为异步操作的第一步,调用后返回 `task_id`,需配合 `smartpage_get_export_result` 轮询获取导出结果。
4
+
5
+ ## 技能定义
6
+
7
+ ```json
8
+ {
9
+ "name": "smartpage_export_task",
10
+ "description": "发起智能主页内容导出任务(异步)。传入 docid 和 content_type,返回 task_id。需配合 smartpage_get_export_result 轮询查询导出进度,直到任务完成后获取导出文件路径。",
11
+ "inputSchema": {
12
+ "properties": {
13
+ "docid": {
14
+ "description": "智能主页的 docid,由 smartpage_create 返回",
15
+ "title": "Doc ID",
16
+ "type": "string"
17
+ },
18
+ "content_type": {
19
+ "description": "导出内容格式。0: Text,1: Markdown",
20
+ "enum": [0, 1],
21
+ "title": "Content Type",
22
+ "type": "integer"
23
+ }
24
+ },
25
+ "required": ["docid", "content_type"],
26
+ "title": "smartpage_export_taskArguments",
27
+ "type": "object"
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## 参数说明
33
+
34
+ | 参数 | 类型 | 必填 | 说明 |
35
+ |---|---|---|---|
36
+ | docid | string | 是 | 智能主页的 docid |
37
+ | content_type | integer | 是 | 导出内容格式:0-Text,1-Markdown |
38
+
39
+ ## 请求示例
40
+
41
+ ```json
42
+ {
43
+ "docid": "DOCID",
44
+ "content_type": 1
45
+ }
46
+ ```
47
+
48
+ ## 响应示例
49
+
50
+ ```json
51
+ {
52
+ "errcode": 0,
53
+ "errmsg": "ok",
54
+ "task_id": "TASK_ID"
55
+ }
56
+ ```
57
+
58
+ ## 注意事项
59
+
60
+ - 这是异步操作的第一步,调用后仅返回 `task_id`
61
+ - 获取到 `task_id` 后,需调用 `smartpage_get_export_result` 轮询导出进度
62
+ - `content_type` 建议使用 `1`(Markdown)以获取可编辑的文本格式