@vocmarket/voc-skill 0.3.15 → 0.3.17

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.
Files changed (33) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.mcp.json +2 -2
  3. package/README.md +5 -0
  4. package/bin/claude-voc.js +22 -0
  5. package/docs/capability-map.md +6 -0
  6. package/docs/npm-packaging-notes.md +185 -50
  7. package/install.js +5 -0
  8. package/mcp/catalog/voc-social-endpoints.json +143 -0
  9. package/mcp/src/core/api-catalog.js +91 -0
  10. package/mcp/src/core/evidence-quality.js +1 -1
  11. package/mcp/src/core/payment-links.js +20 -1
  12. package/mcp/src/features/douyin-trend/live-collector.js +1 -1
  13. package/mcp/src/features/fmode-image-analysis/image-analysis.js +427 -0
  14. package/mcp/src/providers/douyin-api.js +55 -30
  15. package/mcp/src/providers/voc-gateway.js +162 -0
  16. package/mcp/src/providers/xiaohongshu-api.js +44 -22
  17. package/mcp/src/server.js +266 -99
  18. package/mcp/src/tools/douyin-trend-run.js +88 -18
  19. package/mcp/src/tools/fmode-image-analysis.js +69 -0
  20. package/mcp/src/tools/voc-api-catalog-run.js +313 -0
  21. package/mcp/src/tools/xiaohongshu-trend-run.js +84 -10
  22. package/package.json +6 -3
  23. package/scripts/acceptance.js +91 -0
  24. package/scripts/fmode-image-analysis-smoke.js +108 -0
  25. package/scripts/smoke-mcp.js +62 -0
  26. package/scripts/smoke-package.js +19 -7
  27. package/skill-package-manifest.json +12 -4
  28. package/skills/douyin-trend-intelligence/SKILL.md +19 -3
  29. package/skills/douyin-trend-intelligence/references/live-mode.md +7 -6
  30. package/skills/fmode-image-analysis/SKILL.md +106 -0
  31. package/skills/fmode-image-analysis/agents/openai.yaml +4 -0
  32. package/skills/voc-api-catalog/SKILL.md +55 -0
  33. package/skills/xiaohongshu-trend-intelligence/SKILL.md +16 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "voc-intelligence",
3
- "description": "VOC intelligence skills for Claude Code: end-to-end VOC business workflows, Xiaohongshu and Douyin trend reports, live social VOC collection, token/recharge checks, evidence-card outputs, prioritized issue pools, single-problem deep dives, competitor maps, 7-day content plans, VOC-backed speaking script co-creation, boss/operator action plans, and multi-turn memory.",
4
- "version": "0.3.15",
3
+ "description": "VOC intelligence skills for Claude Code: end-to-end VOC business workflows, Xiaohongshu and Douyin trend reports, live social VOC collection, Fmode Doubao image analysis, token/recharge checks, evidence-card outputs, prioritized issue pools, single-problem deep dives, competitor maps, 7-day content plans, VOC-backed speaking script co-creation, boss/operator action plans, and multi-turn memory.",
4
+ "version": "0.3.17",
5
5
  "author": {
6
6
  "name": "nkkj-BrainHack"
7
7
  }
package/.mcp.json CHANGED
@@ -3,9 +3,9 @@
3
3
  "voc": {
4
4
  "command": "node",
5
5
  "args": [
6
- "E:\\workspace\\openclaw-voc-skill\\claude-code-voc-intelligence\\mcp\\src\\server.js"
6
+ "E:\\workspace\\openclaw-voc-skill\\claude-code\\claude-code-voc-intelligence\\mcp\\src\\server.js"
7
7
  ],
8
- "cwd": "E:\\workspace\\openclaw-voc-skill\\claude-code-voc-intelligence"
8
+ "cwd": "E:\\workspace\\openclaw-voc-skill\\claude-code\\claude-code-voc-intelligence"
9
9
  }
10
10
  }
11
11
  }
package/README.md CHANGED
@@ -110,6 +110,7 @@ npx --yes @vocmarket/voc-skill@latest workspace --smoke
110
110
  .claude/skills/voc-speaking-script/SKILL.md
111
111
  .claude/skills/voc-competitor-map/SKILL.md
112
112
  .claude/skills/voc-business-workflow/SKILL.md
113
+ .claude/skills/fmode-image-analysis/SKILL.md
113
114
  .claude/plugins/voc-intelligence
