@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.
- package/LICENSE +21 -21
- package/README.md +37 -63
- package/dist/index.cjs.map +1 -0
- package/{packages/mcp-server/dist → dist}/index.js +0 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -30
- package/.claude-plugin/marketplace.json +0 -25
- package/.github/ISSUE_TEMPLATE/bug-report.yml +0 -75
- package/.github/workflows/ci.yml +0 -98
- package/.github/workflows/release.yml +0 -52
- package/CHANGELOG.md +0 -12
- package/biome.json +0 -33
- package/codex-skill/kolmopdf/SKILL.md +0 -108
- package/codex-skill/kolmopdf/references/chain-recipes.md +0 -35
- package/codex-skill/kolmopdf/references/parameter-glossary.md +0 -72
- package/doc/apidocs/Format_Conversion_API_Guide.md +0 -117
- package/doc/apidocs/PDF_Layout_Translation_API_Guide.md +0 -138
- package/doc/apidocs/PDF_Parsing_API_Guide.md +0 -364
- package/doc/plan/DEVELOPMENT.md +0 -896
- package/doc/plan/DISTRIBUTION.md +0 -377
- package/doc/plan/TESTING_AND_USAGE.md +0 -370
- package/packages/mcp-server/LICENSE +0 -21
- package/packages/mcp-server/README.md +0 -37
- package/packages/mcp-server/dist/index.cjs.map +0 -1
- package/packages/mcp-server/dist/index.js.map +0 -1
- package/packages/mcp-server/package.json +0 -54
- package/packages/mcp-server/src/client.ts +0 -235
- package/packages/mcp-server/src/config.ts +0 -62
- package/packages/mcp-server/src/context.ts +0 -27
- package/packages/mcp-server/src/errors.ts +0 -271
- package/packages/mcp-server/src/extract.ts +0 -102
- package/packages/mcp-server/src/index.ts +0 -142
- package/packages/mcp-server/src/pages.ts +0 -16
- package/packages/mcp-server/src/polling.ts +0 -84
- package/packages/mcp-server/src/progress.ts +0 -48
- package/packages/mcp-server/src/tools/check-balance.ts +0 -33
- package/packages/mcp-server/src/tools/convert.ts +0 -130
- package/packages/mcp-server/src/tools/estimate-cost.ts +0 -82
- package/packages/mcp-server/src/tools/get-task-status.ts +0 -24
- package/packages/mcp-server/src/tools/parse-pdf.ts +0 -147
- package/packages/mcp-server/src/tools/translate-pdf.ts +0 -110
- package/packages/mcp-server/tests/integration/smoke.test.ts +0 -33
- package/packages/mcp-server/tests/unit/config.test.ts +0 -49
- package/packages/mcp-server/tests/unit/convert.test.ts +0 -28
- package/packages/mcp-server/tests/unit/errors.test.ts +0 -112
- package/packages/mcp-server/tests/unit/estimate-cost.test.ts +0 -28
- package/packages/mcp-server/tests/unit/polling.test.ts +0 -24
- package/packages/mcp-server/tsconfig.json +0 -9
- package/packages/mcp-server/tsup.config.ts +0 -13
- package/packages/mcp-server/vitest.config.ts +0 -13
- package/plugins/kolmopdf/.claude-plugin/plugin.json +0 -16
- package/plugins/kolmopdf/.mcp.json +0 -11
- package/plugins/kolmopdf/README.md +0 -28
- package/plugins/kolmopdf/commands/balance.md +0 -6
- package/plugins/kolmopdf/commands/convert.md +0 -14
- package/plugins/kolmopdf/commands/parse.md +0 -14
- package/plugins/kolmopdf/commands/translate.md +0 -14
- package/plugins/kolmopdf/skills/kolmopdf/SKILL.md +0 -108
- package/plugins/kolmopdf/skills/kolmopdf/references/chain-recipes.md +0 -35
- package/plugins/kolmopdf/skills/kolmopdf/references/parameter-glossary.md +0 -72
- package/pnpm-workspace.yaml +0 -2
- package/smithery.yaml +0 -21
- package/tsconfig.base.json +0 -21
- /package/{packages/mcp-server/dist → dist}/index.cjs +0 -0
- /package/{packages/mcp-server/dist → dist}/index.d.cts +0 -0
- /package/{packages/mcp-server/dist → dist}/index.d.ts +0 -0
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
ERROR_SPECS,
|
|
4
|
-
KolmoPdfError,
|
|
5
|
-
errorFromApiBody,
|
|
6
|
-
isAutoRefunded,
|
|
7
|
-
toMcpErrorResult,
|
|
8
|
-
} from "../../src/errors.js";
|
|
9
|
-
|
|
10
|
-
describe("KolmoPdfError", () => {
|
|
11
|
-
it("uses the spec default message, status, and remediation", () => {
|
|
12
|
-
const err = new KolmoPdfError("invalid_api_key");
|
|
13
|
-
expect(err.errorCode).toBe("invalid_api_key");
|
|
14
|
-
expect(err.httpStatus).toBe(401);
|
|
15
|
-
expect(err.message).toBe("API key is missing or invalid.");
|
|
16
|
-
expect(err.remediation).toContain("api-keys");
|
|
17
|
-
expect(err.source).toBe("api");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("allows overriding message, status, and point fields", () => {
|
|
21
|
-
const err = new KolmoPdfError("insufficient_points", {
|
|
22
|
-
message: "custom",
|
|
23
|
-
pointsRequired: 20,
|
|
24
|
-
currentPoints: 5,
|
|
25
|
-
});
|
|
26
|
-
expect(err.message).toBe("custom");
|
|
27
|
-
expect(err.pointsRequired).toBe(20);
|
|
28
|
-
expect(err.currentPoints).toBe(5);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("falls back to a generic spec for unknown codes", () => {
|
|
32
|
-
const err = new KolmoPdfError("totally_made_up");
|
|
33
|
-
expect(err.message).toBe("Unknown error.");
|
|
34
|
-
expect(err.httpStatus).toBeNull();
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe("toMcpErrorResult", () => {
|
|
39
|
-
it("wraps a KolmoPdfError into the MCP error envelope", () => {
|
|
40
|
-
const result = toMcpErrorResult(
|
|
41
|
-
new KolmoPdfError("insufficient_points", { pointsRequired: 20, currentPoints: 5 }),
|
|
42
|
-
);
|
|
43
|
-
expect(result.isError).toBe(true);
|
|
44
|
-
const payload = JSON.parse(result.content[0]?.text ?? "");
|
|
45
|
-
expect(payload.error_code).toBe("insufficient_points");
|
|
46
|
-
expect(payload.http_status).toBe(402);
|
|
47
|
-
expect(payload.points_required).toBe(20);
|
|
48
|
-
expect(payload.current_points).toBe(5);
|
|
49
|
-
expect(payload.remediation).toContain("subscription");
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("coerces a plain Error into api_task_error", () => {
|
|
53
|
-
const result = toMcpErrorResult(new Error("boom"));
|
|
54
|
-
const payload = JSON.parse(result.content[0]?.text ?? "");
|
|
55
|
-
expect(payload.error_code).toBe("api_task_error");
|
|
56
|
-
expect(payload.message).toBe("boom");
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("omits point fields when not provided", () => {
|
|
60
|
-
const result = toMcpErrorResult(new KolmoPdfError("parse_error"));
|
|
61
|
-
const payload = JSON.parse(result.content[0]?.text ?? "");
|
|
62
|
-
expect(payload).not.toHaveProperty("points_required");
|
|
63
|
-
expect(payload).not.toHaveProperty("current_points");
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe("isAutoRefunded", () => {
|
|
68
|
-
it("flags server-refunded failure codes", () => {
|
|
69
|
-
expect(isAutoRefunded("parse_error")).toBe(true);
|
|
70
|
-
expect(isAutoRefunded("parse_timeout")).toBe(true);
|
|
71
|
-
expect(isAutoRefunded("task_creation_failed")).toBe(true);
|
|
72
|
-
expect(isAutoRefunded("parse_file_invalid")).toBe(true);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("does not flag non-refunded codes", () => {
|
|
76
|
-
expect(isAutoRefunded("invalid_api_key")).toBe(false);
|
|
77
|
-
expect(isAutoRefunded("insufficient_points")).toBe(false);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe("errorFromApiBody", () => {
|
|
82
|
-
it("maps a failure body with code + points", () => {
|
|
83
|
-
const err = errorFromApiBody(
|
|
84
|
-
{
|
|
85
|
-
error_code: "insufficient_points",
|
|
86
|
-
message: "Insufficient points",
|
|
87
|
-
points_required: 20,
|
|
88
|
-
current_points: 15,
|
|
89
|
-
},
|
|
90
|
-
402,
|
|
91
|
-
);
|
|
92
|
-
expect(err.errorCode).toBe("insufficient_points");
|
|
93
|
-
expect(err.httpStatus).toBe(402);
|
|
94
|
-
expect(err.pointsRequired).toBe(20);
|
|
95
|
-
expect(err.currentPoints).toBe(15);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it("defaults to api_task_error when no code is present", () => {
|
|
99
|
-
const err = errorFromApiBody({ message: "weird" });
|
|
100
|
-
expect(err.errorCode).toBe("api_task_error");
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe("ERROR_SPECS coverage", () => {
|
|
105
|
-
it("every spec has a non-empty message and remediation", () => {
|
|
106
|
-
for (const [code, spec] of Object.entries(ERROR_SPECS)) {
|
|
107
|
-
expect(spec.message, code).toBeTruthy();
|
|
108
|
-
expect(spec.remediation, code).toBeTruthy();
|
|
109
|
-
expect(["api", "client"]).toContain(spec.source);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { buildRecommendation, estimateCredits } from "../../src/tools/estimate-cost.js";
|
|
3
|
-
|
|
4
|
-
describe("estimateCredits", () => {
|
|
5
|
-
it("parse = pages × 2", () => {
|
|
6
|
-
expect(estimateCredits("parse", 15)).toBe(30);
|
|
7
|
-
});
|
|
8
|
-
it("parse_translate = pages × 3", () => {
|
|
9
|
-
expect(estimateCredits("parse_translate", 15)).toBe(45);
|
|
10
|
-
});
|
|
11
|
-
it("translate = pages × 2", () => {
|
|
12
|
-
expect(estimateCredits("translate", 8)).toBe(16);
|
|
13
|
-
});
|
|
14
|
-
it("convert = 1 regardless of pages", () => {
|
|
15
|
-
expect(estimateCredits("convert", 999)).toBe(1);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe("buildRecommendation", () => {
|
|
20
|
-
it("reports sufficiency when no shortfall", () => {
|
|
21
|
-
expect(buildRecommendation(0)).toBe("Sufficient");
|
|
22
|
-
});
|
|
23
|
-
it("includes the top-up URL and shortfall when short", () => {
|
|
24
|
-
const rec = buildRecommendation(195);
|
|
25
|
-
expect(rec).toContain("subscription");
|
|
26
|
-
expect(rec).toContain("195");
|
|
27
|
-
});
|
|
28
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { RETRY_POLICY, backoffDelayMs, isRetryable } from "../../src/polling.js";
|
|
3
|
-
|
|
4
|
-
describe("backoffDelayMs", () => {
|
|
5
|
-
it("grows exponentially from the base delay", () => {
|
|
6
|
-
expect(backoffDelayMs(1)).toBe(RETRY_POLICY.baseDelayMs);
|
|
7
|
-
expect(backoffDelayMs(2)).toBe(RETRY_POLICY.baseDelayMs * RETRY_POLICY.factor);
|
|
8
|
-
expect(backoffDelayMs(3)).toBe(RETRY_POLICY.baseDelayMs * RETRY_POLICY.factor ** 2);
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
describe("isRetryable", () => {
|
|
13
|
-
it("retries transient network error codes", () => {
|
|
14
|
-
expect(isRetryable({ code: "ECONNRESET" })).toBe(true);
|
|
15
|
-
expect(isRetryable({ code: "ETIMEDOUT" })).toBe(true);
|
|
16
|
-
});
|
|
17
|
-
it("retries 5xx", () => {
|
|
18
|
-
expect(isRetryable({ httpStatus: 502 })).toBe(true);
|
|
19
|
-
});
|
|
20
|
-
it("does not retry 4xx business errors", () => {
|
|
21
|
-
expect(isRetryable({ httpStatus: 400 })).toBe(false);
|
|
22
|
-
expect(isRetryable({ httpStatus: 402 })).toBe(false);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vitest/config";
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
environment: "node",
|
|
6
|
-
include: ["tests/**/*.test.ts"],
|
|
7
|
-
coverage: {
|
|
8
|
-
provider: "v8",
|
|
9
|
-
include: ["src/**/*.ts"],
|
|
10
|
-
reporter: ["text", "lcov"],
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/claude-code-plugin.json",
|
|
3
|
-
"name": "kolmopdf",
|
|
4
|
-
"displayName": "KolmoPDF",
|
|
5
|
-
"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.",
|
|
6
|
-
"version": "1.0.0",
|
|
7
|
-
"author": {
|
|
8
|
-
"name": "KomoAI LLC",
|
|
9
|
-
"email": "support@kolmopdf.com"
|
|
10
|
-
},
|
|
11
|
-
"homepage": "https://www.kolmopdf.com",
|
|
12
|
-
"repository": "https://github.com/kolmopdf/claude-plugin",
|
|
13
|
-
"license": "MIT",
|
|
14
|
-
"keywords": ["pdf", "markdown", "ocr", "translation", "latex", "research", "arxiv", "kolmopdf"],
|
|
15
|
-
"category": "document-processing"
|
|
16
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# KolmoPDF
|
|
2
|
-
|
|
3
|
-
## Install
|
|
4
|
-
|
|
5
|
-
| Client | Command |
|
|
6
|
-
| --- | --- |
|
|
7
|
-
| Claude Code | `/plugin marketplace add kolmopdf/claude-plugin` then `/plugin install kolmopdf@kolmopdf` |
|
|
8
|
-
| Codex CLI | `cp -r codex-skill/kolmopdf ~/.codex/skills/` + add `[mcp_servers.kolmopdf]` to `~/.codex/config.toml` |
|
|
9
|
-
| Cursor | `cp -r codex-skill/kolmopdf ~/.cursor/skills/` + add server to `~/.cursor/mcp.json` |
|
|
10
|
-
| Claude Desktop | Add server to `claude_desktop_config.json` (MCP tools only, no skill auto-trigger) |
|
|
11
|
-
|
|
12
|
-
## API key
|
|
13
|
-
|
|
14
|
-
Create a key at https://www.kolmopdf.com/api-keys (requires Plus or Pro), then set `KOLMOPDF_API_KEY` in your environment.
|
|
15
|
-
|
|
16
|
-
## Tools
|
|
17
|
-
|
|
18
|
-
| Tool | Capability |
|
|
19
|
-
| --- | --- |
|
|
20
|
-
| `kolmopdf_parse_pdf` | PDF → Markdown (optional translation) |
|
|
21
|
-
| `kolmopdf_translate_pdf` | Layout-preserving PDF translation |
|
|
22
|
-
| `kolmopdf_convert_markdown` | Markdown → DOCX / HTML / PDF / LaTeX |
|
|
23
|
-
| `kolmopdf_estimate_cost` | Pre-flight credit estimate |
|
|
24
|
-
| `kolmopdf_check_balance` | Current credit balance |
|
|
25
|
-
|
|
26
|
-
## License
|
|
27
|
-
|
|
28
|
-
MIT
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Convert Markdown to DOCX, HTML, PDF, or LaTeX (KolmoPDF).
|
|
3
|
-
argument-hint: <markdown-or-zip-path> [--format word|docx|html|pdf|latex|tex]
|
|
4
|
-
allowed-tools: mcp__kolmopdf__kolmopdf_convert_markdown, mcp__kolmopdf__kolmopdf_estimate_cost
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Convert the provided Markdown file (or ZIP archive containing markdown + images) to the target format. Steps:
|
|
8
|
-
|
|
9
|
-
1. Parse arguments. Default `--format word`.
|
|
10
|
-
2. Call `kolmopdf_estimate_cost` for operation `convert` (always 1 credit). Stop if insufficient.
|
|
11
|
-
3. Call `kolmopdf_convert_markdown`.
|
|
12
|
-
4. Report `output.output_path` to the user.
|
|
13
|
-
|
|
14
|
-
Arguments: $ARGUMENTS
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Parse a PDF to Markdown via KolmoPDF (handles formulas, tables, multi-column).
|
|
3
|
-
argument-hint: <file-path> [--translate] [--target-lang zh|en|ja|ko|fr|de|es|ru]
|
|
4
|
-
allowed-tools: mcp__kolmopdf__kolmopdf_parse_pdf, mcp__kolmopdf__kolmopdf_estimate_cost
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Parse the PDF at the provided path using KolmoPDF. Steps:
|
|
8
|
-
|
|
9
|
-
1. Run `kolmopdf_estimate_cost` for operation `parse` (or `parse_translate` if `--translate` was passed) and report the cost. If `sufficient=false`, stop.
|
|
10
|
-
2. If `--translate` was passed, set `enable_translation=true` and use the `--target-lang` value (default `zh`) with `output_options=["bilingual"]`.
|
|
11
|
-
3. Call `kolmopdf_parse_pdf`.
|
|
12
|
-
4. Report `output.markdown_path` and `preview` to the user.
|
|
13
|
-
|
|
14
|
-
Arguments: $ARGUMENTS
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Translate a PDF while preserving its original layout (KolmoPDF).
|
|
3
|
-
argument-hint: <file-path> [--from <lang>] [--to <lang>] [--mode translated_only|side_by_side]
|
|
4
|
-
allowed-tools: mcp__kolmopdf__kolmopdf_translate_pdf, mcp__kolmopdf__kolmopdf_estimate_cost
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Translate the PDF while preserving its layout. Steps:
|
|
8
|
-
|
|
9
|
-
1. Parse the file path and flags from $ARGUMENTS. Defaults: `--from en`, `--to zh`, `--mode translated_only`.
|
|
10
|
-
2. Call `kolmopdf_estimate_cost` for operation `translate`. Stop if insufficient.
|
|
11
|
-
3. Call `kolmopdf_translate_pdf` with the parsed arguments.
|
|
12
|
-
4. Report `output.translated_pdf_path` to the user.
|
|
13
|
-
|
|
14
|
-
Arguments: $ARGUMENTS
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: kolmopdf
|
|
3
|
-
description: Use this skill ONLY when the user gives an explicit operational instruction to process a PDF or Markdown file. Specifically: (1) explicitly asks to parse/convert a PDF into Markdown, (2) explicitly asks for layout-preserving PDF translation to produce a new translated PDF, (3) explicitly asks to export/convert Markdown to DOCX/HTML/PDF/LaTeX, or (4) a combination of the above (e.g. "parse this PDF to Markdown, then translate it, then export to DOCX"). Do NOT trigger for general PDF reading, summarization, or Q&A unless the user explicitly requests Markdown extraction first. Triggers: "parse PDF to markdown", "convert PDF to markdown", "translate this PDF preserving layout", "export markdown to docx/html/pdf/latex", "PDF to markdown with tables as images", "parse and translate this PDF".
|
|
4
|
-
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
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# KolmoPDF Skill
|
|
8
|
-
|
|
9
|
-
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.
|
|
10
|
-
|
|
11
|
-
## When to use
|
|
12
|
-
|
|
13
|
-
This skill triggers ONLY on explicit user instructions to perform a file operation:
|
|
14
|
-
|
|
15
|
-
- User explicitly asks to parse/convert a PDF into Markdown → `kolmopdf_parse_pdf`.
|
|
16
|
-
- User explicitly asks for layout-preserving PDF translation → `kolmopdf_translate_pdf`.
|
|
17
|
-
- User explicitly asks to export Markdown to DOCX/HTML/PDF/LaTeX → `kolmopdf_convert_markdown`.
|
|
18
|
-
- User requests a combination (e.g. "parse this PDF, translate it, then export to DOCX") → chain the tools in sequence.
|
|
19
|
-
|
|
20
|
-
Do NOT trigger when:
|
|
21
|
-
- User just wants to read or summarize a PDF without requesting Markdown output.
|
|
22
|
-
- User asks general questions about a PDF's content (use built-in Read instead).
|
|
23
|
-
- User mentions PDF in passing without an explicit processing instruction.
|
|
24
|
-
|
|
25
|
-
## Natural language parameter mapping
|
|
26
|
-
|
|
27
|
-
Users may describe parameters in natural language. Map their descriptions to tool parameters:
|
|
28
|
-
|
|
29
|
-
| User says | Parameter |
|
|
30
|
-
| --- | --- |
|
|
31
|
-
| "tables as images" / "keep table layout" | `table_mode="image"` |
|
|
32
|
-
| "use dollar signs for formulas" / "KaTeX format" | `formula_format="dollar"` |
|
|
33
|
-
| "use bracket notation" / "LaTeX-style delimiters" | `formula_format="bracket"` |
|
|
34
|
-
| "translate to Chinese/Japanese/..." | `enable_translation=true`, `target_language="zh"/"ja"/...` |
|
|
35
|
-
| "bilingual output" / "show both languages" | `output_options=["bilingual"]` |
|
|
36
|
-
| "images as URLs" / "don't download images" | `images_as_url=true` |
|
|
37
|
-
| "merge tables across pages" / "cross-page tables" | `enable_cross_page_merge=true` |
|
|
38
|
-
| "side by side translation" | `layout_modes=["side_by_side"]` |
|
|
39
|
-
| "translate images too" | `enable_image_translation=true` |
|
|
40
|
-
| "translate tables too" | `enable_table_translation=true` |
|
|
41
|
-
| "export to Word/DOCX/HTML/PDF/LaTeX" | `target_format` accordingly |
|
|
42
|
-
|
|
43
|
-
When the user's natural language is ambiguous, use sensible defaults from `references/parameter-glossary.md`. When the user specifies multiple preferences in one request, combine all applicable parameters in a single tool call.
|
|
44
|
-
|
|
45
|
-
## Cost-awareness protocol
|
|
46
|
-
|
|
47
|
-
Before running any operation that consumes credits:
|
|
48
|
-
|
|
49
|
-
1. Call `kolmopdf_estimate_cost` with the file path and intended operation.
|
|
50
|
-
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.
|
|
51
|
-
3. If `estimated_credits > 50`: tell the user the estimated cost and ask for confirmation before proceeding.
|
|
52
|
-
4. Otherwise: proceed.
|
|
53
|
-
|
|
54
|
-
## API key requirement
|
|
55
|
-
|
|
56
|
-
Tools require `KOLMOPDF_API_KEY` in the MCP server environment. If a tool returns `invalid_api_key`:
|
|
57
|
-
|
|
58
|
-
- Direct the user to https://www.kolmopdf.com/api-keys to create a key (requires Plus or Pro plan).
|
|
59
|
-
- Tell the user to set `KOLMOPDF_API_KEY` in their environment and restart Claude Code.
|
|
60
|
-
- Do not proceed with retries until the user confirms.
|
|
61
|
-
|
|
62
|
-
## Chained workflows
|
|
63
|
-
|
|
64
|
-
### PDF → DOCX/HTML/PDF/LaTeX (full pipeline)
|
|
65
|
-
|
|
66
|
-
1. `kolmopdf_estimate_cost(file, "parse")` → check balance.
|
|
67
|
-
2. `kolmopdf_parse_pdf(file)` → get `markdown_path`.
|
|
68
|
-
3. `kolmopdf_convert_markdown(markdown_path, target_format)` → final file.
|
|
69
|
-
|
|
70
|
-
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`.
|
|
71
|
-
|
|
72
|
-
### Read + ask Q&A about a paper
|
|
73
|
-
|
|
74
|
-
1. `kolmopdf_parse_pdf(file)` → get `markdown_path` and `preview`.
|
|
75
|
-
2. Use `Read` on `markdown_path` to load the full content.
|
|
76
|
-
3. Answer the user's question grounded in the markdown.
|
|
77
|
-
|
|
78
|
-
### Translate then convert to bilingual deliverable
|
|
79
|
-
|
|
80
|
-
Option A (PDF deliverable):
|
|
81
|
-
- `kolmopdf_translate_pdf(file, layout_modes=["side_by_side"])` → single PDF with side-by-side layout.
|
|
82
|
-
|
|
83
|
-
Option B (editable Markdown deliverable):
|
|
84
|
-
- `kolmopdf_parse_pdf(file, enable_translation=true, output_options=["bilingual"])` → bilingual markdown.
|
|
85
|
-
|
|
86
|
-
## Parameter guidance
|
|
87
|
-
|
|
88
|
-
See `references/parameter-glossary.md` for the full parameter table and defaults. Highlights:
|
|
89
|
-
|
|
90
|
-
- `formula_format=dollar` is the default and works with KaTeX/MathJax. Use `bracket` for LaTeX-strict downstream renderers.
|
|
91
|
-
- `enable_cross_page_merge=true` is recommended when the source PDF has tables spanning page breaks.
|
|
92
|
-
- `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.
|
|
93
|
-
|
|
94
|
-
## Output handling
|
|
95
|
-
|
|
96
|
-
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.
|
|
97
|
-
|
|
98
|
-
## Failure modes
|
|
99
|
-
|
|
100
|
-
| error_code | Action |
|
|
101
|
-
| --- | --- |
|
|
102
|
-
| `invalid_api_key` | Stop; follow API key requirement section above. |
|
|
103
|
-
| `insufficient_points` | Stop; report shortfall and top-up URL. |
|
|
104
|
-
| `parse_page_limit_exceeded`, `parse_file_too_large` | Stop; suggest splitting the PDF locally. |
|
|
105
|
-
| `parse_file_not_pdf`, `parse_file_invalid` | Stop; ask the user to re-export the PDF. |
|
|
106
|
-
| `parse_error`, `parse_timeout` | Server auto-refunds points. Suggest retry with smaller page range. |
|
|
107
|
-
| `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. |
|
|
108
|
-
| Network/5xx | Tools auto-retry up to 3 times. If still failing, suggest checking https://www.kolmopdf.com/contact. |
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# KolmoPDF Chain Recipes
|
|
2
|
-
|
|
3
|
-
Expanded, step-by-step playbooks for the chained workflows summarized in `SKILL.md`.
|
|
4
|
-
|
|
5
|
-
## Recipe 1 — PDF → DOCX/HTML/PDF/LaTeX (full pipeline)
|
|
6
|
-
|
|
7
|
-
1. `kolmopdf_estimate_cost({ file_path, operation: "parse" })`.
|
|
8
|
-
- If `sufficient=false` → stop; report `shortfall` + https://www.kolmopdf.com/subscription.
|
|
9
|
-
- If `estimated_credits > 50` → ask the user to confirm.
|
|
10
|
-
2. `kolmopdf_parse_pdf({ file_path })` → capture `output.markdown_path` and `output.output_root`.
|
|
11
|
-
3. Decide the convert input:
|
|
12
|
-
- **Markdown has no local images** (or `images_as_url=true` was used): pass `output.markdown_path` directly.
|
|
13
|
-
- **Markdown references local images**: zip `output.output_root` with your own tools (`Write`/shell), then pass the `.zip` path so figures survive conversion.
|
|
14
|
-
4. `kolmopdf_convert_markdown({ file_path: <md-or-zip>, target_format })`.
|
|
15
|
-
5. Report `output.output_path` to the user (absolute path).
|
|
16
|
-
|
|
17
|
-
Total cost ≈ `pages × 2 + 1`.
|
|
18
|
-
|
|
19
|
-
## Recipe 2 — Read + Q&A about a paper
|
|
20
|
-
|
|
21
|
-
1. `kolmopdf_parse_pdf({ file_path })` → `output.markdown_path`, `preview`.
|
|
22
|
-
2. `Read` the `markdown_path` to load full content into context.
|
|
23
|
-
3. Answer the user's question grounded strictly in the parsed markdown. Cite section headings where useful.
|
|
24
|
-
|
|
25
|
-
## Recipe 3 — Translate then deliver bilingual
|
|
26
|
-
|
|
27
|
-
**Option A — PDF deliverable (layout preserved):**
|
|
28
|
-
1. `kolmopdf_estimate_cost({ file_path, operation: "translate" })`.
|
|
29
|
-
2. `kolmopdf_translate_pdf({ file_path, source_language, target_language, layout_modes: ["side_by_side"] })`.
|
|
30
|
-
3. Report `output.translated_pdf_path`.
|
|
31
|
-
|
|
32
|
-
**Option B — editable Markdown deliverable:**
|
|
33
|
-
1. `kolmopdf_estimate_cost({ file_path, operation: "parse_translate" })`.
|
|
34
|
-
2. `kolmopdf_parse_pdf({ file_path, enable_translation: true, target_language, output_options: ["bilingual"] })`.
|
|
35
|
-
3. Report `output.markdown_path`. Optionally chain Recipe 1 step 4 to produce a bilingual DOCX.
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# KolmoPDF Parameter Glossary
|
|
2
|
-
|
|
3
|
-
Full parameter reference for the KolmoPDF tools. This file is not auto-loaded; the skill reads it on demand.
|
|
4
|
-
|
|
5
|
-
## `kolmopdf_parse_pdf`
|
|
6
|
-
|
|
7
|
-
| Parameter | Type | Legal values | Default | Billing impact |
|
|
8
|
-
| --- | --- | --- | --- | --- |
|
|
9
|
-
| `file_path` | string | local path to a `.pdf` | — | — |
|
|
10
|
-
| `table_mode` | enum | `markdown`, `image` | `markdown` | none |
|
|
11
|
-
| `formula_format` | enum | `dollar`, `bracket` | `dollar` | none |
|
|
12
|
-
| `enable_translation` | boolean | `true`, `false` | `false` | `true` → 3 pts/page instead of 2 |
|
|
13
|
-
| `target_language` | enum | `zh`, `en`, `ja`, `ko`, `fr`, `de`, `es`, `ru` | `zh` | only when `enable_translation=true` |
|
|
14
|
-
| `output_options` | string[] | `original`, `translated`, `bilingual` | `original` | none |
|
|
15
|
-
| `images_as_url` | boolean | `true`, `false` | `false` | none (`true` → single `.md` w/ 30-day URLs; `false` → ZIP) |
|
|
16
|
-
| `skip_rotation_detection` | boolean | `true`, `false` | `false` | none |
|
|
17
|
-
| `enable_cross_page_merge` | boolean | `true`, `false` | `false` | none (merges tables across ≤ 3 pages) |
|
|
18
|
-
| `output_subdir` | string | any dir name | `<task_id>` | none |
|
|
19
|
-
|
|
20
|
-
Cost: parse only = `pages × 2`; parse + translate = `pages × 3`.
|
|
21
|
-
|
|
22
|
-
## `kolmopdf_translate_pdf`
|
|
23
|
-
|
|
24
|
-
| Parameter | Type | Legal values | Default |
|
|
25
|
-
| --- | --- | --- | --- |
|
|
26
|
-
| `file_path` | string | local path to a `.pdf` | — |
|
|
27
|
-
| `source_language` | string | language code | `en` |
|
|
28
|
-
| `target_language` | string | language code | `zh` |
|
|
29
|
-
| `layout_modes` | string[] | `translated_only`, `side_by_side` | `["translated_only"]` |
|
|
30
|
-
| `enable_image_translation` | boolean | `true`, `false` | `false` |
|
|
31
|
-
| `enable_table_translation` | boolean | `true`, `false` | `false` |
|
|
32
|
-
| `output_subdir` | string | any dir name | `<task_id>` |
|
|
33
|
-
|
|
34
|
-
Cost: `pages × 2`.
|
|
35
|
-
|
|
36
|
-
## `kolmopdf_convert_markdown`
|
|
37
|
-
|
|
38
|
-
| Parameter | Type | Legal values | Default |
|
|
39
|
-
| --- | --- | --- | --- |
|
|
40
|
-
| `file_path` | string | `.md`, `.markdown`, or `.zip` | — |
|
|
41
|
-
| `target_format` | enum | `word`, `docx`, `html`, `pdf`, `latex`, `tex` | `word` |
|
|
42
|
-
| `output_subdir` | string | any dir name | `<task_id>` |
|
|
43
|
-
|
|
44
|
-
Extension mapping: `word|docx → .docx`, `html → .html`, `pdf → .pdf`, `latex|tex → .tex`.
|
|
45
|
-
|
|
46
|
-
Cost: 1 credit/task.
|
|
47
|
-
|
|
48
|
-
## Language codes
|
|
49
|
-
|
|
50
|
-
| Code | Language |
|
|
51
|
-
| --- | --- |
|
|
52
|
-
| `zh` | Chinese |
|
|
53
|
-
| `en` | English |
|
|
54
|
-
| `ja` | Japanese |
|
|
55
|
-
| `ko` | Korean |
|
|
56
|
-
| `fr` | French |
|
|
57
|
-
| `de` | German |
|
|
58
|
-
| `es` | Spanish |
|
|
59
|
-
| `ru` | Russian |
|
|
60
|
-
|
|
61
|
-
## ZIP output structure (`images_as_url=false`)
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
<KOLMOPDF_OUTPUT_DIR>/<task_id>/
|
|
65
|
-
├── <document>.md # canonical markdown_path (first *.md found)
|
|
66
|
-
├── images/ # extracted figures → images_dir
|
|
67
|
-
│ ├── img-0001.png
|
|
68
|
-
│ └── ...
|
|
69
|
-
└── (other assets, flattened)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
When `images_as_url=true`, the result is a single `result.md` with public image URLs (cached 30 days) and `images_dir = null`.
|
package/pnpm-workspace.yaml
DELETED
package/smithery.yaml
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
startCommand:
|
|
2
|
-
type: stdio
|
|
3
|
-
configSchema:
|
|
4
|
-
type: object
|
|
5
|
-
required: [KOLMOPDF_API_KEY]
|
|
6
|
-
properties:
|
|
7
|
-
KOLMOPDF_API_KEY:
|
|
8
|
-
type: string
|
|
9
|
-
description: "Your KolmoPDF API key (get one at https://www.kolmopdf.com/api-keys)."
|
|
10
|
-
KOLMOPDF_BASE_URL:
|
|
11
|
-
type: string
|
|
12
|
-
default: "https://www.kolmopdf.com"
|
|
13
|
-
commandFunction: |
|
|
14
|
-
(config) => ({
|
|
15
|
-
command: "npx",
|
|
16
|
-
args: ["-y", "@kolmopdf/mcp-server"],
|
|
17
|
-
env: {
|
|
18
|
-
KOLMOPDF_API_KEY: config.KOLMOPDF_API_KEY,
|
|
19
|
-
KOLMOPDF_BASE_URL: config.KOLMOPDF_BASE_URL || "https://www.kolmopdf.com"
|
|
20
|
-
}
|
|
21
|
-
})
|
package/tsconfig.base.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"target": "ES2022",
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"moduleResolution": "Bundler",
|
|
7
|
-
"lib": ["ES2022"],
|
|
8
|
-
"strict": true,
|
|
9
|
-
"noUncheckedIndexedAccess": true,
|
|
10
|
-
"noImplicitOverride": true,
|
|
11
|
-
"noFallthroughCasesInSwitch": true,
|
|
12
|
-
"esModuleInterop": true,
|
|
13
|
-
"forceConsistentCasingInFileNames": true,
|
|
14
|
-
"skipLibCheck": true,
|
|
15
|
-
"declaration": true,
|
|
16
|
-
"sourceMap": true,
|
|
17
|
-
"resolveJsonModule": true,
|
|
18
|
-
"isolatedModules": true,
|
|
19
|
-
"verbatimModuleSyntax": true
|
|
20
|
-
}
|
|
21
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|