yuque-mcp-plus 0.2.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.
package/README.md ADDED
@@ -0,0 +1,882 @@
1
+ # yuque-mcp-plus
2
+
3
+ 增强版语雀 MCP 服务,默认中文文档。
4
+
5
+ 它在现有 `yuque-mcp-server` 的基础上补了几类关键能力:
6
+
7
+ - 默认知识库解析
8
+ - 知识库 TOC/目录树查询
9
+ - 支持 `parentUuid` 的文档创建
10
+ - 文档与目录节点移动
11
+ - 目录节点创建与删除
12
+ - 官方命名兼容别名
13
+ - 通用 OpenAPI 透传 `yuque_request`
14
+ - 通用 multipart 上传透传 `yuque_multipart_request`
15
+
16
+ 英文文档见 [README.en.md](/Users/program/code/code_mcp/yuque-mcp-plus/README.en.md)。
17
+
18
+ ## 适用场景
19
+
20
+ 适合这些语雀自动化需求:
21
+
22
+ - 按目录结构维护知识库
23
+ - 在指定目录下创建文档
24
+ - 批量重组目录或文档位置
25
+ - 通过 MCP 给 AI 助手提供稳定的语雀管理能力
26
+ - 在官方工具未覆盖的接口上,通过通用请求继续扩展
27
+
28
+ ## 当前状态
29
+
30
+ 已经完成并验证:
31
+
32
+ - `yuque_get_default_repository`
33
+ - `yuque_get_repository_toc_tree`
34
+ - `yuque_create_doc` + `parentUuid`
35
+ - `yuque_move_document`
36
+ - `yuque_create_toc_node`
37
+ - `yuque_delete_toc_node`
38
+ - 根节点自动删除
39
+ - 官方兼容别名工具
40
+
41
+ 真实联调已通过的能力:
42
+
43
+ - 创建根目录节点
44
+ - 在目录节点下创建文档
45
+ - 移动目录节点
46
+ - 删除目录节点
47
+ - 删除测试文档
48
+
49
+ ## 环境变量
50
+
51
+ 必填:
52
+
53
+ - `YUQUE_TOKEN`
54
+
55
+ 可选:
56
+
57
+ - `YUQUE_API_BASE_URL`
58
+ - `YUQUE_TIMEOUT_MS`
59
+ - `YUQUE_RETRIES`
60
+ - `YUQUE_DEFAULT_REPO_ID`
61
+ - `YUQUE_DEFAULT_REPO_NAMESPACE`
62
+
63
+ 说明:
64
+
65
+ - `YUQUE_DEFAULT_REPO_ID` 优先级高于 `YUQUE_DEFAULT_REPO_NAMESPACE`
66
+ - 两者都不填时,会回退到当前账号可访问的第一个知识库
67
+
68
+ ## 运行方式
69
+
70
+ 直接启动:
71
+
72
+ ```bash
73
+ node ./src/index.js
74
+ ```
75
+
76
+ 本地检查:
77
+
78
+ ```bash
79
+ npm run check
80
+ ```
81
+
82
+ 本地测试:
83
+
84
+ ```bash
85
+ npm test
86
+ ```
87
+
88
+ 版本变更记录:
89
+
90
+ - [CHANGELOG.md](/Users/program/code/code_mcp/yuque-mcp-plus/CHANGELOG.md)
91
+
92
+ 发布步骤:
93
+
94
+ - [RELEASE.md](/Users/program/code/code_mcp/yuque-mcp-plus/RELEASE.md)
95
+
96
+ ## Codex MCP 配置示例
97
+
98
+ ```toml
99
+ [mcp_servers.yuque]
100
+ command = "node"
101
+ args = [ "/Users/program/code/code_mcp/yuque-mcp-plus/src/index.js" ]
102
+
103
+ [mcp_servers.yuque.env]
104
+ YUQUE_TOKEN = "your-token"
105
+ ```
106
+
107
+ ## 其他客户端接入
108
+
109
+ 下面这些示例基于 2026-03-04 当天可查到的客户端文档整理。不同版本的 UI 或配置文件位置可能会变,但本地 `stdio` 启动方式基本一致。
110
+
111
+ ### Claude Code
112
+
113
+ 官方文档当前推荐直接用命令注册本地 `stdio` MCP:
114
+
115
+ ```bash
116
+ claude mcp add --transport stdio yuque -- node /Users/program/code/code_mcp/yuque-mcp-plus/src/index.js
117
+ ```
118
+
119
+ 如果要带环境变量:
120
+
121
+ ```bash
122
+ claude mcp add --transport stdio --env YUQUE_TOKEN=your-token yuque -- node /Users/program/code/code_mcp/yuque-mcp-plus/src/index.js
123
+ ```
124
+
125
+ 常用管理命令:
126
+
127
+ ```bash
128
+ claude mcp list
129
+ claude mcp get yuque
130
+ ```
131
+
132
+ 如果你使用项目共享配置,也可以把它写进项目根目录的 `.mcp.json`:
133
+
134
+ ```json
135
+ {
136
+ "mcpServers": {
137
+ "yuque": {
138
+ "command": "node",
139
+ "args": [
140
+ "/Users/program/code/code_mcp/yuque-mcp-plus/src/index.js"
141
+ ],
142
+ "env": {
143
+ "YUQUE_TOKEN": "${YUQUE_TOKEN}"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ ### Qoder
151
+
152
+ Qoder 当前支持在设置页里直接添加 MCP。
153
+
154
+ 操作路径:
155
+
156
+ - 打开 Qoder Settings
157
+ - 进入 `MCP`
158
+ - 在 `My Servers` 里点击 `+ Add`
159
+ - 粘贴 JSON 配置并保存
160
+
161
+ 本项目可直接使用:
162
+
163
+ ```json
164
+ {
165
+ "mcpServers": {
166
+ "yuque": {
167
+ "command": "node",
168
+ "args": [
169
+ "/Users/program/code/code_mcp/yuque-mcp-plus/src/index.js"
170
+ ],
171
+ "env": {
172
+ "YUQUE_TOKEN": "your-token"
173
+ }
174
+ }
175
+ }
176
+ }
177
+ ```
178
+
179
+ 保存后如果能看到连接图标,说明服务已成功连上。使用时要切到 `Agent mode`,这样 Qoder 才会调用 MCP 工具。
180
+
181
+ ### OpenCode
182
+
183
+ OpenCode 当前在 `opencode.jsonc` 里配置 MCP。本地 MCP 要放在 `mcp` 字段下,并声明为 `type: "local"`。
184
+
185
+ 示例:
186
+
187
+ ```jsonc
188
+ {
189
+ "$schema": "https://opencode.ai/config.json",
190
+ "mcp": {
191
+ "yuque": {
192
+ "type": "local",
193
+ "command": [
194
+ "node",
195
+ "/Users/program/code/code_mcp/yuque-mcp-plus/src/index.js"
196
+ ],
197
+ "enabled": true,
198
+ "environment": {
199
+ "YUQUE_TOKEN": "your-token"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ 使用时可以在提示词里直接点名,例如:
207
+
208
+ ```text
209
+ use the yuque tool to list my repositories
210
+ ```
211
+
212
+ ### Trae
213
+
214
+ Trae 已经支持 MCP,但我当前没查到和 Qoder/OpenCode 一样完整公开的本地配置文件格式文档。所以这里按目前公开的接入方式写最稳的 UI 配置步骤。
215
+
216
+ 常见操作路径:
217
+
218
+ - 打开聊天框
219
+ - 点击右上角齿轮
220
+ - 进入 `MCP`
221
+ - 添加一个本地 `STDIO` 服务
222
+
223
+ 建议填写:
224
+
225
+ - Name: `yuque`
226
+ - Command: `node`
227
+ - Args: `/Users/program/code/code_mcp/yuque-mcp-plus/src/index.js`
228
+ - Env: `YUQUE_TOKEN=your-token`
229
+
230
+ 说明:
231
+
232
+ - Trae 的具体入口位置和字段名可能会随版本变化
233
+ - 如果你的版本支持 JSON 配置导入,可以直接复用 Qoder 的那份 `mcpServers` 配置
234
+ - 如果是通过界面逐项填写,本项目本质上只需要 `command + args + env`
235
+
236
+ ## 工具清单
237
+
238
+ ### 核心工具
239
+
240
+ | 工具 | 用途 | 常用关键参数 |
241
+ | --- | --- | --- |
242
+ | `yuque_hello` | 检查服务和 token 是否可用 | 无 |
243
+ | `yuque_request` | 通用 OpenAPI 透传 | `method`, `path`, `params`, `body` |
244
+ | `yuque_multipart_request` | 通用 multipart 上传请求,适合附件类接口 | `method`, `path`, `params`, `fields`, `files` |
245
+ | `yuque_get_user` | 获取当前用户信息 | 无 |
246
+ | `yuque_get_repos` | 获取知识库列表 | `ownerLogin`, `ownerType`, `userId` |
247
+ | `yuque_list_groups` | 获取当前用户或指定用户的团队列表 | `userId` |
248
+ | `yuque_get_repo` | 获取单个知识库详情 | `repoId`, `repoNamespace` |
249
+ | `yuque_get_default_repository` | 解析默认知识库 | 无 |
250
+ | `yuque_search` | 搜索文档或知识库内容 | `query`, `type`, `repoId`, `page` |
251
+
252
+ ### 知识库与文档
253
+
254
+ | 工具 | 用途 | 常用关键参数 |
255
+ | --- | --- | --- |
256
+ | `yuque_get_docs` | 列出知识库文档 | `repoId`, `repoNamespace`, `limit`, `offset` |
257
+ | `yuque_get_doc` | 获取单篇文档详情 | `docId`, `repoId`, `repoNamespace` |
258
+ | `yuque_create_doc` | 创建文档,可挂到目录节点下 | `repoId`, `title`, `body`, `format`, `parentUuid` |
259
+ | `yuque_update_doc` | 更新文档标题或正文 | `docId`, `title`, `body`, `format` |
260
+ | `yuque_delete_doc` | 删除文档 | `docId`, `repoId`, `repoNamespace` |
261
+ | `yuque_create_repo` | 创建知识库 | `name`, `slug`, `description`, `ownerLogin`, `ownerType` |
262
+ | `yuque_update_repo` | 更新知识库配置 | `repoId`, `repoNamespace`, `name`, `slug`, `description`, `isPublic` |
263
+ | `yuque_delete_repo` | 删除知识库 | `repoId`, `repoNamespace` |
264
+
265
+ ### TOC 与结构调整
266
+
267
+ | 工具 | 用途 | 常用关键参数 |
268
+ | --- | --- | --- |
269
+ | `yuque_get_repository_toc_tree` | 获取完整目录树 | `repoId`, `repoNamespace` |
270
+ | `yuque_create_toc_node` | 创建目录或链接节点 | `repoId`, `title`, `nodeType`, `parentUuid`, `actionMode`, `position` |
271
+ | `yuque_delete_toc_node` | 删除目录节点,支持根节点自动推导 | `repoId`, `nodeUuid`, `parentUuid` |
272
+ | `yuque_move_document` | 移动文档或目录节点 | `repoId`, `docId` 或 `nodeUuid`, `parentUuid`, `actionMode`, `position` |
273
+ | `yuque_update_repository_toc` | 直接透传底层 TOC 更新 | `repoId`, `repoNamespace`, `payload` |
274
+
275
+ ### 版本、团队与统计
276
+
277
+ | 工具 | 用途 | 常用关键参数 |
278
+ | --- | --- | --- |
279
+ | `yuque_list_doc_versions` | 获取文档版本列表 | `docId` |
280
+ | `yuque_get_doc_version` | 获取某个文档版本详情 | `versionId` |
281
+ | `yuque_list_group_members` | 获取团队成员列表 | `login` |
282
+ | `yuque_update_group_member` | 更新团队成员角色 | `login`, `userId`, `role` |
283
+ | `yuque_remove_group_member` | 移除团队成员 | `login`, `userId` |
284
+ | `yuque_group_stats` | 获取团队总统计 | `login` |
285
+ | `yuque_group_member_stats` | 获取团队成员统计 | `login` |
286
+ | `yuque_group_book_stats` | 获取团队知识库统计 | `login` |
287
+ | `yuque_group_doc_stats` | 获取团队文档统计 | `login` |
288
+
289
+ ### 兼容别名
290
+
291
+ | 别名 | 实际工具 |
292
+ | --- | --- |
293
+ | `yuque_list_repos` | `yuque_get_repos` |
294
+ | `yuque_list_docs` | `yuque_get_docs` |
295
+ | `yuque_get_toc` | `yuque_get_repository_toc_tree` |
296
+ | `yuque_update_toc` | `yuque_update_repository_toc` |
297
+
298
+ ## 常用调用示例
299
+
300
+ ### 1. 获取默认知识库
301
+
302
+ ```json
303
+ {}
304
+ ```
305
+
306
+ 对应工具:
307
+
308
+ - `yuque_get_default_repository`
309
+
310
+ ### 2. 获取知识库目录树
311
+
312
+ ```json
313
+ {
314
+ "repoId": 63978478
315
+ }
316
+ ```
317
+
318
+ 对应工具:
319
+
320
+ - `yuque_get_repository_toc_tree`
321
+
322
+ ### 3. 在指定目录下创建文档
323
+
324
+ ```json
325
+ {
326
+ "repoId": 63978478,
327
+ "title": "新文档",
328
+ "body": "# 标题\n\n正文",
329
+ "format": "markdown",
330
+ "parentUuid": "-W39TNJu_tufwcVm"
331
+ }
332
+ ```
333
+
334
+ 对应工具:
335
+
336
+ - `yuque_create_doc`
337
+
338
+ ### 4. 创建目录节点
339
+
340
+ ```json
341
+ {
342
+ "repoId": 63978478,
343
+ "title": "新目录",
344
+ "nodeType": "TITLE",
345
+ "parentUuid": "-W39TNJu_tufwcVm",
346
+ "actionMode": "child",
347
+ "position": "append"
348
+ }
349
+ ```
350
+
351
+ 如果不传 `parentUuid`,则创建在根层级。
352
+
353
+ 对应工具:
354
+
355
+ - `yuque_create_toc_node`
356
+
357
+ ### 5. 删除目录节点
358
+
359
+ 最简单的调用方式:
360
+
361
+ ```json
362
+ {
363
+ "repoId": 63978478,
364
+ "nodeUuid": "CxEXaBKTPFRKaopb"
365
+ }
366
+ ```
367
+
368
+ 说明:
369
+
370
+ - 对子节点,服务会自动解析 `parent_uuid`
371
+ - 对根节点,服务会自动解析删除策略
372
+ - 你也可以手动传 `parentUuid` 覆盖自动推导
373
+
374
+ 对应工具:
375
+
376
+ - `yuque_delete_toc_node`
377
+
378
+ ### 6. 移动文档或目录节点
379
+
380
+ ```json
381
+ {
382
+ "repoId": 63978478,
383
+ "nodeUuid": "Mir36kbfs2f4g130",
384
+ "parentUuid": "-W39TNJu_tufwcVm",
385
+ "actionMode": "child",
386
+ "position": "append"
387
+ }
388
+ ```
389
+
390
+ 如果是移动文档,也可以传:
391
+
392
+ ```json
393
+ {
394
+ "repoId": 63978478,
395
+ "docId": 259413650,
396
+ "parentUuid": "-W39TNJu_tufwcVm",
397
+ "actionMode": "child",
398
+ "position": "append"
399
+ }
400
+ ```
401
+
402
+ 对应工具:
403
+
404
+ - `yuque_move_document`
405
+
406
+ ### 7. 通用 OpenAPI 请求
407
+
408
+ ```json
409
+ {
410
+ "method": "GET",
411
+ "path": "/user"
412
+ }
413
+ ```
414
+
415
+ 或:
416
+
417
+ ```json
418
+ {
419
+ "method": "GET",
420
+ "path": "/search",
421
+ "params": {
422
+ "q": "联商客",
423
+ "type": "doc"
424
+ }
425
+ }
426
+ ```
427
+
428
+ 对应工具:
429
+
430
+ - `yuque_request`
431
+
432
+ ## 工具速查示例
433
+
434
+ 下面这部分按工具拆开,适合复制后直接改参数。
435
+
436
+ ### `yuque_get_default_repository`
437
+
438
+ ```json
439
+ {}
440
+ ```
441
+
442
+ ### `yuque_get_repos`
443
+
444
+ ```json
445
+ {}
446
+ ```
447
+
448
+ 按用户或团队过滤:
449
+
450
+ ```json
451
+ {
452
+ "ownerLogin": "your-team",
453
+ "ownerType": "groups"
454
+ }
455
+ ```
456
+
457
+ ### `yuque_get_repo`
458
+
459
+ ```json
460
+ {
461
+ "repoId": 63978478
462
+ }
463
+ ```
464
+
465
+ ### `yuque_get_repository_toc_tree`
466
+
467
+ ```json
468
+ {
469
+ "repoId": 63978478
470
+ }
471
+ ```
472
+
473
+ ### `yuque_create_toc_node`
474
+
475
+ 创建根目录:
476
+
477
+ ```json
478
+ {
479
+ "repoId": 63978478,
480
+ "title": "一级目录",
481
+ "nodeType": "TITLE"
482
+ }
483
+ ```
484
+
485
+ 创建子目录:
486
+
487
+ ```json
488
+ {
489
+ "repoId": 63978478,
490
+ "title": "二级目录",
491
+ "nodeType": "TITLE",
492
+ "parentUuid": "-W39TNJu_tufwcVm",
493
+ "actionMode": "child",
494
+ "position": "append"
495
+ }
496
+ ```
497
+
498
+ ### `yuque_delete_toc_node`
499
+
500
+ 自动删除目录节点:
501
+
502
+ ```json
503
+ {
504
+ "repoId": 63978478,
505
+ "nodeUuid": "CxEXaBKTPFRKaopb"
506
+ }
507
+ ```
508
+
509
+ ### `yuque_create_doc`
510
+
511
+ 创建根层级文档:
512
+
513
+ ```json
514
+ {
515
+ "repoId": 63978478,
516
+ "title": "根文档",
517
+ "body": "# 标题\n\n正文",
518
+ "format": "markdown"
519
+ }
520
+ ```
521
+
522
+ 创建到目录下:
523
+
524
+ ```json
525
+ {
526
+ "repoId": 63978478,
527
+ "title": "目录文档",
528
+ "body": "# 标题\n\n正文",
529
+ "format": "markdown",
530
+ "parentUuid": "-W39TNJu_tufwcVm"
531
+ }
532
+ ```
533
+
534
+ ### `yuque_update_doc`
535
+
536
+ ```json
537
+ {
538
+ "docId": 259413650,
539
+ "title": "更新后的标题",
540
+ "body": "# 新标题\n\n新正文",
541
+ "format": "markdown"
542
+ }
543
+ ```
544
+
545
+ ### `yuque_delete_doc`
546
+
547
+ ```json
548
+ {
549
+ "docId": 259413650
550
+ }
551
+ ```
552
+
553
+ ### `yuque_move_document`
554
+
555
+ 按文档移动:
556
+
557
+ ```json
558
+ {
559
+ "repoId": 63978478,
560
+ "docId": 259413650,
561
+ "parentUuid": "-W39TNJu_tufwcVm",
562
+ "actionMode": "child",
563
+ "position": "append"
564
+ }
565
+ ```
566
+
567
+ 按目录节点移动:
568
+
569
+ ```json
570
+ {
571
+ "repoId": 63978478,
572
+ "nodeUuid": "Mir36kbfs2f4g130",
573
+ "parentUuid": "-W39TNJu_tufwcVm",
574
+ "actionMode": "child",
575
+ "position": "append"
576
+ }
577
+ ```
578
+
579
+ ### `yuque_search`
580
+
581
+ ```json
582
+ {
583
+ "query": "联商客",
584
+ "type": "doc",
585
+ "repoId": 63978478
586
+ }
587
+ ```
588
+
589
+ ### `yuque_list_doc_versions`
590
+
591
+ ```json
592
+ {
593
+ "docId": 259413650
594
+ }
595
+ ```
596
+
597
+ ### `yuque_get_doc_version`
598
+
599
+ ```json
600
+ {
601
+ "versionId": 123456789
602
+ }
603
+ ```
604
+
605
+ ### `yuque_list_group_members`
606
+
607
+ ```json
608
+ {
609
+ "login": "your-team"
610
+ }
611
+ ```
612
+
613
+ ### `yuque_update_group_member`
614
+
615
+ ```json
616
+ {
617
+ "login": "your-team",
618
+ "userId": 123456,
619
+ "role": 1
620
+ }
621
+ ```
622
+
623
+ ### `yuque_remove_group_member`
624
+
625
+ ```json
626
+ {
627
+ "login": "your-team",
628
+ "userId": 123456
629
+ }
630
+ ```
631
+
632
+ ### `yuque_group_stats`
633
+
634
+ ```json
635
+ {
636
+ "login": "your-team"
637
+ }
638
+ ```
639
+
640
+ ### `yuque_request`
641
+
642
+ 查询当前用户:
643
+
644
+ ```json
645
+ {
646
+ "method": "GET",
647
+ "path": "/user"
648
+ }
649
+ ```
650
+
651
+ 评论类请求示例:
652
+
653
+ ```json
654
+ {
655
+ "method": "POST",
656
+ "path": "/repos/63978478/docs/259413650/comments",
657
+ "body": {
658
+ "body": "这是一条评论"
659
+ }
660
+ }
661
+ ```
662
+
663
+ ### `yuque_multipart_request`
664
+
665
+ 附件上传类请求示例:
666
+
667
+ ```json
668
+ {
669
+ "method": "POST",
670
+ "path": "/repos/63978478/attachments",
671
+ "fields": {
672
+ "type": "file"
673
+ },
674
+ "files": [
675
+ {
676
+ "fieldName": "file",
677
+ "filePath": "/absolute/path/to/example.png",
678
+ "contentType": "image/png"
679
+ }
680
+ ]
681
+ }
682
+ ```
683
+
684
+ 底层 TOC 更新:
685
+
686
+ ```json
687
+ {
688
+ "path": "/repos/63978478/toc",
689
+ "method": "PUT",
690
+ "body": {
691
+ "action": "removeNode",
692
+ "action_mode": "child",
693
+ "target_uuid": "-W39TNJu_tufwcVm",
694
+ "node_uuid": "Mir36kbfs2f4g130"
695
+ }
696
+ }
697
+ ```
698
+
699
+ ## 命名兼容说明
700
+
701
+ 为了兼容官方 `yuque/yuque-mcp-server` 的命名习惯,项目提供了这些别名:
702
+
703
+ - `yuque_list_repos` -> `yuque_get_repos`
704
+ - `yuque_list_docs` -> `yuque_get_docs`
705
+ - `yuque_get_toc` -> `yuque_get_repository_toc_tree`
706
+ - `yuque_update_toc` -> `yuque_update_repository_toc`
707
+
708
+ ## 已知边界
709
+
710
+ - 评论暂未封装成专用工具,建议通过 `yuque_request` 访问
711
+ - 附件暂未封装成官方专用工具,但现在可通过 `yuque_multipart_request` 处理上传类接口
712
+ - `yuque_update_repository_toc` 属于底层透传工具,适合高级场景
713
+
714
+ 说明:
715
+
716
+ - 我已核对官方 `openapi-metadata` 和 `sdk`
717
+ - 其中没有明确公开 comments / attachments 的专用 OpenAPI 定义
718
+ - 所以当前实现选择“补强通用能力”,而不是硬编码猜测端点
719
+
720
+ ## 真实联调记录
721
+
722
+ 以下场景已经在真实语雀知识库里跑通过:
723
+
724
+ ### 默认知识库解析
725
+
726
+ - `yuque_get_default_repository` 可以正常返回默认知识库
727
+ - 返回中会带 `_defaultSource`
728
+ - 该字段用于标记默认知识库的解析来源,方便排查配置问题
729
+
730
+ ### 目录树查询
731
+
732
+ - `yuque_get_repository_toc_tree` 可以正确返回 `TITLE`、`DOC` 和层级关系
733
+ - 已验证返回字段中包含 `uuid`、`parent_uuid`、`prev_uuid`、`sibling_uuid`
734
+
735
+ ### 在目录下创建文档
736
+
737
+ - `yuque_create_doc` 传入 `parentUuid` 后,可以先创建文档,再正确挂载到指定目录下
738
+ - 已验证创建出的文档在 TOC 中可见,且 `parent_uuid` 正确
739
+
740
+ ### 文档移动
741
+
742
+ - `yuque_move_document` 已验证支持:
743
+ - 通过 `docId` 移动文档
744
+ - 通过 `nodeUuid` 移动 TOC 节点
745
+ - 可在根层级与目录层级之间移动
746
+
747
+ ### 创建目录节点
748
+
749
+ - `yuque_create_toc_node` 已验证可创建根层级 `TITLE`
750
+ - 也已验证可创建子级目录节点
751
+
752
+ ### 删除目录节点
753
+
754
+ - `yuque_delete_toc_node` 已验证可删除:
755
+ - 有父目录的普通目录节点
756
+ - 根层级目录节点
757
+ - 对根节点删除时,服务会自动推导正确的删除策略
758
+
759
+ ### 清理测试数据
760
+
761
+ - 测试过程中创建的临时文档和临时目录节点都已成功删除
762
+ - 当前实现已经适合做日常知识库结构维护
763
+
764
+ ## 常见报错处理
765
+
766
+ ### `Missing YUQUE_TOKEN`
767
+
768
+ 原因:
769
+
770
+ - 没有注入 `YUQUE_TOKEN`
771
+ - 终端手动运行时忘记带环境变量
772
+
773
+ 处理:
774
+
775
+ - 检查 `config.toml` 里的 `[mcp_servers.yuque.env]`
776
+ - 或者在终端启动时显式传入:
777
+
778
+ ```bash
779
+ YUQUE_TOKEN="your-token" node ./src/index.js
780
+ ```
781
+
782
+ ### `doc not found`
783
+
784
+ 原因:
785
+
786
+ - 文档 ID 不存在
787
+ - 文档已经被删除
788
+ - 仓库不匹配
789
+
790
+ 处理:
791
+
792
+ - 先用 `yuque_get_docs` 或 `yuque_get_doc` 确认 `docId`
793
+ - 确认 `repoId` 或 `repoNamespace` 正确
794
+
795
+ ### `action invalid`
796
+
797
+ 原因:
798
+
799
+ - 传给 `yuque_update_repository_toc` 的底层 `action` 不符合语雀实际支持的值
800
+
801
+ 处理:
802
+
803
+ - 优先使用上层工具:
804
+ - `yuque_create_toc_node`
805
+ - `yuque_delete_toc_node`
806
+ - `yuque_move_document`
807
+ - 只有在高级场景下再使用 `yuque_update_repository_toc`
808
+
809
+ ### `missing action_mode`
810
+
811
+ 原因:
812
+
813
+ - 调用 TOC 更新接口时缺少 `action_mode`
814
+
815
+ 处理:
816
+
817
+ - 尽量不要手写 TOC 底层 payload
818
+ - 对删除目录节点,优先使用 `yuque_delete_toc_node`
819
+
820
+ ### `action_mode invalid`
821
+
822
+ 原因:
823
+
824
+ - `action_mode` 与当前操作不匹配
825
+
826
+ 处理:
827
+
828
+ - 删除子节点通常对应 `child`
829
+ - 删除根层级节点通常需要通过相邻节点推导 `sibling`
830
+ - 该逻辑已经封装在 `yuque_delete_toc_node` 中
831
+
832
+ ### `getaddrinfo ENOTFOUND www.yuque.com`
833
+
834
+ 原因:
835
+
836
+ - 当前运行环境没有网络
837
+ - 被沙箱或代理限制
838
+
839
+ 处理:
840
+
841
+ - 在允许联网的环境执行真实联调
842
+ - 在 Codex 中如遇沙箱网络限制,需要提权后重跑
843
+
844
+ ### 工具新增后当前会话里看不到
845
+
846
+ 原因:
847
+
848
+ - MCP 配置已更新,但当前会话工具面没有热刷新
849
+
850
+ 处理:
851
+
852
+ - 重启 Codex
853
+ - 重启后重新进入会话,再次调用新工具
854
+
855
+ ## 项目结构
856
+
857
+ ```text
858
+ src/
859
+ config.js
860
+ index.js
861
+ server.js
862
+ tools.js
863
+ yuque-client.js
864
+
865
+ tests/
866
+ tools.test.js
867
+ yuque-client.test.js
868
+ ```
869
+
870
+ ## 开发说明
871
+
872
+ 核心实现位置:
873
+
874
+ - 配置读取:[src/config.js](/Users/program/code/code_mcp/yuque-mcp-plus/src/config.js)
875
+ - MCP 服务入口:[src/server.js](/Users/program/code/code_mcp/yuque-mcp-plus/src/server.js)
876
+ - 工具定义与分发:[src/tools.js](/Users/program/code/code_mcp/yuque-mcp-plus/src/tools.js)
877
+ - 语雀 API 客户端:[src/yuque-client.js](/Users/program/code/code_mcp/yuque-mcp-plus/src/yuque-client.js)
878
+
879
+ 测试文件:
880
+
881
+ - [tests/tools.test.js](/Users/program/code/code_mcp/yuque-mcp-plus/tests/tools.test.js)
882
+ - [tests/yuque-client.test.js](/Users/program/code/code_mcp/yuque-mcp-plus/tests/yuque-client.test.js)