@page.su/ai-blog-cli 0.1.0-beta.1

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 (146) hide show
  1. package/README.md +145 -0
  2. package/dist/api-client.d.ts +39 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +163 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/api-client.test.d.ts +2 -0
  7. package/dist/api-client.test.d.ts.map +1 -0
  8. package/dist/api-client.test.js +83 -0
  9. package/dist/api-client.test.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +74 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/commands/build.d.ts +4 -0
  15. package/dist/commands/build.d.ts.map +1 -0
  16. package/dist/commands/build.js +158 -0
  17. package/dist/commands/build.js.map +1 -0
  18. package/dist/commands/code-repo.d.ts +4 -0
  19. package/dist/commands/code-repo.d.ts.map +1 -0
  20. package/dist/commands/code-repo.js +102 -0
  21. package/dist/commands/code-repo.js.map +1 -0
  22. package/dist/commands/comments.d.ts +4 -0
  23. package/dist/commands/comments.d.ts.map +1 -0
  24. package/dist/commands/comments.js +53 -0
  25. package/dist/commands/comments.js.map +1 -0
  26. package/dist/commands/demo.d.ts +4 -0
  27. package/dist/commands/demo.d.ts.map +1 -0
  28. package/dist/commands/demo.js +72 -0
  29. package/dist/commands/demo.js.map +1 -0
  30. package/dist/commands/helpers.d.ts +21 -0
  31. package/dist/commands/helpers.d.ts.map +1 -0
  32. package/dist/commands/helpers.js +66 -0
  33. package/dist/commands/helpers.js.map +1 -0
  34. package/dist/commands/knowledge.d.ts +4 -0
  35. package/dist/commands/knowledge.d.ts.map +1 -0
  36. package/dist/commands/knowledge.js +146 -0
  37. package/dist/commands/knowledge.js.map +1 -0
  38. package/dist/commands/post.d.ts +4 -0
  39. package/dist/commands/post.d.ts.map +1 -0
  40. package/dist/commands/post.js +207 -0
  41. package/dist/commands/post.js.map +1 -0
  42. package/dist/commands/scout.d.ts +4 -0
  43. package/dist/commands/scout.d.ts.map +1 -0
  44. package/dist/commands/scout.js +48 -0
  45. package/dist/commands/scout.js.map +1 -0
  46. package/dist/commands/series.d.ts +4 -0
  47. package/dist/commands/series.d.ts.map +1 -0
  48. package/dist/commands/series.js +101 -0
  49. package/dist/commands/series.js.map +1 -0
  50. package/dist/commands/skills.d.ts +3 -0
  51. package/dist/commands/skills.d.ts.map +1 -0
  52. package/dist/commands/skills.js +79 -0
  53. package/dist/commands/skills.js.map +1 -0
  54. package/dist/commands/taxonomy.d.ts +4 -0
  55. package/dist/commands/taxonomy.d.ts.map +1 -0
  56. package/dist/commands/taxonomy.js +52 -0
  57. package/dist/commands/taxonomy.js.map +1 -0
  58. package/dist/commands/uploads.d.ts +4 -0
  59. package/dist/commands/uploads.d.ts.map +1 -0
  60. package/dist/commands/uploads.js +37 -0
  61. package/dist/commands/uploads.js.map +1 -0
  62. package/dist/config.d.ts +19 -0
  63. package/dist/config.d.ts.map +1 -0
  64. package/dist/config.js +84 -0
  65. package/dist/config.js.map +1 -0
  66. package/dist/config.test.d.ts +2 -0
  67. package/dist/config.test.d.ts.map +1 -0
  68. package/dist/config.test.js +53 -0
  69. package/dist/config.test.js.map +1 -0
  70. package/dist/index.d.ts +3 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +100 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/prompts/index.d.ts +9 -0
  75. package/dist/prompts/index.d.ts.map +1 -0
  76. package/dist/prompts/index.js +178 -0
  77. package/dist/prompts/index.js.map +1 -0
  78. package/dist/resources/syntax-spec.d.ts +23 -0
  79. package/dist/resources/syntax-spec.d.ts.map +1 -0
  80. package/dist/resources/syntax-spec.js +105 -0
  81. package/dist/resources/syntax-spec.js.map +1 -0
  82. package/dist/resources/syntax-spec.test.d.ts +2 -0
  83. package/dist/resources/syntax-spec.test.d.ts.map +1 -0
  84. package/dist/resources/syntax-spec.test.js +47 -0
  85. package/dist/resources/syntax-spec.test.js.map +1 -0
  86. package/dist/tools/build.d.ts +13 -0
  87. package/dist/tools/build.d.ts.map +1 -0
  88. package/dist/tools/build.js +181 -0
  89. package/dist/tools/build.js.map +1 -0
  90. package/dist/tools/code-repos.d.ts +5 -0
  91. package/dist/tools/code-repos.d.ts.map +1 -0
  92. package/dist/tools/code-repos.js +149 -0
  93. package/dist/tools/code-repos.js.map +1 -0
  94. package/dist/tools/comments.d.ts +12 -0
  95. package/dist/tools/comments.d.ts.map +1 -0
  96. package/dist/tools/comments.js +87 -0
  97. package/dist/tools/comments.js.map +1 -0
  98. package/dist/tools/demos.d.ts +5 -0
  99. package/dist/tools/demos.d.ts.map +1 -0
  100. package/dist/tools/demos.js +98 -0
  101. package/dist/tools/demos.js.map +1 -0
  102. package/dist/tools/glossary.d.ts +4 -0
  103. package/dist/tools/glossary.d.ts.map +1 -0
  104. package/dist/tools/glossary.js +139 -0
  105. package/dist/tools/glossary.js.map +1 -0
  106. package/dist/tools/helpers.d.ts +44 -0
  107. package/dist/tools/helpers.d.ts.map +1 -0
  108. package/dist/tools/helpers.js +65 -0
  109. package/dist/tools/helpers.js.map +1 -0
  110. package/dist/tools/knowledge.d.ts +4 -0
  111. package/dist/tools/knowledge.d.ts.map +1 -0
  112. package/dist/tools/knowledge.js +140 -0
  113. package/dist/tools/knowledge.js.map +1 -0
  114. package/dist/tools/math-concepts.d.ts +4 -0
  115. package/dist/tools/math-concepts.d.ts.map +1 -0
  116. package/dist/tools/math-concepts.js +158 -0
  117. package/dist/tools/math-concepts.js.map +1 -0
  118. package/dist/tools/posts.d.ts +35 -0
  119. package/dist/tools/posts.d.ts.map +1 -0
  120. package/dist/tools/posts.js +278 -0
  121. package/dist/tools/posts.js.map +1 -0
  122. package/dist/tools/scout.d.ts +10 -0
  123. package/dist/tools/scout.d.ts.map +1 -0
  124. package/dist/tools/scout.js +111 -0
  125. package/dist/tools/scout.js.map +1 -0
  126. package/dist/tools/series.d.ts +12 -0
  127. package/dist/tools/series.d.ts.map +1 -0
  128. package/dist/tools/series.js +120 -0
  129. package/dist/tools/series.js.map +1 -0
  130. package/dist/tools/syntax-capabilities.d.ts +15 -0
  131. package/dist/tools/syntax-capabilities.d.ts.map +1 -0
  132. package/dist/tools/syntax-capabilities.js +859 -0
  133. package/dist/tools/syntax-capabilities.js.map +1 -0
  134. package/dist/tools/taxonomy.d.ts +4 -0
  135. package/dist/tools/taxonomy.d.ts.map +1 -0
  136. package/dist/tools/taxonomy.js +73 -0
  137. package/dist/tools/taxonomy.js.map +1 -0
  138. package/dist/tools/uploads.d.ts +15 -0
  139. package/dist/tools/uploads.d.ts.map +1 -0
  140. package/dist/tools/uploads.js +56 -0
  141. package/dist/tools/uploads.js.map +1 -0
  142. package/dist/tools/workflows.d.ts +9 -0
  143. package/dist/tools/workflows.d.ts.map +1 -0
  144. package/dist/tools/workflows.js +249 -0
  145. package/dist/tools/workflows.js.map +1 -0
  146. package/package.json +41 -0
