@kolmopdf/mcp-server 1.0.0 → 1.0.2

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 (66) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +37 -63
  3. package/dist/index.cjs.map +1 -0
  4. package/{packages/mcp-server/dist → dist}/index.js +0 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +58 -30
  7. package/.claude-plugin/marketplace.json +0 -25
  8. package/.github/ISSUE_TEMPLATE/bug-report.yml +0 -75
  9. package/.github/workflows/ci.yml +0 -98
  10. package/.github/workflows/release.yml +0 -52
  11. package/CHANGELOG.md +0 -12
  12. package/biome.json +0 -33
  13. package/codex-skill/kolmopdf/SKILL.md +0 -108
  14. package/codex-skill/kolmopdf/references/chain-recipes.md +0 -35
  15. package/codex-skill/kolmopdf/references/parameter-glossary.md +0 -72
  16. package/doc/apidocs/Format_Conversion_API_Guide.md +0 -117
  17. package/doc/apidocs/PDF_Layout_Translation_API_Guide.md +0 -138
  18. package/doc/apidocs/PDF_Parsing_API_Guide.md +0 -364
  19. package/doc/plan/DEVELOPMENT.md +0 -896
  20. package/doc/plan/DISTRIBUTION.md +0 -377
  21. package/doc/plan/TESTING_AND_USAGE.md +0 -370
  22. package/packages/mcp-server/LICENSE +0 -21
  23. package/packages/mcp-server/README.md +0 -37
  24. package/packages/mcp-server/dist/index.cjs.map +0 -1
  25. package/packages/mcp-server/dist/index.js.map +0 -1
  26. package/packages/mcp-server/package.json +0 -54
  27. package/packages/mcp-server/src/client.ts +0 -235
  28. package/packages/mcp-server/src/config.ts +0 -62
  29. package/packages/mcp-server/src/context.ts +0 -27
  30. package/packages/mcp-server/src/errors.ts +0 -271
  31. package/packages/mcp-server/src/extract.ts +0 -102
  32. package/packages/mcp-server/src/index.ts +0 -142
  33. package/packages/mcp-server/src/pages.ts +0 -16
  34. package/packages/mcp-server/src/polling.ts +0 -84
  35. package/packages/mcp-server/src/progress.ts +0 -48
  36. package/packages/mcp-server/src/tools/check-balance.ts +0 -33
  37. package/packages/mcp-server/src/tools/convert.ts +0 -130
  38. package/packages/mcp-server/src/tools/estimate-cost.ts +0 -82
  39. package/packages/mcp-server/src/tools/get-task-status.ts +0 -24
  40. package/packages/mcp-server/src/tools/parse-pdf.ts +0 -147
  41. package/packages/mcp-server/src/tools/translate-pdf.ts +0 -110
  42. package/packages/mcp-server/tests/integration/smoke.test.ts +0 -33
  43. package/packages/mcp-server/tests/unit/config.test.ts +0 -49
  44. package/packages/mcp-server/tests/unit/convert.test.ts +0 -28
  45. package/packages/mcp-server/tests/unit/errors.test.ts +0 -112
  46. package/packages/mcp-server/tests/unit/estimate-cost.test.ts +0 -28
  47. package/packages/mcp-server/tests/unit/polling.test.ts +0 -24
  48. package/packages/mcp-server/tsconfig.json +0 -9
  49. package/packages/mcp-server/tsup.config.ts +0 -13
  50. package/packages/mcp-server/vitest.config.ts +0 -13
  51. package/plugins/kolmopdf/.claude-plugin/plugin.json +0 -16
  52. package/plugins/kolmopdf/.mcp.json +0 -11
  53. package/plugins/kolmopdf/README.md +0 -28
  54. package/plugins/kolmopdf/commands/balance.md +0 -6
  55. package/plugins/kolmopdf/commands/convert.md +0 -14
  56. package/plugins/kolmopdf/commands/parse.md +0 -14
  57. package/plugins/kolmopdf/commands/translate.md +0 -14
  58. package/plugins/kolmopdf/skills/kolmopdf/SKILL.md +0 -108
  59. package/plugins/kolmopdf/skills/kolmopdf/references/chain-recipes.md +0 -35
  60. package/plugins/kolmopdf/skills/kolmopdf/references/parameter-glossary.md +0 -72
  61. package/pnpm-workspace.yaml +0 -2
  62. package/smithery.yaml +0 -21
  63. package/tsconfig.base.json +0 -21
  64. /package/{packages/mcp-server/dist → dist}/index.cjs +0 -0
  65. /package/{packages/mcp-server/dist → dist}/index.d.cts +0 -0
  66. /package/{packages/mcp-server/dist → dist}/index.d.ts +0 -0