114
115
  ```
115
116
 
@@ -186,9 +187,11 @@ npx --yes @vocmarket/voc-skill@latest install --smoke
186
187
  - `voc-speaking-script`
187
188
  - `voc-competitor-map`
188
189
  - `voc-business-workflow`
190
+ - `fmode-image-analysis`
189
191
 
190
192
  MCP 工具:
191
193
 
194
+ - `fmode_image_analysis`
192
195
  - `voc_business_workflow_run`
193
196
  - `voc_xiaohongshu_trend_run`
194
197
  - `voc_xiaohongshu_preference_update`
@@ -207,6 +210,8 @@ MCP 工具:
207
210
  ```powershell
208
211
  npm --prefix claude-code-voc-intelligence run xhs:sample
209
212
  npm --prefix claude-code-voc-intelligence run dy:sample
213
+ npm --prefix claude-code-voc-intelligence run fmode:image:smoke
214
+ claude-voc image --image-path E:\workspace\example\screenshot.png --prompt "识别截图里的文字、主体和风险点"
210
215
  npm --prefix claude-code-voc-intelligence run voc:issue-pool
211
216
  npm --prefix claude-code-voc-intelligence run voc:deep-dive
212
217
  npm --prefix claude-code-voc-intelligence run voc:business-workflow