@@ -0,0 +1,149 @@
1
+ import { z } from "zod";
2
+ import { toolReplyHelpers } from "./helpers.js";
3
+ /**
4
+ * 代码仓库相关 MCP 工具:
5
+ * post.get_code_repo / post.upsert_code_repo / post.delete_code_repo / post.patch_code_file
6
+ * code_repo.list / post.link_code_repo / code_repo.get_links
7
+ *
8
+ * 设计原则:
9
+ * - 工具的入参 schema 用 zod raw shape 形态
10
+ * - upsert_code_repo 是幂等操作,文章已有关联仓库则更新,否则创建新仓库并关联
11
+ * - 一篇文章最多关联一个仓库,一个仓库可被多篇文章共享
12
+ * - code_repo.list + post.link_code_repo 让 Agent 可搜索并复用已有仓库
13
+ * - tool 的返回统一打包为 { content: [{ type: "text", text: <json> }] }
14
+ */
15
+ const { safe } = toolReplyHelpers;
16
+ /** 注册全部代码仓库相关工具 */
17
+ export function registerCodeRepoTools(server, api) {
18
+ // ─── post.get_code_repo ───────────────────────────────────────────────
19
+ server.registerTool("post.get_code_repo", {
20
+ title: "Get code repository",
21
+ description: "获取指定文章关联的代码仓库,包含所有文件的完整内容。" +
22
+ "一篇文章最多关联一个代码仓库,一个仓库可被多篇文章共享。" +
23
+ "返回的 files 数组中每项包含 path(支持文件夹层级)和 content。",
24
+ inputSchema: {
25
+ id: z.string().describe("文章 id (uuid)"),
26
+ },
27
+ }, async ({ id }) => safe(() => api.get(`/api/mcp/posts/${encodeURIComponent(id)}/code`)));
28
+ // ─── post.upsert_code_repo ────────────────────────────────────────────
29
+ server.registerTool("post.upsert_code_repo", {
30
+ title: "Create or update code repository",
31
+ description: "创建或更新文章关联的代码仓库。如果该文章已有关联仓库则更新,否则创建新仓库并关联。" +
32
+ "一篇文章最多关联一个仓库。files 数组中每项的 path 支持文件夹层级(如 'src/components/Button.tsx')。" +
33
+ "⚠️ path 必须为相对路径,禁止以 / 开头或包含 ..。" +
34
+ "💡 如果想复用已有仓库而非创建新的,请先用 code_repo.list 搜索,再用 post.link_code_repo 关联。",
35
+ inputSchema: {
36
+ id: z.string().describe("文章 id (uuid)"),
37
+ title: z.string().max(255).optional().describe("仓库展示名称"),
38
+ description: z.string().optional().describe("仓库描述"),
39
+ defaultFilePath: z
40
+ .string()
41
+ .optional()
42
+ .describe("默认打开的文件路径,如 'README.md'"),
43
+ meta: z
44
+ .object({
45
+ branch: z.string().optional().describe("展示用分支名"),
46
+ license: z.string().optional().describe("展示用许可证"),
47
+ repoUrl: z.string().optional().describe("关联的外部仓库链接"),
48
+ })
49
+ .optional()
50
+ .describe("仓库元信息"),
51
+ files: z
52
+ .array(z.object({
53
+ path: z
54
+ .string()
55
+ .describe("文件相对路径,如 'src/index.ts'(禁止绝对路径或 ..)"),
56
+ content: z.string().describe("文件内容"),
57
+ }))
58
+ .min(1)
59
+ .describe("代码文件列表,至少包含一个文件"),
60
+ },
61
+ }, async ({ id, title, description, defaultFilePath, meta, files }) => safe(() => api.post(`/api/mcp/posts/${encodeURIComponent(id)}/code`, {
62
+ title,
63
+ description,
64
+ defaultFilePath,
65
+ meta,
66
+ files,
67
+ })));
68
+ // ─── post.delete_code_repo ────────────────────────────────────────────
69
+ server.registerTool("post.delete_code_repo", {
70
+ title: "Delete code repository",
71
+ description: "解除文章与代码仓库的关联。若文章是仓库的唯一所有者,则同时删除仓库。文章本身不受影响。" +
72
+ "💡 解除前可用 code_repo.get_links 确认是否有其他文章共享此仓库。",
73
+ inputSchema: {
74
+ id: z.string().describe("文章 id (uuid)"),
75
+ },
76
+ }, async ({ id }) => safe(() => api.delete(`/api/mcp/posts/${encodeURIComponent(id)}/code`)));
77
+ // ─── code_repo.list ─────────────────────────────────────────────────────
78
+ server.registerTool("code_repo.list", {
79
+ title: "List code repositories",
80
+ description: "列出所有代码仓库(支持搜索和分页)。" +
81
+ "用于发现可复用的已有仓库,避免重复创建。" +
82
+ "返回每个仓库的 id、标题、文件数和被关联的文章数量。",
83
+ inputSchema: {
84
+ search: z.string().optional().describe("按标题模糊搜索"),
85
+ page: z.number().int().min(1).optional().describe("页码,默认 1"),
86
+ pageSize: z
87
+ .number()
88
+ .int()
89
+ .min(1)
90
+ .max(50)
91
+ .optional()
92
+ .describe("每页条数,默认 20"),
93
+ },
94
+ }, async ({ search, page, pageSize }) => {
95
+ const params = new URLSearchParams();
96
+ if (search)
97
+ params.set("search", search);
98
+ if (page)
99
+ params.set("page", String(page));
100
+ if (pageSize)
101
+ params.set("pageSize", String(pageSize));
102
+ const qs = params.toString();
103
+ return safe(() => api.get(`/api/mcp/code-repos${qs ? `?${qs}` : ""}`));
104
+ });
105
+ // ─── post.link_code_repo ────────────────────────────────────────────────
106
+ server.registerTool("post.link_code_repo", {
107
+ title: "Link article to existing code repository",
108
+ description: "将文章关联到一个已有的代码仓库(不创建新仓库)。" +
109
+ "适用于系列文章共享同一个代码库的场景。" +
110
+ "一篇文章最多关联一个仓库,若已有关联需先解除。" +
111
+ "先用 code_repo.list 搜索可复用的仓库,再用此工具关联。",
112
+ inputSchema: {
113
+ id: z.string().describe("文章 id (uuid)"),
114
+ codeRepoId: z
115
+ .string()
116
+ .describe("要关联的仓库 id (uuid),从 code_repo.list 获取"),
117
+ },
118
+ }, async ({ id, codeRepoId }) => safe(() => api.post(`/api/mcp/posts/${encodeURIComponent(id)}/code/link`, {
119
+ codeRepoId,
120
+ })));
121
+ // ─── code_repo.get_links ────────────────────────────────────────────────
122
+ server.registerTool("code_repo.get_links", {
123
+ title: "Get articles linked to a code repository",
124
+ description: "查看某个代码仓库被哪些文章关联。" +
125
+ "用于了解仓库的共享情况,避免误删正在被使用的仓库。",
126
+ inputSchema: {
127
+ repoId: z.string().describe("仓库 id (uuid)"),
128
+ },
129
+ }, async ({ repoId }) => safe(() => api.get(`/api/mcp/code-repos/${encodeURIComponent(repoId)}/links`)));
130
+ // ─── post.patch_code_file ─────────────────────────────────────────────
131
+ server.registerTool("post.patch_code_file", {
132
+ title: "Update a single file in code repository",
133
+ description: "更新代码仓库中的单个文件内容(不影响其他文件)。" +
134
+ "⚠️ 修改单个文件的首选方式,无需重传整个仓库。" +
135
+ "先用 post.get_code_repo 查看现有文件列表,修改后用此工具写回。",
136
+ inputSchema: {
137
+ id: z.string().describe("文章 id (uuid)"),
138
+ filePath: z
139
+ .string()
140
+ .min(1)
141
+ .describe("要更新的文件路径(与仓库中的 path 一致),如 'src/index.ts'"),
142
+ content: z.string().describe("该文件的新内容"),
143
+ },
144
+ }, async ({ id, filePath, content }) => safe(() => api.patch(`/api/mcp/posts/${encodeURIComponent(id)}/code/file`, {
145
+ filePath,
146
+ content,
147
+ })));
148
+ }
149
+ //# sourceMappingURL=code-repos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-repos.js","sourceRoot":"","sources":["../../src/tools/code-repos.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ApiClient } from "../api-client.js";
3
+ /**
4
+ * 评论相关 MCP 工具:comment.create。
5
+ *
6
+ * 支持:
7
+ * - 在指定文章下创建一级评论(仅传 postId + content)
8
+ * - 回复指定评论(额外传 parentId)
9
+ */
10
+ /** 注册评论相关 MCP 工具 */
11
+ export declare function registerCommentTools(server: McpServer, api: ApiClient): void;
12
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;;;GAMG;AAEH,oBAAoB;AACpB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAiG5E"}
@@ -0,0 +1,87 @@
1
+ import { z } from "zod";
2
+ import { safe } from "./helpers.js";
3
+ /**
4
+ * 评论相关 MCP 工具:comment.create。
5
+ *
6
+ * 支持:
7
+ * - 在指定文章下创建一级评论(仅传 postId + content)
8
+ * - 回复指定评论(额外传 parentId)
9
+ */
10
+ /** 注册评论相关 MCP 工具 */
11
+ export function registerCommentTools(server, api) {
12
+ // ─── comment.create ────────────────────────────────────────────────────
13
+ server.registerTool("comment.create", {
14
+ title: "Create comment",
15
+ description: "在指定文章下创建一级评论,或回复已有评论。" +
16
+ "创建一级评论只需传 postId + content;" +
17
+ "回复某条评论需额外传 parentId(被回复评论的 UUID)。" +
18
+ "content 支持 Markdown 格式,长度 1-5000 字符。",
19
+ inputSchema: {
20
+ postId: z.string().uuid().describe("目标文章 ID(UUID)"),
21
+ parentId: z
22
+ .string()
23
+ .uuid()
24
+ .nullable()
25
+ .describe("要回复的评论 ID(UUID);创建一级评论时传 null 或不传")
26
+ .optional(),
27
+ content: z
28
+ .string()
29
+ .min(1)
30
+ .max(5000)
31
+ .describe("评论内容,支持 Markdown,1-5000 字符"),
32
+ },
33
+ }, async ({ postId, parentId, content }) => safe(() => api.post("/api/mcp/comments", {
34
+ postId,
35
+ parentId: parentId ?? null,
36
+ content,
37
+ })));
38
+ // ─── comment.ai_generate ──────────────────────────────────────────────
39
+ server.registerTool("comment.ai_generate", {
40
+ title: "Generate AI comment",
41
+ description: "使用指定的 AI Bot 对文章生成一条评论。" +
42
+ "可通过 botId(UUID)或 botSlug(如 tech-observer)指定机器人。" +
43
+ "生成的评论默认为草稿状态(需后台审核),除非 Bot 配置了自动发布或传入 autoApprove=true。" +
44
+ "可选传入 instruction 引导评论方向,parentId 可回复已有评论。",
45
+ inputSchema: {
46
+ botId: z
47
+ .string()
48
+ .uuid()
49
+ .optional()
50
+ .describe("Bot UUID。与 botSlug 二选一"),
51
+ botSlug: z
52
+ .string()
53
+ .optional()
54
+ .describe("Bot slug(如 tech-observer)。与 botId 二选一"),
55
+ postId: z.string().uuid().describe("目标文章 ID(UUID)"),
56
+ instruction: z
57
+ .string()
58
+ .max(500)
59
+ .optional()
60
+ .describe("额外指令,引导 AI 评论方向(可选)"),
61
+ parentId: z
62
+ .string()
63
+ .uuid()
64
+ .nullable()
65
+ .optional()
66
+ .describe("要回复的评论 ID(UUID);对文章直接评论时不传"),
67
+ autoApprove: z
68
+ .boolean()
69
+ .optional()
70
+ .describe("是否跳过审核直接发布(覆盖 Bot 默认配置)"),
71
+ },
72
+ }, async ({ botId, botSlug, postId, instruction, parentId, autoApprove }) => safe(() => api.post("/api/mcp/ai-comments", {
73
+ botId,
74
+ botSlug,
75
+ postId,
76
+ instruction,
77
+ parentId: parentId ?? null,
78
+ autoApprove,
79
+ })));
80
+ // ─── comment.ai_list_bots ─────────────────────────────────────────────
81
+ server.registerTool("comment.ai_list_bots", {
82
+ title: "List AI bots",
83
+ description: "列出所有已启用的 AI 评论机器人,返回 id / slug / name / provider / model。",
84
+ inputSchema: {},
85
+ }, async () => safe(() => api.get("/api/mcp/ai-comments")));
86
+ }
87
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ApiClient } from "../api-client.js";
3
+ /** 注册全部 Demo 相关工具 */
4
+ export declare function registerDemoTools(server: McpServer, api: ApiClient): void;
5
+ //# sourceMappingURL=demos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demos.d.ts","sourceRoot":"","sources":["../../src/tools/demos.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAalD,qBAAqB;AACrB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAsIzE"}
@@ -0,0 +1,98 @@
1
+ import { z } from "zod";
2
+ import { toolReplyHelpers } from "./posts.js";
3
+ /**
4
+ * Demo 相关 MCP 工具:post.list_demos / get_demo / upsert_demo / delete_demo。
5
+ *
6
+ * 设计原则:
7
+ * - 工具的入参 schema 用 zod raw shape 形态
8
+ * - upsert_demo 是幂等操作,按 postId+slot 匹配
9
+ * - tool 的返回统一打包为 `{ content: [{ type: "text", text: <json> }] }`
10
+ */
11
+ const { safe } = toolReplyHelpers;
12
+ /** 注册全部 Demo 相关工具 */
13
+ export function registerDemoTools(server, api) {
14
+ // ─── post.list_demos ─────────────────────────────────────────────────────
15
+ server.registerTool("post.list_demos", {
16
+ title: "List all demos of a post",
17
+ description: "列出指定文章的所有 Demo,返回每个 Demo 的 slot、title 等基本信息。",
18
+ inputSchema: {
19
+ id: z.string().describe("文章 id (uuid)"),
20
+ },
21
+ }, async ({ id }) => safe(() => api.get(`/api/mcp/posts/${encodeURIComponent(id)}/demos`)));
22
+ // ─── post.get_demo ───────────────────────────────────────────────────────
23
+ server.registerTool("post.get_demo", {
24
+ title: "Get demo source code",
25
+ description: "获取指定文章的某个 Demo 的完整源码,包括 meta 和所有 files。" +
26
+ "⚠️ 会一次性返回 Demo 全部文件内容。如果 Demo 较大或只需查看/修改单个文件," +
27
+ "推荐改用 post.get_demo_file 按文件名读取。",
28
+ inputSchema: {
29
+ id: z.string().describe("文章 id (uuid)"),
30
+ slot: z.string().describe("Demo 的 slot 标识"),
31
+ },
32
+ }, async ({ id, slot }) => safe(() => api.get(`/api/mcp/posts/${encodeURIComponent(id)}/demos/${encodeURIComponent(slot)}`)));
33
+ // ─── post.upsert_demo ────────────────────────────────────────────────────
34
+ server.registerTool("post.upsert_demo", {
35
+ title: "Create or update a demo",
36
+ description: "创建或更新文章的 Demo。这是一个幂等操作:如果存在相同 postId+slot 的 Demo 则更新,否则创建新 Demo。" +
37
+ "⚠️ Demo 代码独立存储,文章正文通过 {{demo:slot-name}} 占位符引用。" +
38
+ "修改 Demo 单个文件用 post.patch_demo_file 更高效,无需重传所有文件。",
39
+ inputSchema: {
40
+ id: z.string().describe("文章 id (uuid)"),
41
+ slot: z
42
+ .string()
43
+ .min(1)
44
+ .max(128)
45
+ .describe("Demo 的 slot 标识,1-128 字符"),
46
+ title: z.string().optional().describe("Demo 标题"),
47
+ meta: z
48
+ .object({
49
+ tailwind: z.boolean().optional().describe("是否启用 Tailwind Play CDN"),
50
+ cdn: z.array(z.string()).optional().describe("外部 CDN URL 列表"),
51
+ height: z.number().int().optional().describe("iframe 初始高度(像素)"),
52
+ })
53
+ .optional()
54
+ .describe("Demo 元数据配置"),
55
+ files: z
56
+ .array(z.object({
57
+ name: z.string().describe("文件名(含扩展名),如 index.html"),
58
+ content: z.string().describe("文件内容"),
59
+ }))
60
+ .describe("Demo 的文件列表"),
61
+ },
62
+ }, async ({ id, slot, title, meta, files }) => safe(() => api.post(`/api/mcp/posts/${encodeURIComponent(id)}/demos`, { slot, title, meta, files })));
63
+ // ─── post.get_demo_file ─────────────────────────────────────────────────
64
+ server.registerTool("post.get_demo_file", {
65
+ title: "Read a single file from a demo",
66
+ description: "读取 Demo 中的单个文件内容(不加载其他文件)。" +
67
+ "⚠️ Demo 较大时(>5000字),优先用此工具按文件名读取,避免 post.get_demo 全量加载。" +
68
+ "文件名可从 post.list_demos 返回的 files 列表中获取(含每个文件的 contentLength)。",
69
+ inputSchema: {
70
+ id: z.string().describe("文章 id (uuid)"),
71
+ slot: z.string().describe("Demo 的 slot 标识"),
72
+ fileName: z.string().min(1).describe("要读取的文件名(含扩展名),如 'app.js'"),
73
+ },
74
+ }, async ({ id, slot, fileName }) => safe(() => api.get(`/api/mcp/posts/${encodeURIComponent(id)}/demos/${encodeURIComponent(slot)}/file`, { name: fileName })));
75
+ // ─── post.patch_demo_file ─────────────────────────────────────────────────
76
+ server.registerTool("post.patch_demo_file", {
77
+ title: "Update a single file in a demo",
78
+ description: "更新 Demo 中的单个文件内容(不影响其他文件)。" +
79
+ "⚠️ 修改 Demo 的首选方式。先用 post.get_demo_file 读取目标文件,修改后用此工具写回。" +
80
+ "无需重传 Demo 的其他文件。",
81
+ inputSchema: {
82
+ id: z.string().describe("文章 id (uuid)"),
83
+ slot: z.string().describe("Demo 的 slot 标识"),
84
+ fileName: z.string().min(1).describe("要更新的文件名(含扩展名),如 'app.js'"),
85
+ content: z.string().describe("该文件的新内容"),
86
+ },
87
+ }, async ({ id, slot, fileName, content }) => safe(() => api.patch(`/api/mcp/posts/${encodeURIComponent(id)}/demos/${encodeURIComponent(slot)}/file`, { fileName, content })));
88
+ // ─── post.delete_demo ────────────────────────────────────────────────────
89
+ server.registerTool("post.delete_demo", {
90
+ title: "Delete a demo",
91
+ description: "删除指定文章的某个 Demo。",
92
+ inputSchema: {
93
+ id: z.string().describe("文章 id (uuid)"),
94
+ slot: z.string().describe("Demo 的 slot 标识"),
95
+ },
96
+ }, async ({ id, slot }) => safe(() => api.delete(`/api/mcp/posts/${encodeURIComponent(id)}/demos/${encodeURIComponent(slot)}`)));
97
+ }
98
+ //# sourceMappingURL=demos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demos.js","sourceRoot":"","sources":["../../src/tools/demos.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ApiClient } from "../api-client.js";
3
+ export declare function registerGlossaryTools(server: McpServer, api: ApiClient): void;
4
+ //# sourceMappingURL=glossary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.d.ts","sourceRoot":"","sources":["../../src/tools/glossary.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA4DlE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAuG7E"}
@@ -0,0 +1,139 @@
1
+ import { z } from "zod";
2
+ import { ApiClientError } from "../api-client.js";
3
+ /**
4
+ * 术语词库相关 MCP 工具:glossary.list / get / create / update / delete
5
+ *
6
+ * 独立于 post 工具,因为术语有额外的 terms/brief/autoLink 字段,
7
+ * 且语义上应与文章区分,AI 使用时更清晰。
8
+ */
9
+ /** 术语字段 schema */
10
+ const glossaryFieldsShape = {
11
+ title: z.string().min(1).describe("术语标题,必填").optional(),
12
+ slug: z.string().describe("术语 slug;为空时由后端自动生成").optional(),
13
+ status: z.enum(["draft", "published"]).describe("状态").optional(),
14
+ publishedAt: z.string().describe("ISO 时间字符串").optional(),
15
+ categoryIds: z.array(z.string().uuid()).describe("分类 id 列表").optional(),
16
+ tagIds: z.array(z.string().uuid()).describe("标签 id 列表").optional(),
17
+ excerpt: z.string().describe("摘要,最长 400 字符").optional(),
18
+ content: z.string().describe("Markdown 正文,术语的完整说明").optional(),
19
+ seoTitle: z.string().describe("SEO 标题").optional(),
20
+ seoDescription: z.string().describe("SEO 描述").optional(),
21
+ terms: z.string().describe("匹配词,多个用 | 分隔,如 'Promise|Thenable'").optional(),
22
+ brief: z.string().describe("简短释义(≤200字),用于 hover tooltip").optional(),
23
+ autoLink: z.boolean().describe("是否启用自动高亮匹配").optional(),
24
+ };
25
+ function toToolText(value) {
26
+ return {
27
+ content: [
28
+ {
29
+ type: "text",
30
+ text: typeof value === "string" ? value : JSON.stringify(value, null, 2),
31
+ },
32
+ ],
33
+ };
34
+ }
35
+ function toToolError(error) {
36
+ let text;
37
+ if (error instanceof ApiClientError) {
38
+ const lines = [`HTTP ${error.status}: ${error.message}`];
39
+ if (error.issues !== undefined) {
40
+ lines.push("Validation issues:");
41
+ lines.push(JSON.stringify(error.issues, null, 2));
42
+ }
43
+ text = lines.join("\n");
44
+ }
45
+ else if (error instanceof Error) {
46
+ text = error.message;
47
+ }
48
+ else {
49
+ text = String(error);
50
+ }
51
+ return {
52
+ content: [{ type: "text", text }],
53
+ isError: true,
54
+ };
55
+ }
56
+ export function registerGlossaryTools(server, api) {
57
+ // ── glossary.list ──
58
+ server.tool("glossary_list", "列出术语词库中的术语。支持按状态筛选和关键词搜索。", {
59
+ status: z.enum(["draft", "published"]).describe("按状态筛选").optional(),
60
+ search: z.string().describe("搜索关键词(匹配术语名/匹配词)").optional(),
61
+ page: z.number().int().positive().describe("页码,默认 1").optional(),
62
+ pageSize: z.number().int().positive().max(100).describe("每页数量,默认 20").optional(),
63
+ }, async ({ status, search, page, pageSize }) => {
64
+ try {
65
+ const params = new URLSearchParams();
66
+ if (status)
67
+ params.set("status", status);
68
+ if (search)
69
+ params.set("search", search);
70
+ if (page)
71
+ params.set("page", String(page));
72
+ if (pageSize)
73
+ params.set("pageSize", String(pageSize));
74
+ const result = await api.get(`/api/mcp/glossary?action=list&${params.toString()}`);
75
+ return toToolText(result);
76
+ }
77
+ catch (error) {
78
+ return toToolError(error);
79
+ }
80
+ });
81
+ // ── glossary.get ──
82
+ server.tool("glossary_get", "获取一个术语的完整可编辑数据,包含匹配词、简短释义、Markdown 正文等。", {
83
+ id: z.string().uuid().describe("术语 id (uuid)"),
84
+ }, async ({ id }) => {
85
+ try {
86
+ const result = await api.get(`/api/mcp/glossary?action=get&id=${id}`);
87
+ return toToolText(result);
88
+ }
89
+ catch (error) {
90
+ return toToolError(error);
91
+ }
92
+ });
93
+ // ── glossary.create ──
94
+ server.tool("glossary_create", "创建一个新的术语条目。terms(匹配词)和 brief(简短释义)为术语特有必填字段。", glossaryFieldsShape, async (params) => {
95
+ try {
96
+ const result = await api.post("/api/mcp/glossary", {
97
+ action: "create",
98
+ data: params,
99
+ });
100
+ return toToolText(result);
101
+ }
102
+ catch (error) {
103
+ return toToolError(error);
104
+ }
105
+ });
106
+ // ── glossary.update ──
107
+ server.tool("glossary_update", "更新一个已有的术语条目。需要传入完整字段。", {
108
+ id: z.string().uuid().describe("术语 id (uuid)"),
109
+ ...glossaryFieldsShape,
110
+ }, async ({ id, ...data }) => {
111
+ try {
112
+ const result = await api.post("/api/mcp/glossary", {
113
+ action: "update",
114
+ id,
115
+ data,
116
+ });
117
+ return toToolText(result);
118
+ }
119
+ catch (error) {
120
+ return toToolError(error);
121
+ }
122
+ });
123
+ // ── glossary.delete ──
124
+ server.tool("glossary_delete", "永久删除一个术语条目。请谨慎使用。", {
125
+ id: z.string().uuid().describe("术语 id (uuid)"),
126
+ }, async ({ id }) => {
127
+ try {
128
+ const result = await api.post("/api/mcp/glossary", {
129
+ action: "delete",
130
+ id,
131
+ });
132
+ return toToolText(result);
133
+ }
134
+ catch (error) {
135
+ return toToolError(error);
136
+ }
137
+ });
138
+ }
139
+ //# sourceMappingURL=glossary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../src/tools/glossary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * MCP 工具通用 helper 函数
3
+ * 统一处理工具返回值和错误格式,避免各工具文件重复定义
4
+ */
5
+ /**
6
+ * 将数据转换为 MCP 工具的标准文本响应格式
7
+ */
8
+ export declare function toToolText(value: unknown): {
9
+ content: Array<{
10
+ type: "text";
11
+ text: string;
12
+ }>;
13
+ };
14
+ /**
15
+ * 将错误转换为 MCP 工具的标准错误响应格式
16
+ * 对 ApiClientError 做特殊处理,输出 HTTP 状态码和校验问题
17
+ */
18
+ export declare function toToolError(error: unknown): {
19
+ content: Array<{
20
+ type: "text";
21
+ text: string;
22
+ }>;
23
+ isError: true;
24
+ };
25
+ /**
26
+ * 安全执行异步函数,自动捕获错误并转换为标准错误格式
27
+ * 用于简化工具函数的错误处理逻辑
28
+ */
29
+ export declare function safe<T>(fn: () => Promise<T>): Promise<{
30
+ content: Array<{
31
+ type: "text";
32
+ text: string;
33
+ }>;
34
+ isError?: true;
35
+ }>;
36
+ /**
37
+ * 导出统一的 helper 对象,方便导入使用
38
+ */
39
+ export declare const toolReplyHelpers: {
40
+ toToolText: typeof toToolText;
41
+ toToolError: typeof toToolError;
42
+ safe: typeof safe;
43
+ };
44
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAS7F;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG;IAC3C,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,IAAI,CAAC;CACf,CAkBA;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,CAAC,EAC1B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CAO7E;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;CAI5B,CAAC"}