@@ -1,896 +0,0 @@
1
- # KolmoPDF Claude Code Plugin — 开发规范
2
-
3
- > Spec version: 1.0 · 目标客户端: Claude Code · Codex CLI · Cursor (兼容 SKILL.md 的客户端皆可)
4
-
5
- ## 0. 范围
6
-
7
- ### In scope (v1.0)
8
-
9
- | 能力 | 上游 API |
10
- |---|---|
11
- | PDF → Markdown 解析(含可选翻译) | `POST /api/pdf-to-markdown-proxy/parse` |
12
- | PDF 版式保留翻译 | `POST /api/pdf-to-markdown-proxy/translate-pdf` |
13
- | Markdown → DOCX/HTML/PDF/LaTeX 格式转换 | `POST /api/pdf-to-markdown-proxy/convert` |
14
- | 任务状态查询 | `GET /api/pdf-to-markdown-proxy/status/{task_id}` |
15
- | 结果下载 | `GET /api/pdf-to-markdown-proxy/download/{task_id}` |
16
- | 积分余额查询 | `GET /api/pdf-to-markdown-proxy/balance` |
17
-
18
- ### Out of scope (v1.0)
19
-
20
- Image OCR、Markdown Translation、AI PPT、PDF Merge/Split、首跑赠送积分(依赖后端改动,列入 §13)。
21
-
22
- ---
23
-
24
- ## 1. 交付物
25
-
26
- | ID | 类型 | 产物 | 分发渠道 |
27
- |---|---|---|---|
28
- | A | npm 包 | `@kolmopdf/mcp-server` | npm registry |
29
- | B | Skill 目录 | `skills/kolmopdf/SKILL.md` (+ supporting refs) | 包含在 Plugin 内 |
30
- | C | Claude Code Plugin | `plugins/kolmopdf/` | GitHub marketplace `kolmopdf/claude-plugin` |
31
- | D | Marketplace 入口 | `.claude-plugin/marketplace.json` | GitHub repo root |
32
- | E | Codex CLI 单文件 Skill | 同 B 内容,独立分发路径 `~/.codex/skills/kolmopdf/` | 同 GitHub repo(路径不同) |
33
-
34
- ---
35
-
36
- ## 2. 仓库结构
37
-
38
- GitHub repo: `kolmopdf/claude-plugin`(新建,pnpm workspaces monorepo)。
39
-
40
- ```
41
- kolmopdf-claude-plugin/
42
- ├── .claude-plugin/
43
- │ └── marketplace.json # 顶层 marketplace 入口(D)
44
- ├── plugins/
45
- │ └── kolmopdf/ # Claude Code Plugin(C)
46
- │ ├── .claude-plugin/
47
- │ │ └── plugin.json
48
- │ ├── .mcp.json # 引用 npm 上的 MCP server
49
- │ ├── skills/
50
- │ │ └── kolmopdf/
51
- │ │ ├── SKILL.md # Skill 主文件(B)
52
- │ │ └── references/
53
- │ │ ├── parameter-glossary.md
54
- │ │ └── chain-recipes.md
55
- │ ├── commands/
56
- │ │ ├── parse.md
57
- │ │ ├── translate.md
58
- │ │ ├── convert.md
59
- │ │ └── balance.md
60
- │ └── README.md
61
- ├── packages/
62
- │ └── mcp-server/ # MCP Server (A)
63
- │ ├── src/
64
- │ │ ├── index.ts # entry, server bootstrap
65
- │ │ ├── client.ts # KolmoPDF API client
66
- │ │ ├── config.ts # env-var loader
67
- │ │ ├── errors.ts # error mapping
68
- │ │ ├── polling.ts # task polling state machine
69
- │ │ ├── progress.ts # MCP progress notification helper
70
- │ │ ├── extract.ts # ZIP extraction
71
- │ │ ├── pages.ts # local page count (pdf-lib)
72
- │ │ └── tools/
73
- │ │ ├── parse-pdf.ts
74
- │ │ ├── translate-pdf.ts
75
- │ │ ├── convert.ts
76
- │ │ ├── estimate-cost.ts
77
- │ │ ├── check-balance.ts
78
- │ │ └── get-task-status.ts
79
- │ ├── tests/
80
- │ │ ├── unit/
81
- │ │ └── integration/
82
- │ ├── package.json
83
- │ ├── tsconfig.json
84
- │ └── tsup.config.ts
85
- ├── codex-skill/ # Codex CLI 标准路径分发 (E)
86
- │ └── kolmopdf/
87
- │ ├── SKILL.md # 软链或镜像自 plugins/.../SKILL.md
88
- │ └── references/
89
- ├── .github/
90
- │ └── workflows/
91
- │ ├── ci.yml
92
- │ └── release.yml
93
- ├── pnpm-workspace.yaml
94
- ├── package.json # root, dev deps
95
- ├── tsconfig.base.json
96
- ├── .gitignore
97
- ├── LICENSE # MIT
98
- ├── README.md
99
- ├── DEVELOPMENT.md # 本文件
100
- ├── TESTING_AND_USAGE.md
101
- └── DISTRIBUTION.md
102
- ```
103
-
104
- ---
105
-
106
- ## 3. 技术栈与依赖
107
-
108
- | 类别 | 选型 | 版本 |
109
- |---|---|---|
110
- | Runtime | Node.js | ≥ 20 LTS |
111
- | 语言 | TypeScript | 5.4+ |
112
- | 包管理 | pnpm | 9.x |
113
- | MCP SDK | `@modelcontextprotocol/sdk` | 1.x(peer dep: zod ≥ 3.25) |
114
- | 校验 | `zod` | 3.25+ |
115
- | 本地 PDF 解析 | `pdf-lib` | 仅用于读取 page count |
116
- | HTTP 客户端 | `undici` | 内置 fetch + multipart 支持 |
117
- | ZIP 解压 | `yauzl` | 7.x |
118
- | 打包 | `tsup` | 8.x(输出 esm + cjs + dts) |
119
- | 测试 | `vitest` | 2.x |
120
- | Lint | `@biomejs/biome` | 1.x |
121
-
122
- ---
123
-
124
- ## 4. 环境变量
125
-
126
- | 变量 | 必需 | 默认 | 说明 |
127
- |---|---|---|---|
128
- | `KOLMOPDF_API_KEY` | 是 | — | 用户从 https://www.kolmopdf.com/api-keys 申请 |
129
- | `KOLMOPDF_BASE_URL` | 否 | `https://www.kolmopdf.com` | 仅企业/调试场景覆盖 |
130
- | `KOLMOPDF_OUTPUT_DIR` | 否 | `./kolmopdf-output` | 解压目标根目录(相对 cwd) |
131
- | `KOLMOPDF_POLL_INTERVAL_MS` | 否 | `2000` | 状态轮询周期(API 建议 1-3s) |
132
- | `KOLMOPDF_MAX_POLL_MINUTES` | 否 | `30` | 单任务客户端最长等待 |
133
- | `KOLMOPDF_HTTP_TIMEOUT_MS` | 否 | `60000` | 单次 HTTP 调用超时(upload/download 单独放宽) |
134
- | `KOLMOPDF_UPLOAD_TIMEOUT_MS` | 否 | `600000` | 上传超时(300MB 大文件) |
135
-
136
- ---
137
-
138
- ## 5. Package A: `@kolmopdf/mcp-server`
139
-
140
- ### 5.1 package.json 关键字段
141
-
142
- ```json
143
- {
144
- "name": "@kolmopdf/mcp-server",
145
- "version": "1.0.0",
146
- "description": "MCP server for KolmoPDF — PDF parsing, layout-preserving translation, and Markdown format conversion.",
147
- "license": "MIT",
148
- "type": "module",
149
- "bin": {
150
- "kolmopdf-mcp": "./dist/index.js"
151
- },
152
- "engines": { "node": ">=20" },
153
- "files": ["dist", "README.md", "LICENSE"],
154
- "keywords": [
155
- "mcp", "model-context-protocol", "claude", "claude-code",
156
- "codex", "pdf", "markdown", "pdf-to-markdown", "translation",
157
- "kolmopdf"
158
- ],
159
- "repository": {
160
- "type": "git",
161
- "url": "https://github.com/kolmopdf/claude-plugin.git",
162
- "directory": "packages/mcp-server"
163
- }
164
- }
165
- ```
166
-
167
- ### 5.2 Server bootstrap
168
-
169
- `src/index.ts` 必须:
170
-
171
- 1. 通过 `stdio` transport 注册。
172
- 2. 启动时不校验 API key(避免无网络场景启动失败);首次调用任意需鉴权工具时再校验,错误结果以 MCP error 形式返回。
173
- 3. 注册下表工具,全部用 `server.registerTool()` 方式。
174
-
175
- ### 5.3 工具清单
176
-
177
- | Tool name | 异步策略 | 暴露给 LLM | 调用对应 API |
178
- |---|---|---|---|
179
- | `kolmopdf_parse_pdf` | 单工具内 submit → poll → download → unzip | 是 | `POST /parse` + status + download |
180
- | `kolmopdf_translate_pdf` | 同上 | 是 | `POST /translate-pdf` + status + download |
181
- | `kolmopdf_convert_markdown` | 同上 | 是 | `POST /convert` + status + download |
182
- | `kolmopdf_estimate_cost` | 仅本地 + 1 次 balance | 是 | 仅 `GET /balance` |
183
- | `kolmopdf_check_balance` | 单次 | 是 | `GET /balance` |
184
- | `kolmopdf_get_task_status` | 单次 | 否(hidden,仅 escape hatch) | `GET /status/{id}` |
185
-
186
- > `kolmopdf_get_task_status` 通过 `description` 标注 "advanced/debug" 并避免触发关键词,使 LLM 默认不调用;用户/开发者可显式调用以排障。
187
-
188
- ### 5.4 Tool: `kolmopdf_parse_pdf`
189
-
190
- **Input schema (Zod)**
191
-
192
- ```ts
193
- z.object({
194
- file_path: z.string().describe("Absolute or cwd-relative path to a local PDF file."),
195
- table_mode: z.enum(["markdown", "image"]).optional(),
196
- formula_format: z.enum(["dollar", "bracket"]).optional(),
197
- enable_translation: z.boolean().optional(),
198
- target_language: z.enum(["zh","en","ja","ko","fr","de","es","ru"]).optional(),
199
- output_options: z.array(z.enum(["original","translated","bilingual"])).optional(),
200
- images_as_url: z.boolean().optional(),
201
- skip_rotation_detection: z.boolean().optional(),
202
- enable_cross_page_merge: z.boolean().optional(),
203
- output_subdir: z.string().optional()
204
- .describe("Subdirectory name under KOLMOPDF_OUTPUT_DIR. Defaults to <task_id>.")
205
- })
206
- ```
207
-
208
- **Boolean → string 转换**:API 端使用 `"true"` / `"false"` 字符串形式接收,client 层负责转换。
209
-
210
- **FormData 构造**
211
-
212
- ```
213
- file : <binary>
214
- table_mode : "markdown" | "image"
215
- formula_format : "dollar" | "bracket"
216
- enable_translation : "true" | "false"
217
- target_language : <code> # 仅当 enable_translation=true
218
- output_options : "original,translated" # 逗号分隔
219
- images_as_url : "true" | "false"
220
- skip_rotation_detection : "true" | "false"
221
- enable_cross_page_merge : "true" | "false"
222
- ```
223
-
224
- **返回结构**
225
-
226
- ```ts
227
- {
228
- task_id: string,
229
- pages_parsed: number, // 从 points_deducted 倒推:parse_only=pts/2, parse+translate=pts/3
230
- points_deducted: number,
231
- remaining_points: number,
232
- output: {
233
- type: "zip_extracted" | "markdown_file",
234
- markdown_path: string, // 已解压后的 .md 绝对路径
235
- images_dir: string | null, // zip 模式下为 images/ 路径;url 模式下为 null
236
- output_root: string // 总输出目录绝对路径
237
- },
238
- preview: string // markdown 前 500 字符
239
- }
240
- ```
241
-
242
- **行为细则**
243
-
244
- 1. 上传前本地用 `pdf-lib` 读 page count;若 > 800 → 立即抛 `parse_page_limit_exceeded` 错误(带建议拆分到 800 页以内)。
245
- 2. 上传前 `fs.stat` 校验 file size > 300MB → 立即抛 `parse_file_too_large`。
246
- 3. 上传响应解析 `task_id` 后进入 polling(§5.10)。
247
- 4. 状态 `completed` 后调用 `/download/{task_id}` 流式拉取。
248
- 5. `images_as_url=false`(默认) → 拉到 ZIP,解压到 `<OUTPUT_DIR>/<task_id>/`,自动识别第一个 `*.md` 作为 `markdown_path`;其余文件平铺。
249
- 6. `images_as_url=true` → 拉到 markdown 文件,直接写入 `<OUTPUT_DIR>/<task_id>/result.md`,`images_dir=null`。
250
- 7. 全程 progress notification(§5.11)。
251
-
252
- ### 5.5 Tool: `kolmopdf_translate_pdf`
253
-
254
- **Input schema**
255
-
256
- ```ts
257
- z.object({
258
- file_path: z.string(),
259
- source_language: z.string().optional().default("en"),
260
- target_language: z.string().optional().default("zh"),
261
- layout_modes: z.array(z.enum(["translated_only","side_by_side"]))
262
- .optional().default(["translated_only"]),
263
- enable_image_translation: z.boolean().optional().default(false),
264
- enable_table_translation: z.boolean().optional().default(false),
265
- output_subdir: z.string().optional()
266
- })
267
- ```
268
-
269
- **FormData 字段**:`file`, `sourceLanguage`, `targetLanguage`, `layoutModes`(逗号分隔),`enableImageTranslation`, `enableTableTranslation`(boolean → 字符串)。
270
-
271
- **返回结构**
272
-
273
- ```ts
274
- {
275
- task_id: string,
276
- pages_translated: number, // 倒推:points_deducted / 2
277
- points_deducted: number,
278
- remaining_points: number,
279
- output: {
280
- translated_pdf_path: string // 下载后落到 <OUTPUT_DIR>/<task_id>/translated.pdf
281
- }
282
- }
283
- ```
284
-
285
- **行为细则**:同 §5.4 的 1–4;下载文件保存为 `.pdf`,无解压;progress 同 §5.11。
286
-
287
- ### 5.6 Tool: `kolmopdf_convert_markdown`
288
-
289
- **Input schema**
290
-
291
- ```ts
292
- z.object({
293
- file_path: z.string()
294
- .describe("Path to a .md/.markdown file or .zip containing markdown + images."),
295
- target_format: z.enum(["word","docx","html","pdf","latex","tex"])
296
- .optional().default("word"),
297
- output_subdir: z.string().optional()
298
- })
299
- ```
300
-
301
- **FormData 字段**:`file`, `targetFormat`。
302
-
303
- **返回结构**
304
-
305
- ```ts
306
- {
307
- task_id: string,
308
- points_deducted: number,
309
- remaining_points: number,
310
- output: {
311
- output_path: string, // 落到 <OUTPUT_DIR>/<task_id>/result.<ext>
312
- target_format: string // 规范化后的 docx/html/pdf/tex
313
- }
314
- }
315
- ```
316
-
317
- **扩展名映射**:`word|docx → .docx`, `html → .html`, `pdf → .pdf`, `latex|tex → .tex`。
318
-
319
- ### 5.7 Tool: `kolmopdf_estimate_cost`
320
-
321
- **Input schema**
322
-
323
- ```ts
324
- z.object({
325
- file_path: z.string(),
326
- operation: z.enum(["parse","parse_translate","translate","convert"]),
327
- options: z.object({
328
- images_as_url: z.boolean().optional()
329
- }).optional()
330
- })
331
- ```
332
-
333
- **计算规则**
334
-
335
- | operation | 公式 |
336
- |---|---|
337
- | `parse` | `pages × 2` |
338
- | `parse_translate` | `pages × 3` |
339
- | `translate` | `pages × 2` |
340
- | `convert` | `1` |
341
-
342
- **返回结构**
343
-
344
- ```ts
345
- {
346
- pages: number | null, // convert 时为 null
347
- estimated_credits: number,
348
- current_balance: number, // 调用 GET /balance
349
- sufficient: boolean,
350
- shortfall: number, // = max(0, estimated_credits - current_balance)
351
- recommendation: string // 例如 "Sufficient" / "Need top-up at https://www.kolmopdf.com/subscription"
352
- }
353
- ```
354
-
355
- **行为**:本地 `pdf-lib` 读页数 + 1 次 `/balance`。不消耗积分。convert 时跳过页数读取,固定 1 积分。
356
-
357
- ### 5.8 Tool: `kolmopdf_check_balance`
358
-
359
- Input:空。Output:`{ points: number, api_key_masked: string }`(API key 显示前 6 + 后 4,中间 `***`)。
360
-
361
- ### 5.9 Tool: `kolmopdf_get_task_status`
362
-
363
- Input:`{ task_id: string }`。Output:原样透传 API 响应。
364
-
365
- **Description 写法**(避免误触发):
366
- ```
367
- Advanced/debug tool. Returns raw status for a KolmoPDF task. Use only when explicitly asked to inspect a task by ID, or when troubleshooting a stuck task.
368
- ```
369
-
370
- ### 5.10 Polling 状态机
371
-
372
- ```
373
- INIT
374
- └─ POST /parse (or /translate-pdf / /convert)
375
- ├─ HTTP 4xx/5xx → ERROR (map to KolmoPDF error_code, see §8)
376
- └─ 200 { task_id, status }
377
- ├─ status = "processing" → POLLING
378
- ├─ status = "waiting" → POLLING
379
- └─ (other) → POLLING
380
-
381
- POLLING:
382
- loop every KOLMOPDF_POLL_INTERVAL_MS:
383
- GET /status/{task_id}
384
- ├─ status in {pending, waiting, processing} → emit progress, continue
385
- ├─ status = "completed" → DOWNLOAD
386
- └─ status = "failed" → ERROR (use error_code from response; note: server-side auto-refunds)
387
- guard: if elapsed > KOLMOPDF_MAX_POLL_MINUTES → ERROR("client_polling_timeout")
388
-
389
- DOWNLOAD:
390
- GET /download/{task_id} (Accept any binary)
391
- ├─ HTTP 200 → write to disk, extract if zip, return result
392
- └─ HTTP error → ERROR("download_failed")
393
- ```
394
-
395
- **重试策略**
396
-
397
- | 场景 | 行为 |
398
- |---|---|
399
- | HTTP 网络错误(ECONNRESET / ETIMEDOUT / 5xx) | 指数退避,最多 3 次(base 1s,因子 2) |
400
- | HTTP 4xx(业务错误) | 立即 fail,不重试 |
401
- | `parse_error` / `parse_timeout` / `parse_file_invalid` | 立即 fail(API 已扣后退) |
402
- | Polling 接口偶发 5xx | 同网络错误重试 |
403
-
404
- ### 5.11 Progress notification
405
-
406
- 每次 polling tick 都向 MCP client 发送 progress notification(前提:client 在 request `_meta` 中提供 `progressToken`)。
407
-
408
- ```ts
409
- await ctx.mcpReq.notify({
410
- method: 'notifications/progress',
411
- params: {
412
- progressToken,
413
- progress: monotonic_counter, // 自增整数
414
- message: `[${status}] ${humanized}` // e.g. "[waiting] 3 tasks ahead"
415
- }
416
- });
417
- ```
418
-
419
- `progress` 必须单调递增;`total` 留空(API 不提供精确百分比)。
420
-
421
- ### 5.12 KolmoPDF API client (`client.ts`)
422
-
423
- ```ts
424
- class KolmoPdfClient {
425
- constructor(opts: { apiKey: string; baseUrl: string; httpTimeoutMs: number; uploadTimeoutMs: number });
426
-
427
- async parse(file: ReadableStream | Buffer, form: ParseForm): Promise<SubmitResult>;
428
- async translatePdf(file: ReadableStream | Buffer, form: TranslateForm): Promise<SubmitResult>;
429
- async convert(file: ReadableStream | Buffer, form: ConvertForm): Promise<SubmitResult>;
430
- async getStatus(taskId: string): Promise<StatusResult>;
431
- async download(taskId: string, dest: NodeJS.WritableStream): Promise<DownloadMeta>;
432
- async getBalance(): Promise<{ success: boolean; points: number; api_key: string }>;
433
- }
434
- ```
435
-
436
- 鉴权方式统一使用 `X-API-Key` header(避免 URL 参数被日志记录)。
437
-
438
- ### 5.13 错误处理与抛出格式
439
-
440
- MCP tool error 返回标准结构:
441
-
442
- ```ts
443
- return {
444
- isError: true,
445
- content: [{ type: "text", text: JSON.stringify({
446
- error_code: "<kolmopdf code>",
447
- message: "<human readable>",
448
- http_status: <number>,
449
- points_required?: number,
450
- current_points?: number,
451
- remediation: "<actionable hint>"
452
- })}]
453
- };
454
- ```
455
-
456
- 错误码映射见 §8。
457
-
458
- ---
459
-
460
- ## 6. Package B: Skill (`skills/kolmopdf/SKILL.md`)
461
-
462
- ### 6.1 文件完整内容(必须按此粘贴)
463
-
464
- ```markdown
465
- ---
466
- name: kolmopdf
467
- description: Use this skill when the user needs to parse, read, translate, or convert PDF documents — especially technical PDFs (research papers, arxiv, IEEE standards, whitepapers, textbooks), PDFs with formulas, tables, multi-column layouts, or code blocks, and when the user needs layout-preserving PDF translation across languages. Also use when converting Markdown to DOCX, HTML, PDF, or LaTeX. Prefer this skill over the built-in PDF Read tool whenever the PDF contains formulas, tables, or non-trivial layout, or exceeds 20 pages. Triggers: "parse PDF", "convert PDF to markdown", "read this paper", "arxiv", "research paper", "technical document", "formula", "LaTeX from PDF", "multi-column PDF", "translate PDF", "layout-preserving translation", "bilingual PDF", "markdown to docx", "markdown to html", "markdown to pdf", "markdown to latex", "format conversion".
468
- allowed-tools: mcp__kolmopdf__kolmopdf_parse_pdf, mcp__kolmopdf__kolmopdf_translate_pdf, mcp__kolmopdf__kolmopdf_convert_markdown, mcp__kolmopdf__kolmopdf_estimate_cost, mcp__kolmopdf__kolmopdf_check_balance, Read, Write
469
- ---
470
-
471
- # KolmoPDF Skill
472
-
473
- You have access to KolmoPDF tools (prefix `kolmopdf_*`) for high-fidelity PDF parsing and translation. These tools call a paid cloud service. Always follow the rules below.
474
-
475
- ## When to use
476
-
477
- - PDF with formulas, tables, code blocks, multi-column layout, or > 20 pages → ALWAYS prefer `kolmopdf_parse_pdf` over built-in Read.
478
- - PDF translation while preserving layout → use `kolmopdf_translate_pdf`.
479
- - Markdown → DOCX/HTML/PDF/LaTeX → use `kolmopdf_convert_markdown`.
480
- - Simple text-only PDFs ≤ 20 pages and no formulas/tables → built-in Read is acceptable.
481
-
482
- ## Cost-awareness protocol
483
-
484
- Before running any operation that consumes credits:
485
-
486
- 1. Call `kolmopdf_estimate_cost` with the file path and intended operation.
487
- 2. If `sufficient` is false: stop and report `shortfall` and the top-up URL `https://www.kolmopdf.com/subscription` to the user. Do not proceed.
488
- 3. If `estimated_credits > 50`: tell the user the estimated cost and ask for confirmation before proceeding.
489
- 4. Otherwise: proceed.
490
-
491
- ## API key requirement
492
-
493
- Tools require `KOLMOPDF_API_KEY` in the MCP server environment. If a tool returns `invalid_api_key`:
494
-
495
- - Direct the user to https://www.kolmopdf.com/api-keys to create a key (requires Plus or Pro plan).
496
- - Tell the user to set `KOLMOPDF_API_KEY` in their environment and restart Claude Code.
497
- - Do not proceed with retries until the user confirms.
498
-
499
- ## Chained workflows
500
-
501
- ### PDF → DOCX/HTML/PDF/LaTeX (full pipeline)
502
-
503
- 1. `kolmopdf_estimate_cost(file, "parse")` → check balance.
504
- 2. `kolmopdf_parse_pdf(file)` → get `markdown_path`.
505
- 3. `kolmopdf_convert_markdown(markdown_path, target_format)` → final file.
506
-
507
- If the PDF contains many images, pass the original directory (not just the markdown file) by zipping `output_root` first using your own tools, then pass the zip to convert. See `references/chain-recipes.md`.
508
-
509
- ### Read + ask Q&A about a paper
510
-
511
- 1. `kolmopdf_parse_pdf(file)` → get `markdown_path` and `preview`.
512
- 2. Use `Read` on `markdown_path` to load the full content.
513
- 3. Answer the user's question grounded in the markdown.
514
-
515
- ### Translate then convert to bilingual deliverable
516
-
517
- Option A (PDF deliverable):
518
- - `kolmopdf_translate_pdf(file, layout_modes=["side_by_side"])` → single PDF with side-by-side layout.
519
-
520
- Option B (editable Markdown deliverable):
521
- - `kolmopdf_parse_pdf(file, enable_translation=true, output_options=["bilingual"])` → bilingual markdown.
522
-
523
- ## Parameter guidance
524
-
525
- See `references/parameter-glossary.md` for the full parameter table and defaults. Highlights:
526
-
527
- - `formula_format=dollar` is the default and works with KaTeX/MathJax. Use `bracket` for LaTeX-strict downstream renderers.
528
- - `enable_cross_page_merge=true` is recommended when the source PDF has tables spanning page breaks.
529
- - `images_as_url=true` returns a single markdown file with 30-day URL references; use this for ephemeral pipelines. Default `false` returns a self-contained ZIP.
530
-
531
- ## Output handling
532
-
533
- After successful tool calls, treat `output.markdown_path` / `output.translated_pdf_path` / `output.output_path` as the canonical local file paths and reference them in your reply to the user. Show the user the absolute path; do not re-print the entire file unless asked.
534
-
535
- ## Failure modes
536
-
537
- | error_code | Action |
538
- | --- | --- |
539
- | `invalid_api_key` | Stop; follow API key requirement section above. |
540
- | `insufficient_points` | Stop; report shortfall and top-up URL. |
541
- | `parse_page_limit_exceeded`, `parse_file_too_large` | Stop; suggest splitting the PDF locally. |
542
- | `parse_file_not_pdf`, `parse_file_invalid` | Stop; ask the user to re-export the PDF. |
543
- | `parse_error`, `parse_timeout` | Server auto-refunds points. Suggest retry with smaller page range. |
544
- | `client_polling_timeout` | Tell the user the task is still running server-side and suggest using `kolmopdf_get_task_status` with the task_id later. |
545
- | Network/5xx | Tools auto-retry up to 3 times. If still failing, suggest checking https://www.kolmopdf.com/contact. |
546
- ```
547
-
548
- ### 6.2 references/parameter-glossary.md
549
-
550
- 完整参数对照表(API 文档原样转写为表格)。该文件不会被自动加载,仅在 SKILL 内显式 `Read` 时使用。包含:
551
-
552
- - `kolmopdf_parse_pdf` 全部字段、合法值、默认值、计费影响
553
- - `kolmopdf_translate_pdf` 全部字段
554
- - `kolmopdf_convert_markdown` 全部字段
555
- - 语言代码完整列表
556
- - ZIP 输出结构示意
557
-
558
- ### 6.3 references/chain-recipes.md
559
-
560
- 记录三类典型链式调用的精确步骤(与 §6.1 中的简版对应展开)。
561
-
562
- ### 6.4 Skill 触发关键词清单(用于 description)
563
-
564
- | 类别 | 关键词 |
565
- |---|---|
566
- | 通用 PDF | `PDF`, `parse PDF`, `read PDF`, `extract from PDF`, `convert PDF to markdown` |
567
- | 学术 | `arxiv`, `arxiv paper`, `research paper`, `IEEE`, `academic paper`, `read this paper`, `summarize paper` |
568
- | 技术文档 | `technical document`, `whitepaper`, `standard document`, `RFC`, `API doc PDF`, `datasheet` |
569
- | 内容特征 | `formula`, `equation`, `LaTeX from PDF`, `table from PDF`, `multi-column PDF`, `code block in PDF` |
570
- | 翻译 | `translate PDF`, `layout-preserving translation`, `bilingual PDF`, `side-by-side translation` |
571
- | 格式转换 | `markdown to docx`, `markdown to word`, `markdown to html`, `markdown to pdf`, `markdown to latex`, `format conversion` |
572
-
573
- ---
574
-
575
- ## 7. Package C: Claude Code Plugin
576
-
577
- ### 7.1 `plugins/kolmopdf/.claude-plugin/plugin.json`
578
-
579
- ```json
580
- {
581
- "$schema": "https://json.schemastore.org/claude-code-plugin.json",
582
- "name": "kolmopdf",
583
- "displayName": "KolmoPDF",
584
- "description": "High-fidelity PDF to Markdown parsing, layout-preserving PDF translation, and Markdown→DOCX/HTML/PDF/LaTeX conversion. Handles formulas, tables, and multi-column layouts that the built-in Read tool struggles with.",
585
- "version": "1.0.0",
586
- "author": {
587
- "name": "KomoAI LLC",
588
- "email": "support@kolmopdf.com"
589
- },
590
- "homepage": "https://www.kolmopdf.com",
591
- "repository": "https://github.com/kolmopdf/claude-plugin",
592
- "license": "MIT",
593
- "keywords": [
594
- "pdf", "markdown", "ocr", "translation", "latex",
595
- "research", "arxiv", "kolmopdf"
596
- ],
597
- "category": "document-processing"
598
- }
599
- ```
600
-
601
- ### 7.2 `plugins/kolmopdf/.mcp.json`
602
-
603
- ```json
604
- {
605
- "mcpServers": {
606
- "kolmopdf": {
607
- "command": "npx",
608
- "args": ["-y", "@kolmopdf/mcp-server"],
609
- "env": {
610
- "KOLMOPDF_API_KEY": "${KOLMOPDF_API_KEY}"
611
- }
612
- }
613
- }
614
- }
615
- ```
616
-
617
- > 注:`env` 中的 `${KOLMOPDF_API_KEY}` 走 Claude Code 的环境变量替换;用户在 shell rc 或 `.env` 设置即可。
618
-
619
- ### 7.3 Slash commands
620
-
621
- 四个命令文件,全部位于 `plugins/kolmopdf/commands/`。
622
-
623
- #### 7.3.1 `commands/parse.md`
624
-
625
- ```markdown
626
- ---
627
- description: Parse a PDF to Markdown via KolmoPDF (handles formulas, tables, multi-column).
628
- argument-hint: <file-path> [--translate] [--target-lang zh|en|ja|ko|fr|de|es|ru]
629
- allowed-tools: mcp__kolmopdf__kolmopdf_parse_pdf, mcp__kolmopdf__kolmopdf_estimate_cost
630
- ---
631
-
632
- Parse the PDF at the provided path using KolmoPDF. Steps:
633
-
634
- 1. Run `kolmopdf_estimate_cost` for operation `parse` (or `parse_translate` if `--translate` was passed) and report the cost. If `sufficient=false`, stop.
635
- 2. If `--translate` was passed, set `enable_translation=true` and use the `--target-lang` value (default `zh`) with `output_options=["bilingual"]`.
636
- 3. Call `kolmopdf_parse_pdf`.
637
- 4. Report `output.markdown_path` and `preview` to the user.
638
-
639
- Arguments: $ARGUMENTS
640
- ```
641
-
642
- #### 7.3.2 `commands/translate.md`
643
-
644
- ```markdown
645
- ---
646
- description: Translate a PDF while preserving its original layout (KolmoPDF).
647
- argument-hint: <file-path> [--from <lang>] [--to <lang>] [--mode translated_only|side_by_side]
648
- allowed-tools: mcp__kolmopdf__kolmopdf_translate_pdf, mcp__kolmopdf__kolmopdf_estimate_cost
649
- ---
650
-
651
- Translate the PDF while preserving its layout. Steps:
652
-
653
- 1. Parse the file path and flags from $ARGUMENTS. Defaults: `--from en`, `--to zh`, `--mode translated_only`.
654
- 2. Call `kolmopdf_estimate_cost` for operation `translate`. Stop if insufficient.
655
- 3. Call `kolmopdf_translate_pdf` with the parsed arguments.
656
- 4. Report `output.translated_pdf_path` to the user.
657
-
658
- Arguments: $ARGUMENTS
659
- ```
660
-
661
- #### 7.3.3 `commands/convert.md`
662
-
663
- ```markdown
664
- ---
665
- description: Convert Markdown to DOCX, HTML, PDF, or LaTeX (KolmoPDF).
666
- argument-hint: <markdown-or-zip-path> [--format word|docx|html|pdf|latex|tex]
667
- allowed-tools: mcp__kolmopdf__kolmopdf_convert_markdown, mcp__kolmopdf__kolmopdf_estimate_cost
668
- ---
669
-
670
- Convert the provided Markdown file (or ZIP archive containing markdown + images) to the target format. Steps:
671
-
672
- 1. Parse arguments. Default `--format word`.
673
- 2. Call `kolmopdf_estimate_cost` for operation `convert` (always 1 credit). Stop if insufficient.
674
- 3. Call `kolmopdf_convert_markdown`.
675
- 4. Report `output.output_path` to the user.
676
-
677
- Arguments: $ARGUMENTS
678
- ```
679
-
680
- #### 7.3.4 `commands/balance.md`
681
-
682
- ```markdown
683
- ---
684
- description: Show KolmoPDF account credit balance.
685
- allowed-tools: mcp__kolmopdf__kolmopdf_check_balance
686
- ---
687
-
688
- Call `kolmopdf_check_balance` and report the result in a single line: `KolmoPDF balance: <points> credits (key <masked>)`.
689
- ```
690
-
691
- ### 7.4 命名空间
692
-
693
- Plugin 内 skill 调用形式:`/kolmopdf:kolmopdf`(slash menu 直接显示 KolmoPDF)。
694
- Plugin 内 command 调用形式:`/kolmopdf:parse`, `/kolmopdf:translate`, `/kolmopdf:convert`, `/kolmopdf:balance`。
695
-
696
- ### 7.5 Plugin README
697
-
698
- `plugins/kolmopdf/README.md` 仅包含:
699
-
700
- - 一段安装命令矩阵(Claude Code / Codex CLI / Cursor / Claude Desktop)
701
- - API key 申请链接
702
- - 工具能力清单表
703
- - License: MIT
704
-
705
- 不写教程性文字。
706
-
707
- ---
708
-
709
- ## 8. 统一错误码映射表
710
-
711
- > source 列:API 上游已定义的错误码 / client 表示由 MCP server 本地补充
712
-
713
- | error_code | source | HTTP | 是否扣分 | MCP 抛出 message | 建议 remediation |
714
- |---|---|---|---|---|---|
715
- | `invalid_api_key` | API | 401 | 否 | "API key is missing or invalid." | "Create a key at https://www.kolmopdf.com/api-keys (requires Plus/Pro)." |
716
- | `insufficient_points` | API | 402 | 否 | "Not enough credits." | "Top up at https://www.kolmopdf.com/subscription." |
717
- | `points_deduction_failed` | API | 402 | 否 | "Credit deduction failed." | "Retry; if persists contact support." |
718
- | `no_file_found` | API | 400 | 否 | "Request missing file field." | "(internal) MCP server bug, please report." |
719
- | `parse_file_too_large` | API | 400 | 否 | "PDF exceeds 300MB." | "Split the PDF locally." |
720
- | `parse_page_limit_exceeded` | API | 400 | 否 | "PDF exceeds 800 pages." | "Split the PDF locally." |
721
- | `parse_file_not_pdf` | API | 400 | 否 | "File is not a valid PDF." | "Upload a .pdf file." |
722
- | `translate_pdf_file_too_large` | API | 400 | 否 | (同上 translate) | 同 |
723
- | `translate_pdf_file_not_pdf` | API | 400 | 否 | 同 | 同 |
724
- | `translate_pdf_page_limit_exceeded` | API | 400 | 否 | 同 | 同 |
725
- | `convert_file_too_large` | API | 400 | 否 | "File exceeds 300MB." | "Reduce file size." |
726
- | `convert_file_type_unsupported` | API | 400 | 否 | "File must be .md / .markdown / .zip." | "Convert source to markdown first." |
727
- | `convert_target_format_unsupported` | API | 400 | 否 | "Target format unsupported." | "Use word/docx/html/pdf/latex/tex." |
728
- | `file_upload_failed` | API | 500 | 否 | "Upload to storage failed." | "Check network and retry." |
729
- | `task_creation_failed` | API | 500 | 是(自动退) | "Task creation failed." | "Retry." |
730
- | `parse_error` | API | 500 | 是(自动退) | "Parsing failed." | "Retry; if persists, split and try again." |
731
- | `parse_file_invalid` | API | 500 | 是(自动退) | "PDF is malformed." | "Re-export the PDF." |
732
- | `parse_timeout` | API | 500 | 是(自动退) | "Server-side timeout." | "Split into smaller PDFs." |
733
- | `api_task_error` | API | 500 | 视情况 | "Generic task error." | "Retry; if persists contact support." |
734
- | `client_polling_timeout` | client | — | 否 | "Local polling exceeded KOLMOPDF_MAX_POLL_MINUTES." | "Task may still be running. Use kolmopdf_get_task_status with task_id." |
735
- | `client_network_error` | client | — | 否 | "Network error after retries." | "Check network." |
736
- | `client_local_validation` | client | — | 否 | "Local pre-check failed (page count / file size)." | (按子类型) |
737
- | `client_extract_failed` | client | — | 否 | "ZIP extraction failed." | "Check disk permissions on output dir." |
738
-
739
- ---
740
-
741
- ## 9. Marketplace 入口
742
-
743
- ### 9.1 `.claude-plugin/marketplace.json`(仓库根目录)
744
-
745
- ```json
746
- {
747
- "$schema": "https://json.schemastore.org/claude-code-marketplace.json",
748
- "name": "kolmopdf",
749
- "description": "Official KolmoPDF plugin marketplace for Claude Code.",
750
- "owner": {
751
- "name": "KomoAI LLC",
752
- "email": "support@kolmopdf.com"
753
- },
754
- "plugins": [
755
- {
756
- "name": "kolmopdf",
757
- "displayName": "KolmoPDF",
758
- "source": "./plugins/kolmopdf",
759
- "description": "High-fidelity PDF to Markdown parsing, layout-preserving PDF translation, and Markdown format conversion.",
760
- "version": "1.0.0",
761
- "author": { "name": "KomoAI LLC", "email": "support@kolmopdf.com" },
762
- "homepage": "https://www.kolmopdf.com",
763
- "repository": "https://github.com/kolmopdf/claude-plugin",
764
- "license": "MIT",
765
- "keywords": ["pdf", "markdown", "ocr", "translation", "latex", "research"],
766
- "category": "document-processing",
767
- "tags": ["pdf", "markdown", "translation", "academic", "arxiv"]
768
- }
769
- ]
770
- }
771
- ```
772
-
773
- > 不要把这个 marketplace 取名为 Anthropic 保留名(参见 §11 reserved list)。当前 `kolmopdf` 通过。
774
-
775
- ### 9.2 安装命令(最终用户视角)
776
-
777
- ```bash
778
- # Claude Code
779
- /plugin marketplace add kolmopdf/claude-plugin
780
- /plugin install kolmopdf@kolmopdf
781
-
782
- # 环境变量(用户自己设置)
783
- export KOLMOPDF_API_KEY=sk-xxxxxxxxxxxxxxxx
784
- ```
785
-
786
- ---
787
-
788
- ## 10. Codex CLI 兼容路径
789
-
790
- ### 10.1 镜像同一份 SKILL.md
791
-
792
- CI 中将 `plugins/kolmopdf/skills/kolmopdf/` 整体复制到 `codex-skill/kolmopdf/`。两份内容必须 byte-identical;release pipeline 用脚本校验。
793
-
794
- ### 10.2 用户安装方式(README 指引,不依赖 Codex 的 plugin 体系)
795
-
796
- ```bash
797
- # Codex CLI(不走 plugin,直接放 skill 目录)
798
- mkdir -p ~/.codex/skills
799
- git clone --depth 1 https://github.com/kolmopdf/claude-plugin /tmp/kolmopdf
800
- cp -r /tmp/kolmopdf/codex-skill/kolmopdf ~/.codex/skills/
801
-
802
- # MCP server 通过 ~/.codex/config.toml 或 Codex 推荐方式独立配置:
803
- # [mcp_servers.kolmopdf]
804
- # command = "npx"
805
- # args = ["-y", "@kolmopdf/mcp-server"]
806
- # env = { KOLMOPDF_API_KEY = "sk-..." }
807
- ```
808
-
809
- > Codex 不支持 `.mcp.json` plugin 嵌入,所以 MCP server 配置需用户手动加。SKILL.md 中的 `allowed-tools` 字段在 Codex 中被忽略(OpenAI 文档明确说明),不构成功能阻塞。
810
-
811
- ---
812
-
813
- ## 11. 包发布规范
814
-
815
- ### 11.1 npm 包
816
-
817
- | 字段 | 值 |
818
- |---|---|
819
- | Package name | `@kolmopdf/mcp-server` |
820
- | Scope | `@kolmopdf`(需注册组织) |
821
- | Access | `public` |
822
- | Distribution tag | `latest` |
823
- | Engines | `node >= 20` |
824
- | Files included | `dist/`, `README.md`, `LICENSE` |
825
- | Published via | GitHub Actions release workflow(§12.2) |
826
-
827
- ### 11.2 Marketplace 保留名规避
828
-
829
- 不可用 marketplace 名(节选 Anthropic 官方保留):
830
- `claude-code-marketplace`, `claude-code-plugins`, `claude-plugins-official`, `anthropic-marketplace`, `anthropic-plugins`, `agent-skills`, `anthropic-agent-skills`, `knowledge-work-plugins`, `life-sciences`, 任何 `official-*` / `anthropic-*` 前缀。
831
-
832
- 本项目使用:`kolmopdf` ✅
833
-
834
- ---
835
-
836
- ## 12. CI/CD
837
-
838
- ### 12.1 `.github/workflows/ci.yml`
839
-
840
- | Job | 触发 | 步骤 |
841
- |---|---|---|
842
- | `lint` | push / PR | `pnpm install` → `pnpm biome check .` |
843
- | `typecheck` | push / PR | `pnpm -r tsc --noEmit` |
844
- | `test:unit` | push / PR | `pnpm -r test:unit` |
845
- | `test:integration` | nightly + manual | 用 secret `KOLMOPDF_API_KEY` 跑一组 smoke test(§见 TESTING_AND_USAGE.md) |
846
- | `validate-plugin` | push / PR | `npx @anthropic-ai/claude-code plugin validate .`(cli 提供时启用) |
847
- | `mirror-codex-skill` | push (main) | 脚本校验 `plugins/.../SKILL.md` 与 `codex-skill/.../SKILL.md` 一致 |
848
-
849
- ### 12.2 `.github/workflows/release.yml`
850
-
851
- 触发:push tag `v*.*.*`
852
-
853
- | Step | 行为 |
854
- |---|---|
855
- | build | `pnpm -r build`(产出 `dist/`) |
856
- | publish-npm | `cd packages/mcp-server && pnpm publish --access public --no-git-checks` |
857
- | bump-plugin-version | 自动校验 `plugins/kolmopdf/.claude-plugin/plugin.json` 与 tag 匹配,不匹配则 fail |
858
- | github-release | 用 conventional-changelog 生成 release notes |
859
-
860
- ### 12.3 版本策略
861
-
862
- | 包/文件 | 版本号 | 策略 |
863
- |---|---|---|
864
- | `@kolmopdf/mcp-server` | 独立 semver | 主导版本,按 SDK 变化 |
865
- | `plugin.json` `version` | 跟随 mcp-server | 同步发版 |
866
- | `marketplace.json` plugin entry `version` | 跟随 plugin.json | 同步发版 |
867
- | Git tag | `v<semver>` | 单调递增 |
868
-
869
- > 每次发版必须同时改三处 version,否则 Claude Code 客户端不会拉取更新(旧版本 cache hit)。release workflow 中加 sanity check。
870
-
871
- ---
872
-
873
- ## 13. 后续增量计划(v1.1+,需后端配合)
874
-
875
- | 计划项 | 后端依赖 | 客户端改动 |
876
- |---|---|---|
877
- | Skill 首次安装赠送积分(兑换码) | 后端新增「插件专属兑换码池」+ 防滥用(限制每账户一次) | MCP server 安装后首次启动检测到 0 积分时弹一次性 onboarding 文案,引导兑换 |
878
- | 异步任务取消 | 后端 `DELETE /status/{task_id}` | MCP 增加 `kolmopdf_cancel_task` |
879
- | 任务失败精确 error_code(如细分 `parse_table_failed`) | 后端枚举扩充 | 错误码映射表更新 |
880
- | Image OCR 接口开放 | 后端 API 已存在,仅需 API key 鉴权 | 新工具 `kolmopdf_parse_image` |
881
- | Markdown Translation 接口 | 同上 | 新工具 `kolmopdf_translate_markdown` |
882
- | 任务事件 webhook(替代 polling) | 后端新增 webhook | MCP 可选订阅替代 polling |
883
-
884
- ---
885
-
886
- ## 14. 开发顺序(建议里程碑)
887
-
888
- | 阶段 | 产出 | 验收 |
889
- |---|---|---|
890
- | M1 | `client.ts` + `errors.ts` + `polling.ts` 单元测试 | 全部 KolmoPDF API 路径单测覆盖 ≥ 80% |
891
- | M2 | 三个核心 tool(parse/translate/convert) | 本地 stdio MCP server 能跑通三类任务 |
892
- | M3 | 辅助 tool(estimate_cost / check_balance / get_task_status) | Skill 中的 cost-aware 流程跑通 |
893
- | M4 | Plugin manifest + SKILL.md + slash commands + marketplace.json | `claude plugin validate .` 全绿 |
894
- | M5 | CI/CD + npm 发版试跑 | dry-run release 通过 |
895
- | M6 | Codex CLI 镜像 + 三客户端冒烟(见 TESTING_AND_USAGE.md) | 三客户端冒烟全过 |
896
- | M7 | 正式 release | 见 DISTRIBUTION.md 时间表 |