package/bin/claude-voc.js CHANGED
@@ -15,6 +15,7 @@ const EXCLUDED_DIRS = new Set([
15
15
  'node_modules',
16
16
  'memory',
17
17
  'outputs',
18
+ '.npm-cache-acceptance',
18
19
  '.tmp',
19
20
  '.git',
20
21
  '.claude'
@@ -36,6 +37,7 @@ function usage() {
36
37
  ' claude-voc install --workspace --smoke',
37
38
  ' claude-voc check',
38
39
  ' claude-voc smoke',
40
+ ' claude-voc image --image-path <file> --prompt <text>',
39
41
  ' claude-voc path',
40
42
  '',
41
43
  'npx:',
@@ -181,6 +183,11 @@ function assertInstalled(targetDir) {
181
183
  'skills/voc-speaking-script/SKILL.md',
182
184
  'skills/voc-competitor-map/SKILL.md',
183
185
  'skills/voc-business-workflow/SKILL.md',
186
+ 'skills/fmode-image-analysis/SKILL.md',
187
+ 'skills/voc-api-catalog/SKILL.md',
188
+ 'mcp/src/tools/fmode-image-analysis.js',
189
+ 'mcp/src/tools/voc-api-catalog-run.js',
190
+ 'mcp/catalog/voc-social-endpoints.json',
184
191
  'mcp/src/server.js'
185
192
  ];
186
193
  const missing = required.filter(rel => !fs.existsSync(path.join(targetDir, rel)));
@@ -641,6 +648,8 @@ function writeWorkspaceSkillEntries(targetDir) {
641
648
  const speakingScriptSkillDir = path.join(WORKSPACE_ROOT, '.claude', 'skills', 'voc-speaking-script');
642
649
  const competitorMapSkillDir = path.join(WORKSPACE_ROOT, '.claude', 'skills', 'voc-competitor-map');
643
650
  const businessWorkflowSkillDir = path.join(WORKSPACE_ROOT, '.claude', 'skills', 'voc-business-workflow');
651
+ const fmodeImageSkillDir = path.join(WORKSPACE_ROOT, '.claude', 'skills', 'fmode-image-analysis');
652
+ const apiCatalogSkillDir = path.join(WORKSPACE_ROOT, '.claude', 'skills', 'voc-api-catalog');
644
653
  ensureDir(xhsSkillDir);
645
654
  ensureDir(douyinSkillDir);
646
655
  ensureDir(issuePoolSkillDir);
@@ -649,6 +658,8 @@ function writeWorkspaceSkillEntries(targetDir) {
649
658
  ensureDir(speakingScriptSkillDir);
650
659
  ensureDir(competitorMapSkillDir);
651
660
  ensureDir(businessWorkflowSkillDir);
661
+ ensureDir(fmodeImageSkillDir);
662
+ ensureDir(apiCatalogSkillDir);
652
663
  fs.writeFileSync(path.join(xhsSkillDir, 'SKILL.md'), workspaceSkillText(targetDir), 'utf8');
653
664
  fs.writeFileSync(path.join(douyinSkillDir, 'SKILL.md'), workspaceDouyinSkillText(targetDir), 'utf8');
654
665
  fs.writeFileSync(path.join(issuePoolSkillDir, 'SKILL.md'), workspaceIssuePoolSkillText(targetDir), 'utf8');
@@ -657,6 +668,8 @@ function writeWorkspaceSkillEntries(targetDir) {
657
668
  fs.writeFileSync(path.join(speakingScriptSkillDir, 'SKILL.md'), workspaceSpeakingScriptSkillText(targetDir), 'utf8');
658
669
  fs.writeFileSync(path.join(competitorMapSkillDir, 'SKILL.md'), workspaceCompetitorMapSkillText(targetDir), 'utf8');
659
670
  fs.writeFileSync(path.join(businessWorkflowSkillDir, 'SKILL.md'), workspaceBusinessWorkflowSkillText(targetDir), 'utf8');
671
+ fs.copyFileSync(path.join(targetDir, 'skills', 'fmode-image-analysis', 'SKILL.md'), path.join(fmodeImageSkillDir, 'SKILL.md'));
672
+ fs.copyFileSync(path.join(targetDir, 'skills', 'voc-api-catalog', 'SKILL.md'), path.join(apiCatalogSkillDir, 'SKILL.md'));
660
673
  }
661
674
 
662
675
  function writeWorkspaceActivation(targetDir) {
@@ -672,6 +685,8 @@ function writeWorkspaceActivation(targetDir) {
672
685
  console.log('Wrote workspace skill entry: .\\.claude\\skills\\voc-speaking-script\\SKILL.md');
673
686
  console.log('Wrote workspace skill entry: .\\.claude\\skills\\voc-competitor-map\\SKILL.md');
674
687
  console.log('Wrote workspace skill entry: .\\.claude\\skills\\voc-business-workflow\\SKILL.md');
688
+ console.log('Wrote workspace skill entry: .\\.claude\\skills\\fmode-image-analysis\\SKILL.md');
689
+ console.log('Wrote workspace skill entry: .\\.claude\\skills\\voc-api-catalog\\SKILL.md');
675
690
  }
676
691
 
677
692
  function printNextSteps(targetDir) {
@@ -692,6 +707,7 @@ function printNextSteps(targetDir) {
692
707
  console.log(' .\\.claude\\skills\\voc-speaking-script\\SKILL.md');
693
708
  console.log(' .\\.claude\\skills\\voc-competitor-map\\SKILL.md');
694
709
  console.log(' .\\.claude\\skills\\voc-business-workflow\\SKILL.md');
710
+ console.log(' .\\.claude\\skills\\fmode-image-analysis\\SKILL.md');
695
711
  console.log(' .\\.claude\\plugins\\voc-intelligence');
696
712
  console.log('');
697
713
  console.log('Restart the VSCode Claude Code session if it was already open.');
@@ -769,6 +785,12 @@ function printPath(opts) {
769
785
  }
770
786
 
771
787
  function main() {
788
+ const directCommand = process.argv[2];
789
+ if (directCommand === 'image' || directCommand === 'fmode-image') {
790
+ run(process.execPath, ['mcp/src/tools/fmode-image-analysis.js', ...process.argv.slice(3)], SOURCE_ROOT);
791
+ return;
792
+ }
793
+
772
794
  const opts = parseArgs(process.argv.slice(2));
773
795
  if (opts.help || opts.command === 'help') {
774
796
  console.log(usage());
@@ -22,6 +22,12 @@
22
22
  | 选中一条内容继续改口播 | `voc-speaking-script` | `voc_speaking_script_run` | 60 秒稿、30 秒稿、提词器版、改稿反馈、定稿记忆 |
23
23
  | 下轮继续优化 | 同一 skill | 带同一 `memory`,或带 project/industry/scenario/audience 让工具自动分桶 | 应用历史记忆,避免从零开始 |
24
24
 
25
+ ## Fmode Image Analysis Add-on
26
+
27
+ | 能力 | 推荐入口 | MCP 工具 | 输出重点 |
28
+ | --- | --- | --- | --- |
29
+ | 图片识别/截图分析 | `fmode-image-analysis` | `fmode_image_analysis` | 使用平台用户 token 调用 Fmode Doubao vision,默认模型 `doubao-seed-2-0-pro-260215` |
30
+
25
31
  ## 技能入口
26
32
 
27
33
  ### `voc-business-workflow`
@@ -1,93 +1,228 @@
1
- # Claude Code VOC 技能包 npm 打包经验
1
+ # Claude Code VOC 技能包 npm 打包与发布说明
2
2
 
3
- ## 目标
3
+ ## 当前包名
4
4
 
5
- 同一个技能包同时支持两种交付:
5
+ VOC 技能包当前对外 npm 包名:
6
6
 
7
- - 链接下载 zip:适合不会 npm 的客户,解压后执行 `node install.js`。
8
- - npm/npx 安装:适合教学、远程交付和批量升级。
7
+ ```bash
8
+ @vocmarket/voc-skill
9
+ ```
9
10
 
10
- 推荐命令:
11
+ CLI 命令保持不变:
11
12
 
12
13
  ```bash
13
- npm install -g @vocmarket/voc-skill
14
- claude-voc install
14
+ claude-voc
15
15
  ```
16
16
 
17
- 免全局安装:
17
+ 插件安装目录也保持不变:
18
18
 
19
- ```bash
20
- npx @vocmarket/voc-skill install
19
+ ```text
20
+ voc-intelligence
21
21
  ```
22
22
 
23
- ## 关键设计
23
+ 这样做的目的:对外包名更短、更适合课程和市场传播;同时不破坏已经沉淀好的 Claude Code 插件目录、MCP server 名称和 skill 入口。
24
24
 
25
- `npx` 下载的包可能在临时缓存里,不能直接让 Claude Code 长期加载这个临时目录。
25
+ ## 用户安装方式
26
26
 
27
- 所以 `claude-voc install` 会把包复制到固定目录:
27
+ 推荐给 VSCode Claude Code 使用工作区安装:
28
+
29
+ ```powershell
30
+ npx --yes @vocmarket/voc-skill@latest workspace --smoke
31
+ ```
32
+
33
+ 工作区安装会写入:
28
34
 
29
35
  ```text
30
- ~/.claude/plugins/voc-intelligence
36
+ .\.mcp.json
37
+ .\.claude\plugins\voc-intelligence
38
+ .\.claude\skills\xiaohongshu-trend-intelligence\SKILL.md
39
+ .\.claude\skills\douyin-trend-intelligence\SKILL.md
40
+ .\.claude\skills\voc-issue-pool\SKILL.md
41
+ .\.claude\skills\voc-problem-deep-dive\SKILL.md
42
+ .\.claude\skills\voc-content-plan\SKILL.md
43
+ .\.claude\skills\voc-speaking-script\SKILL.md
44
+ .\.claude\skills\voc-competitor-map\SKILL.md
45
+ .\.claude\skills\voc-business-workflow\SKILL.md
31
46
  ```
32
47
 
33
- 然后在该目录安装运行依赖,并输出:
48
+ 全局安装:
34
49
 
35
- ```bash
36
- claude --plugin-dir "<安装目录>"
50
+ ```powershell
51
+ npm install -g @vocmarket/voc-skill
52
+ claude-voc install
37
53
  ```
38
54
 
39
- 这样全局安装和 npx 安装的结果一致,后续也便于升级。
55
+ npx 免全局安装:
40
56
 
41
- ## package.json 要点
57
+ ```powershell
58
+ npx --yes @vocmarket/voc-skill@latest install
59
+ ```
42
60
 
43
- - npm 包名使用 scoped package:`@vocmarket/voc-skill`
44
- - CLI 入口:
61
+ ## package.json 要点
45
62
 
46
63
  ```json
47
64
  {
65
+ "name": "@vocmarket/voc-skill",
48
66
  "bin": {
49
67
  "claude-voc": "bin/claude-voc.js"
68
+ },
69
+ "publishConfig": {
70
+ "access": "public"
50
71
  }
51
72
  }
52
73
  ```
53
74
 
54
- - `files` 必须显式包含:
55
- - `.claude-plugin/`
56
- - `.mcp.json`
57
- - `bin/`
58
- - `skills/`
59
- - `mcp/`
60
- - `memory-templates/`
61
- - `docs/`
62
- - `install.js`
63
- - `skill-package-manifest.json`
75
+ `files` 必须显式包含:
76
+
77
+ - `.claude-plugin/`
78
+ - `.mcp.json`
79
+ - `bin/`
80
+ - `docs/`
81
+ - `install.js`
82
+ - `mcp/`
83
+ - `memory-templates/`
84
+ - `package.json`
85
+ - `scripts/`
86
+ - `skill-package-manifest.json`
87
+ - `skills/`
88
+
89
+ 不要发布:
90
+
91
+ - `.env`
92
+ - `.env.local`
93
+ - `.npmrc`
94
+ - `node_modules/`
95
+ - `memory/`
96
+ - `outputs/`
97
+ - 本地 smoke 临时目录
98
+
99
+ ## 发布前验证
100
+
101
+ 在仓库根目录执行:
102
+
103
+ ```powershell
104
+ npm --prefix claude-code/claude-code-voc-intelligence run mcp:smoke
105
+ npm --prefix claude-code/claude-code-voc-intelligence run smoke:package
106
+ npm run claude-voc:acceptance
107
+ npm run claude-voc:build
108
+ npm run claude-voc:npm-pack
109
+ ```
64
110
 
65
- ## 验证命令
111
+ `npm run claude-voc:npm-pack` 会做三类验证:
66
112
 
67
- 根目录执行:
113
+ 1. 校验 npm package metadata、CLI 入口和必要文件。
114
+ 2. 生成 `dist/npm/vocmarket-voc-skill-<version>.tgz`。
115
+ 3. 在临时目录模拟 npm install、npx install、workspace install,并执行 `--smoke`。
68
116
 
69
- ```bash
70
- npm run claude-voc:npm-pack
71
- ```
117
+ `npm run claude-voc:acceptance` 是更完整的发布前验收,会额外断言 workspace 安装后的:
72
118
 
73
- 这个命令会做三件事:
119
+ - `.mcp.json` 已生成
120
+ - 8 个 `.claude/skills/*/SKILL.md` 入口已生成
121
+ - MCP server 路径是安装后插件目录里的绝对路径
122
+ - `npm pack --dry-run` 能看到关键文件
74
123
 
75
- 1. 校验 npm package metadata 和 CLI 入口。
76
- 2. 生成 `dist/npm/*.tgz`。
77
- 3. 在临时目录里模拟 npm 安装,并执行 `claude-voc install --smoke`。
124
+ ## 正式发布
78
125
 
79
- 发布命令:
126
+ 推荐使用 release 脚本:
80
127
 
81
- ```bash
128
+ ```powershell
129
+ powershell -ExecutionPolicy Bypass -File release/npm/claude-code-voc-intelligence/publish.ps1
130
+ ```
131
+
132
+ 也可以直接执行:
133
+
134
+ ```powershell
82
135
  npm run claude-voc:npm-publish
83
136
  ```
84
137
 
85
- 发布前需要完成 `npm login`,或在 CI/部署环境配置 npm token。
138
+ 发布脚本会读取以下位置的 token:
139
+
140
+ ```text
141
+ release/npm/claude-code-voc-intelligence/.env.local
142
+ ```
143
+
144
+ 文件内容格式:
145
+
146
+ ```text
147
+ NPM_TOKEN=你的 npm automation token
148
+ ```
149
+
150
+ 也支持环境变量:
151
+
152
+ ```powershell
153
+ $env:NPM_TOKEN="你的 npm automation token"
154
+ ```
155
+
156
+ 不要提交 `.env.local`、npm token、VOC session token、模型 API key 或任何真实用户凭证。
157
+
158
+ ## 发布后验证
159
+
160
+ 确认 npm latest:
161
+
162
+ ```powershell
163
+ npm view @vocmarket/voc-skill name version dist-tags.latest --registry=https://registry.npmjs.org/
164
+ ```
165
+
166
+ 线上安装 smoke:
167
+
168
+ ```powershell
169
+ $test = Join-Path $env:TEMP ("vocmarket-online-smoke-" + [guid]::NewGuid())
170
+ New-Item -ItemType Directory -Path $test | Out-Null
171
+ Push-Location $test
172
+ npm exec --yes --package @vocmarket/voc-skill@latest -- claude-voc workspace --smoke
173
+ Pop-Location
174
+ ```
175
+
176
+ ## npm 发布假失败处理
177
+
178
+ 有时 `npm publish` 已经返回成功,例如:
179
+
180
+ ```text
181
+ + @vocmarket/voc-skill@0.3.15
182
+ ```
183
+
184
+ 但脚本紧接着执行 `npm view` 时,registry 还没同步完成,会短暂返回 404。
185
+
186
+ 处理方式:
187
+
188
+ 1. 等 20-60 秒后重新执行:
189
+
190
+ ```powershell
191
+ npm view @vocmarket/voc-skill@0.3.15 version --registry=https://registry.npmjs.org/
192
+ ```
193
+
194
+ 2. 如果返回版本号,说明发布已经成功,不要重复发布同一个版本。
195
+ 3. 如果持续 404,再检查 npm 组织权限、token 权限和包名 scope。
196
+
197
+ 当前发布脚本已经把后置校验等待次数从 6 次增加到 12 次,减少这种假失败。
198
+
199
+ ## 当前发布记录
200
+
201
+ - 2026-06-05:已发布 `@vocmarket/voc-skill@0.3.15`。
202
+ - `npm view @vocmarket/voc-skill name version dist-tags.latest` 返回 `0.3.15`。
203
+ - 线上 `npm exec --yes --package @vocmarket/voc-skill@latest -- claude-voc workspace --smoke` 已通过。
204
+ - 旧包 `@gangvy/claude-code-voc-intelligence@*` 已标记为 deprecated,安装旧包时会提示改用 `@vocmarket/voc-skill`。
205
+ - 已新增 `npm run claude-voc:acceptance` 一键发布前验收,覆盖包级 smoke、MCP smoke、npm pack dry-run 和 workspace 安装断言。
206
+ - 包内包含 8 个 skill、12 个 MCP tools。
207
+ - smoke 覆盖 sample report、证据卡、图片缓存、xsec URL 规范化、偏好记忆、no-token 充值提示、祖先 `.env.local` token 读取、抖音搜索入参错误保护、跨行业样例和 MCP tool discovery。
208
+
209
+ ## 后续版本同步
210
+
211
+ 升级版本时同步修改:
212
+
213
+ - `claude-code/claude-code-voc-intelligence/package.json`
214
+ - `claude-code/claude-code-voc-intelligence/package-lock.json`
215
+ - `claude-code/claude-code-voc-intelligence/skill-package-manifest.json`
216
+ - `claude-code/claude-code-voc-intelligence/.claude-plugin/plugin.json`
217
+ - 如涉及 MCP server 或记忆 schema,同步对应版本字段
218
+ - `dist/npm/claude-code-voc-npm-package-manifest.json`
219
+ - `dist/claude-code-voc-intelligence-suite-manifest.json`
220
+ - `release/npm/claude-code-voc-intelligence/README.md`
221
+ - `release/npm/claude-code-voc-intelligence/release-checklist.md`
86
222
 
87
- ## 注意点
223
+ ## 体验原则
88
224
 
89
- - zip 包和 npm 包共用同一套源码,但验证脚本分开。
90
- - npm 包不要发布 `node_modules/`、`memory/`、`outputs/`、`.env`。
91
- - `install.js` 不强依赖 `package-lock.json`,因为 npm publish 后 package-lock 不一定随包安装。
92
- - 用户侧不要暴露 profile、output、collectionMode 这类参数;安装完成后仍然用自然语言启动。
93
-
225
+ - 用户侧不要暴露 `profile`、`output`、`collectionMode` 等底层参数。
226
+ - 用户用自然语言触发 VOC 采集、问题池、单点深挖、内容计划和口播脚本。
227
+ - 第一轮真实采集只输出“初步判断 / 机会假设 / 待校准”,不要包装成最终结论。
228
+ - 无 token、余额不足、业务权限未开通时,返回开通/充值引导,不直接暴露底层 403、余额接口或 stack trace。
package/install.js CHANGED
@@ -111,6 +111,11 @@ function checkFiles() {
111
111
  'skills/voc-speaking-script/SKILL.md',
112
112
  'skills/voc-competitor-map/SKILL.md',
113
113
  'skills/voc-business-workflow/SKILL.md',
114
+ 'skills/fmode-image-analysis/SKILL.md',
115
+ 'skills/voc-api-catalog/SKILL.md',
116
+ 'mcp/src/tools/fmode-image-analysis.js',
117
+ 'mcp/src/tools/voc-api-catalog-run.js',
118
+ 'mcp/catalog/voc-social-endpoints.json',
114
119
  'mcp/src/server.js'
115
120
  ].forEach(assertFile);
116
121
 
@@ -0,0 +1,143 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "updatedAt": "2026-06-21",
4
+ "gateway": {
5
+ "social": {
6
+ "baseUrl": "https://server.fmode.cn/api/voc-social",
7
+ "auth": "Authorization: Bearer <r: 开头的会话 token>",
8
+ "upstream": "TikHub (server.fmode.cn/thapi/v1)",
9
+ "billing": "每次转发调用扣除 1 次社交平台 API 额度(缓存命中也会计费)。",
10
+ "note": "这是一个通用转发网关:任意 proxyPath 都会被透传到上游 TikHub。本清单只列出已验证的常用接口;未列出的接口可以直接用 voc_api_call 传 rawPath + method + params 调用,无需改代码。",
11
+ "rawPathHint": "调用未在清单中的接口时,把上游的相对路径填到 voc_api_call 的 rawPath,例如 douyin/search/fetch_general_search_v2,并按上游文档拼 query/body。"
12
+ }
13
+ },
14
+ "platforms": [
15
+ { "key": "douyin", "label": "抖音", "status": "verified" },
16
+ { "key": "xiaohongshu", "label": "小红书", "status": "verified" },
17
+ { "key": "tiktok", "label": "TikTok", "status": "gateway_available" },
18
+ { "key": "youtube", "label": "YouTube", "status": "gateway_available" },
19
+ { "key": "twitter", "label": "Twitter/X", "status": "gateway_available" },
20
+ { "key": "instagram", "label": "Instagram", "status": "gateway_available" },
21
+ { "key": "linkedin", "label": "LinkedIn", "status": "gateway_available" }
22
+ ],
23
+ "endpoints": [
24
+ {
25
+ "id": "douyin.search_general",
26
+ "platform": "douyin",
27
+ "channel": "social",
28
+ "title": "抖音综合搜索",
29
+ "summary": "按关键词搜索抖音视频(综合搜索 v2)。任意行业/方向关键词均可用于趋势与 VOC 选题采集。",
30
+ "proxyPath": "douyin/search/fetch_general_search_v2",
31
+ "method": "POST",
32
+ "paramsIn": "body",
33
+ "params": [
34
+ { "name": "keyword", "in": "body", "type": "string", "required": true, "desc": "搜索关键词,任意行业/方向均可,例如 股权律师、医美 玻尿酸、少儿编程、新能源汽车。" },
35
+ { "name": "cursor", "in": "body", "type": "integer", "required": false, "default": 0, "desc": "分页游标,首页为 0,翻页用上一次返回的 cursor。" },
36
+ { "name": "sort_type", "in": "body", "type": "string", "required": false, "default": "0", "desc": "排序:0 综合,1 最多点赞,2 最新发布。" },
37
+ { "name": "publish_time", "in": "body", "type": "string", "required": false, "default": "0", "desc": "发布时间:0 不限,1 一天内,7 一周内,180 半年内。" },
38
+ { "name": "filter_duration", "in": "body", "type": "string", "required": false, "default": "0", "desc": "时长筛选:0 不限,0-1 一分钟内,1-5 一到五分钟,5-10000 五分钟以上。" },
39
+ { "name": "content_type", "in": "body", "type": "string", "required": false, "default": "0", "desc": "内容类型:0 不限,1 视频,2 图集,3 文章。" },
40
+ { "name": "search_id", "in": "body", "type": "string", "required": false, "default": "", "desc": "连续翻页时透传上一次返回的 search_id。" },
41
+ { "name": "backtrace", "in": "body", "type": "string", "required": false, "default": "", "desc": "连续翻页时透传上一次返回的 backtrace。" }
42
+ ],
43
+ "tags": ["抖音", "douyin", "搜索", "search", "视频", "关键词", "趋势", "voc"],
44
+ "billing": 1,
45
+ "responseHint": "返回视频列表,每条含 aweme_id、desc、统计字段等;aweme_id 可用于拉取评论。",
46
+ "example": { "keyword": "新能源汽车", "cursor": 0, "sort_type": "0" }
47
+ },
48
+ {
49
+ "id": "douyin.video_comments",
50
+ "platform": "douyin",
51
+ "channel": "social",
52
+ "title": "抖音视频评论列表",
53
+ "summary": "按 aweme_id 拉取某条抖音视频的评论,用于采集真实用户声音(VOC)。",
54
+ "proxyPath": "douyin/app/v3/fetch_video_comments",
55
+ "method": "GET",
56
+ "paramsIn": "query",
57
+ "params": [
58
+ { "name": "aweme_id", "in": "query", "type": "string", "required": true, "desc": "视频 ID,来自抖音综合搜索结果。" },
59
+ { "name": "cursor", "in": "query", "type": "integer", "required": false, "default": 0, "desc": "评论分页游标,首页 0。" },
60
+ { "name": "count", "in": "query", "type": "integer", "required": false, "default": 20, "desc": "每页评论数,建议 20。" }
61
+ ],
62
+ "tags": ["抖音", "douyin", "评论", "comments", "voc", "用户声音"],
63
+ "billing": 1,
64
+ "responseHint": "返回评论列表,含评论文本、点赞数、cid(用于拉取楼中楼回复)。",
65
+ "example": { "aweme_id": "7300000000000000000", "cursor": 0, "count": 20 }
66
+ },
67
+ {
68
+ "id": "douyin.comment_replies",
69
+ "platform": "douyin",
70
+ "channel": "social",
71
+ "title": "抖音评论回复(楼中楼)",
72
+ "summary": "按视频 item_id 和评论 comment_id 拉取某条评论下的回复。",
73
+ "proxyPath": "douyin/app/v3/fetch_video_comment_replies",
74
+ "method": "GET",
75
+ "paramsIn": "query",
76
+ "params": [
77
+ { "name": "item_id", "in": "query", "type": "string", "required": true, "desc": "视频 ID(同 aweme_id)。" },
78
+ { "name": "comment_id", "in": "query", "type": "string", "required": true, "desc": "父评论 ID(来自评论列表的 cid)。" },
79
+ { "name": "cursor", "in": "query", "type": "integer", "required": false, "default": 0, "desc": "回复分页游标。" },
80
+ { "name": "count", "in": "query", "type": "integer", "required": false, "default": 20, "desc": "每页回复数。" }
81
+ ],
82
+ "tags": ["抖音", "douyin", "评论", "回复", "replies", "voc"],
83
+ "billing": 1,
84
+ "responseHint": "返回某条父评论下的回复列表。",
85
+ "example": { "item_id": "7300000000000000000", "comment_id": "7300000000000000001", "cursor": 0, "count": 20 }
86
+ },
87
+ {
88
+ "id": "xiaohongshu.search_notes",
89
+ "platform": "xiaohongshu",
90
+ "channel": "social",
91
+ "title": "小红书笔记搜索",
92
+ "summary": "按关键词搜索小红书笔记,任意行业/方向均可,用于趋势与 VOC 选题采集。",
93
+ "proxyPath": "xiaohongshu/app/search_notes",
94
+ "method": "GET",
95
+ "paramsIn": "query",
96
+ "params": [
97
+ { "name": "keyword", "in": "query", "type": "string", "required": true, "desc": "搜索关键词,任意行业/方向均可。" },
98
+ { "name": "page", "in": "query", "type": "integer", "required": false, "default": 1, "desc": "页码,从 1 开始。" },
99
+ { "name": "sort", "in": "query", "type": "string", "required": false, "default": "popularity_descending", "desc": "排序:general 综合,time_descending 最新,popularity_descending 最热。" },
100
+ { "name": "note_type", "in": "query", "type": "string", "required": false, "default": "_0", "desc": "笔记类型:_0 不限,_1 视频,_2 图文。" }
101
+ ],
102
+ "tags": ["小红书", "xiaohongshu", "xhs", "搜索", "search", "笔记", "关键词", "趋势", "voc"],
103
+ "billing": 1,
104
+ "responseHint": "返回笔记列表,每条含 note_id,可用于拉取详情和评论。",
105
+ "example": { "keyword": "敏感肌护肤", "page": 1, "sort": "popularity_descending", "note_type": "_0" }
106
+ },
107
+ {
108
+ "id": "xiaohongshu.note_detail",
109
+ "platform": "xiaohongshu",
110
+ "channel": "social",
111
+ "title": "小红书笔记详情",
112
+ "summary": "按 note_id 拉取小红书笔记详情(正文、图片、统计等)。",
113
+ "proxyPath": "xiaohongshu/app/get_note_info",
114
+ "method": "GET",
115
+ "paramsIn": "query",
116
+ "params": [
117
+ { "name": "note_id", "in": "query", "type": "string", "required": true, "desc": "笔记 ID,来自搜索结果。" }
118
+ ],
119
+ "tags": ["小红书", "xiaohongshu", "xhs", "笔记", "详情", "note"],
120
+ "billing": 1,
121
+ "responseHint": "返回单条笔记的完整内容。",
122
+ "example": { "note_id": "650000000000000000000000" }
123
+ },
124
+ {
125
+ "id": "xiaohongshu.note_comments",
126
+ "platform": "xiaohongshu",
127
+ "channel": "social",
128
+ "title": "小红书笔记评论",
129
+ "summary": "按 note_id 拉取小红书笔记评论,用于采集真实用户声音(VOC)。",
130
+ "proxyPath": "xiaohongshu/app/get_note_comments",
131
+ "method": "GET",
132
+ "paramsIn": "query",
133
+ "params": [
134
+ { "name": "note_id", "in": "query", "type": "string", "required": true, "desc": "笔记 ID,来自搜索结果。" },
135
+ { "name": "cursor", "in": "query", "type": "string", "required": false, "default": "", "desc": "评论分页游标,翻页用上一次返回的 cursor。" }
136
+ ],
137
+ "tags": ["小红书", "xiaohongshu", "xhs", "评论", "comments", "voc", "用户声音"],
138
+ "billing": 1,
139
+ "responseHint": "返回笔记评论列表。",
140
+ "example": { "note_id": "650000000000000000000000", "cursor": "" }
141
+ }
142
+ ]
143
+ }