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/RELEASE.md ADDED
@@ -0,0 +1,105 @@
1
+ # Release Guide
2
+
3
+ 默认参考日期格式使用 `YYYY-MM-DD`。
4
+
5
+ ## 发布前检查
6
+
7
+ 发布前至少完成这些检查:
8
+
9
+ - 确认 [package.json](/Users/program/code/code_mcp/yuque-mcp-plus/package.json) 的 `version` 已更新
10
+ - 确认 [CHANGELOG.md](/Users/program/code/code_mcp/yuque-mcp-plus/CHANGELOG.md) 已补充本次变更
11
+ - 确认 [README.md](/Users/program/code/code_mcp/yuque-mcp-plus/README.md) 和 [README.en.md](/Users/program/code/code_mcp/yuque-mcp-plus/README.en.md) 已同步
12
+ - 运行 `npm run check`
13
+ - 运行 `npm test`
14
+
15
+ ## 建议发布步骤
16
+
17
+ ### 1. 更新版本
18
+
19
+ 修改:
20
+
21
+ - [package.json](/Users/program/code/code_mcp/yuque-mcp-plus/package.json)
22
+ - [CHANGELOG.md](/Users/program/code/code_mcp/yuque-mcp-plus/CHANGELOG.md)
23
+
24
+ 建议规则:
25
+
26
+ - 新增功能但不破坏兼容:升 `minor`
27
+ - 纯文档或修复小问题:升 `patch`
28
+ - 存在不兼容改动:升 `major`
29
+
30
+ ### 2. 执行本地验证
31
+
32
+ ```bash
33
+ npm run check
34
+ npm test
35
+ ```
36
+
37
+ 如果这一步失败,不要发布。
38
+
39
+ ### 3. 执行真实联调回归
40
+
41
+ 建议至少回归这些能力:
42
+
43
+ - `yuque_get_default_repository`
44
+ - `yuque_get_repository_toc_tree`
45
+ - `yuque_create_toc_node`
46
+ - `yuque_delete_toc_node`
47
+ - `yuque_create_doc`
48
+ - `yuque_move_document`
49
+
50
+ 如果这次改动涉及团队、版本或统计,再额外回归对应工具。
51
+
52
+ ### 4. 更新发布说明
53
+
54
+ 在 [CHANGELOG.md](/Users/program/code/code_mcp/yuque-mcp-plus/CHANGELOG.md) 中记录:
55
+
56
+ - 新增工具
57
+ - 行为变化
58
+ - 兼容性说明
59
+ - 已验证范围
60
+
61
+ ### 5. 打标签或对外发布
62
+
63
+ 如果你的发布流程需要 Git 标签,建议格式:
64
+
65
+ ```bash
66
+ git tag v0.2.0
67
+ ```
68
+
69
+ 如果后续接 npm 或内部制品库,再补对应发布命令。
70
+
71
+ ## 升级说明模板
72
+
73
+ 可以按这个格式写每次升级说明:
74
+
75
+ ```md
76
+ ## v0.2.0
77
+
78
+ ### Added
79
+ - 新增 `yuque_delete_toc_node`
80
+ - 新增根节点自动删除策略
81
+
82
+ ### Changed
83
+ - README 改为默认中文
84
+ - 补充中英文速查示例
85
+
86
+ ### Verified
87
+ - npm run check
88
+ - npm test
89
+ - 真实 Yuque 联调
90
+ ```
91
+
92
+ ## 回滚建议
93
+
94
+ 如果新版本有问题,优先按这个顺序处理:
95
+
96
+ - 切回上一个稳定版本的代码
97
+ - 恢复上一个稳定版本的 `package.json` 版本号和文档
98
+ - 重新验证 `npm run check` 与 `npm test`
99
+ - 如果问题来自真实 API 行为变化,优先在 [README.md](/Users/program/code/code_mcp/yuque-mcp-plus/README.md) 记录临时限制
100
+
101
+ ## 当前版本
102
+
103
+ 当前项目版本:
104
+
105
+ - `0.2.0`
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "yuque-mcp-plus",
3
+ "version": "0.2.0",
4
+ "description": "Enhanced Yuque MCP server with default repo, TOC tree, parentUuid, and move support.",
5
+ "author": "michaeljou <864738795@qq.com>",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+ssh://git@github.com/MichealJou/yuque-mcp-plus.git"
11
+ },
12
+ "homepage": "https://github.com/MichealJou/yuque-mcp-plus#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/MichealJou/yuque-mcp-plus/issues"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "yuque",
19
+ "model-context-protocol",
20
+ "docs",
21
+ "knowledge-base"
22
+ ],
23
+ "bin": {
24
+ "yuque-mcp-plus": "./src/index.js"
25
+ },
26
+ "files": [
27
+ "src",
28
+ "README.md",
29
+ "README.en.md",
30
+ "CHANGELOG.md",
31
+ "RELEASE.md"
32
+ ],
33
+ "scripts": {
34
+ "start": "node ./src/index.js",
35
+ "check": "node --eval \"import('./src/server.js')\"",
36
+ "test": "node --test",
37
+ "pack:check": "npm pack --dry-run"
38
+ },
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.17.4",
44
+ "axios": "^1.12.2"
45
+ }
46
+ }
package/src/config.js ADDED
@@ -0,0 +1,37 @@
1
+ const DEFAULT_API_BASE_URL = "https://www.yuque.com/api/v2";
2
+ const DEFAULT_TIMEOUT_MS = 30000;
3
+ const DEFAULT_RETRIES = 3;
4
+
5
+ function readNumberEnv(name, fallback) {
6
+ const raw = process.env[name];
7
+ if (!raw) {
8
+ return fallback;
9
+ }
10
+
11
+ const value = Number.parseInt(raw, 10);
12
+ return Number.isFinite(value) ? value : fallback;
13
+ }
14
+
15
+ export function getConfig() {
16
+ const token = process.env.YUQUE_TOKEN;
17
+
18
+ return {
19
+ token,
20
+ apiBaseUrl: process.env.YUQUE_API_BASE_URL || DEFAULT_API_BASE_URL,
21
+ timeoutMs: readNumberEnv("YUQUE_TIMEOUT_MS", DEFAULT_TIMEOUT_MS),
22
+ retries: readNumberEnv("YUQUE_RETRIES", DEFAULT_RETRIES),
23
+ defaultRepoId: process.env.YUQUE_DEFAULT_REPO_ID || "",
24
+ defaultRepoNamespace: process.env.YUQUE_DEFAULT_REPO_NAMESPACE || ""
25
+ };
26
+ }
27
+
28
+ export function validateConfig(config = getConfig()) {
29
+ if (!config.token) {
30
+ return {
31
+ isValid: false,
32
+ error: "Missing YUQUE_TOKEN"
33
+ };
34
+ }
35
+
36
+ return { isValid: true };
37
+ }
package/src/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { pathToFileURL } from "node:url";
3
+ import { startServer } from "./server.js";
4
+
5
+ async function main() {
6
+ await startServer();
7
+ }
8
+
9
+ const isDirectRun =
10
+ process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;
11
+
12
+ if (isDirectRun) {
13
+ main().catch((error) => {
14
+ console.error("Failed to start yuque-mcp-plus:", error);
15
+ process.exit(1);
16
+ });
17
+ }
package/src/server.js ADDED
@@ -0,0 +1,55 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import {
4
+ CallToolRequestSchema,
5
+ ErrorCode,
6
+ ListToolsRequestSchema,
7
+ McpError
8
+ } from "@modelcontextprotocol/sdk/types.js";
9
+ import { getConfig, validateConfig } from "./config.js";
10
+ import { TOOLS, handleTool } from "./tools.js";
11
+ import { YuqueClient } from "./yuque-client.js";
12
+
13
+ export function createServer() {
14
+ const config = getConfig();
15
+ const validation = validateConfig(config);
16
+
17
+ if (!validation.isValid) {
18
+ throw new Error(validation.error);
19
+ }
20
+
21
+ const server = new Server(
22
+ {
23
+ name: "yuque-mcp-plus",
24
+ version: "0.2.0"
25
+ },
26
+ {
27
+ capabilities: {
28
+ tools: {}
29
+ }
30
+ }
31
+ );
32
+
33
+ const client = new YuqueClient(config);
34
+
35
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
36
+ tools: TOOLS
37
+ }));
38
+
39
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
40
+ try {
41
+ return await handleTool(request.params.name, request.params.arguments || {}, client);
42
+ } catch (error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ throw new McpError(ErrorCode.InternalError, message);
45
+ }
46
+ });
47
+
48
+ return server;
49
+ }
50
+
51
+ export async function startServer() {
52
+ const server = createServer();
53
+ const transport = new StdioServerTransport();
54
+ await server.connect(transport);
55
+ }