pdf-to-markdown-mcp 1.0.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,8 +29,11 @@ The server needs the following environment variables:
29
29
  - `QWEN_API_URL`: The endpoint URL (e.g., `https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions`)
30
30
  - `QWEN_API_KEY`: Your authentication key.
31
31
  - `QWEN_MODEL`: The specific model name (defaults to `Qwen3-VL-235B-A22B-Instruct`).
32
+ - `VLLM_REASONING_PARSER` (optional): When you serve a reasoning model through vLLM and need thinking disabled, set this to `kimi_k2` for Kimi K2.x or `qwen3` for Qwen3. The server will send the matching `chat_template_kwargs` expected by vLLM.
32
33
  - `WORKSPACE` (optional): Comma-separated list of absolute directory paths. When set, the server will only process PDF files located within these directories, preventing access to files outside the allowed workspace.
33
34
 
35
+ The runtime and test scripts automatically load a project-local `.env` file when one is present, so you can usually keep these values in `.env` instead of exporting them in your shell.
36
+
34
37
  ### 3. Setup with Claude Desktop
35
38
  Add this to your Claude Desktop configuration file:
36
39
 
@@ -53,6 +56,35 @@ Add this to your Claude Desktop configuration file:
53
56
  }
54
57
  ```
55
58
 
59
+ ### vLLM reasoning models
60
+
61
+ If your OpenAI-compatible endpoint is powered by vLLM and the served model defaults to thinking mode, configure the parser so the server can disable it correctly:
62
+
63
+ - `VLLM_REASONING_PARSER=kimi_k2` sends `chat_template_kwargs: { "thinking": false }`
64
+ - `VLLM_REASONING_PARSER=qwen3` sends `chat_template_kwargs: { "enable_thinking": false }`
65
+
66
+ Example MCP configuration for Kimi K2.x through vLLM:
67
+
68
+ ```json
69
+ {
70
+ "mcpServers": {
71
+ "pdf-to-markdown": {
72
+ "command": "npx",
73
+ "args": [
74
+ "-y",
75
+ "pdf-to-markdown-mcp"
76
+ ],
77
+ "env": {
78
+ "QWEN_API_URL": "http://your-vllm-host:8000/v1/chat/completions",
79
+ "QWEN_API_KEY": "EMPTY",
80
+ "QWEN_MODEL": "moonshotai/Kimi-K2.6-Vision-Instruct",
81
+ "VLLM_REASONING_PARSER": "kimi_k2"
82
+ }
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
56
88
  ## Usage
57
89
 
58
90
  Once connected, you can use the `convert_pdf_page_to_markdown` tool.
@@ -77,7 +109,7 @@ Depending on your OS, you may need additional libraries for PDF rendering:
77
109
  ## Troubleshooting
78
110
  - **"PDF file not found"**: Ensure the path is absolute and the file is accessible.
79
111
  - **"Invalid page number"**: Check that the page number exists in the document.
80
- - **API Errors**: Verify your `QWEN_API_URL` and `QWEN_API_KEY`.
112
+ - **API Errors**: Verify your `QWEN_API_URL` and `QWEN_API_KEY` in `.env` or your shell environment.
81
113
  - **Render Failures**: If conversion fails on Linux/macOS, ensure the **System Dependencies** above are installed.
82
114
 
83
115
  ## License
package/TESTING.md CHANGED
@@ -17,7 +17,7 @@ This will test:
17
17
 
18
18
  ### 2. Test Full PDF to Markdown Conversion (Requires API Keys)
19
19
 
20
- First, set up your Qwen API credentials:
20
+ The test runner automatically loads a project-local `.env` file when one is present. If you prefer not to use `.env`, set up your Qwen API credentials manually:
21
21
 
22
22
  **Windows (PowerShell):**
23
23
  ```powershell
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import "dotenv/config";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,35 +1,19 @@
1
1
  #!/usr/bin/env node
2
+ import "dotenv/config";
2
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
5
  import * as fs from "node:fs/promises";
5
6
  import * as path from "node:path";
6
7
  import { z } from "zod";
8
+ import { buildOpenAICompatibleRequest } from "./openaiCompatibleRequest.js";
7
9
  import { convertPdfPageToImage } from "./pdfConverter.js";
8
10
  /**
9
11
  * Call Qwen VL API to convert image to markdown
10
12
  */
11
- async function convertImageToMarkdown(imageBuffer, apiUrl, apiKey, modelName) {
12
- const base64Image = imageBuffer.toString("base64");
13
- const requestBody = {
14
- model: modelName,
15
- messages: [
16
- {
17
- role: "user",
18
- content: [
19
- {
20
- type: "image_url",
21
- image_url: {
22
- url: `data:image/png;base64,${base64Image}`,
23
- },
24
- },
25
- {
26
- type: "text",
27
- text: "Please convert this image to markdown format. Extract all text, tables, and structure accurately.",
28
- },
29
- ],
30
- },
31
- ],
32
- };
13
+ async function convertImageToMarkdown(imageBuffer, apiUrl, apiKey, modelName, vllmReasoningParser) {
14
+ const requestBody = buildOpenAICompatibleRequest(imageBuffer, modelName, {
15
+ vllmReasoningParser,
16
+ });
33
17
  const response = await fetch(apiUrl, {
34
18
  method: "POST",
35
19
  headers: {
@@ -59,6 +43,7 @@ async function main() {
59
43
  const apiUrl = process.env.QWEN_API_URL;
60
44
  const apiKey = process.env.QWEN_API_KEY;
61
45
  const modelName = process.env.QWEN_MODEL || "Qwen3-VL-235B-A22B-Instruct";
46
+ const vllmReasoningParser = process.env.VLLM_REASONING_PARSER;
62
47
  if (!apiUrl || !apiKey) {
63
48
  throw new Error("Missing required environment variables: QWEN_API_URL and QWEN_API_KEY must be set");
64
49
  }
@@ -108,7 +93,7 @@ async function main() {
108
93
  // Convert PDF page to image
109
94
  const imageBuffer = await convertPdfPageToImage(pdf_path, page_number);
110
95
  // Convert image to markdown using Qwen VL
111
- const markdown = await convertImageToMarkdown(imageBuffer, apiUrl, apiKey, modelName);
96
+ const markdown = await convertImageToMarkdown(imageBuffer, apiUrl, apiKey, modelName, vllmReasoningParser);
112
97
  return {
113
98
  content: [
114
99
  {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export declare const supportedVllmReasoningParsers: readonly ["kimi_k2", "qwen3"];
2
+ export type VllmReasoningParser = (typeof supportedVllmReasoningParsers)[number];
3
+ type VisionContentPart = {
4
+ type: "image_url";
5
+ image_url: {
6
+ url: string;
7
+ };
8
+ } | {
9
+ type: "text";
10
+ text: string;
11
+ };
12
+ export interface OpenAICompatibleChatCompletionRequest {
13
+ model: string;
14
+ messages: Array<{
15
+ role: "user";
16
+ content: VisionContentPart[];
17
+ }>;
18
+ chat_template_kwargs?: Record<string, boolean>;
19
+ }
20
+ interface BuildOpenAICompatibleRequestOptions {
21
+ vllmReasoningParser?: string;
22
+ }
23
+ export declare function buildOpenAICompatibleRequest(imageBuffer: Buffer, modelName: string, options?: BuildOpenAICompatibleRequestOptions): OpenAICompatibleChatCompletionRequest;
24
+ export {};
25
+ //# sourceMappingURL=openaiCompatibleRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiCompatibleRequest.d.ts","sourceRoot":"","sources":["../../src/openaiCompatibleRequest.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,+BAAgC,CAAC;AAE3E,MAAM,MAAM,mBAAmB,GAC7B,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,KAAK,iBAAiB,GAClB;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,iBAAiB,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChD;AAED,UAAU,mCAAmC;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAqCD,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,mCAAwC,GAChD,qCAAqC,CAmCvC"}
@@ -0,0 +1,53 @@
1
+ export const supportedVllmReasoningParsers = ["kimi_k2", "qwen3"];
2
+ function parseVllmReasoningParser(vllmReasoningParser) {
3
+ if (!vllmReasoningParser) {
4
+ return undefined;
5
+ }
6
+ const normalizedParser = vllmReasoningParser
7
+ .trim()
8
+ .toLowerCase()
9
+ .replace(/[\s-]+/g, "_");
10
+ if (normalizedParser === "kimi_k2" || normalizedParser === "qwen3") {
11
+ return normalizedParser;
12
+ }
13
+ throw new Error(`Unsupported VLLM_REASONING_PARSER \"${vllmReasoningParser}\". Supported values: ${supportedVllmReasoningParsers.join(", ")}.`);
14
+ }
15
+ function getThinkingDisabledChatTemplateKwargs(vllmReasoningParser) {
16
+ if (!vllmReasoningParser) {
17
+ return undefined;
18
+ }
19
+ if (vllmReasoningParser === "kimi_k2") {
20
+ return { thinking: false };
21
+ }
22
+ return { enable_thinking: false };
23
+ }
24
+ export function buildOpenAICompatibleRequest(imageBuffer, modelName, options = {}) {
25
+ const base64Image = imageBuffer.toString("base64");
26
+ const vllmReasoningParser = parseVllmReasoningParser(options.vllmReasoningParser);
27
+ const requestBody = {
28
+ model: modelName,
29
+ messages: [
30
+ {
31
+ role: "user",
32
+ content: [
33
+ {
34
+ type: "image_url",
35
+ image_url: {
36
+ url: `data:image/png;base64,${base64Image}`,
37
+ },
38
+ },
39
+ {
40
+ type: "text",
41
+ text: "Please convert this image to markdown format. Extract all text, tables, and structure accurately.",
42
+ },
43
+ ],
44
+ },
45
+ ],
46
+ };
47
+ const chatTemplateKwargs = getThinkingDisabledChatTemplateKwargs(vllmReasoningParser);
48
+ if (chatTemplateKwargs) {
49
+ requestBody.chat_template_kwargs = chatTemplateKwargs;
50
+ }
51
+ return requestBody;
52
+ }
53
+ //# sourceMappingURL=openaiCompatibleRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiCompatibleRequest.js","sourceRoot":"","sources":["../../src/openaiCompatibleRequest.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,SAAS,EAAE,OAAO,CAAU,CAAC;AA8B3E,SAAS,wBAAwB,CAC/B,mBAA4B;IAE5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,gBAAgB,GAAG,mBAAmB;SACzC,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAE3B,IAAI,gBAAgB,KAAK,SAAS,IAAI,gBAAgB,KAAK,OAAO,EAAE,CAAC;QACnE,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,MAAM,IAAI,KAAK,CACb,uCAAuC,mBAAmB,yBAAyB,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC/H,CAAC;AACJ,CAAC;AAED,SAAS,qCAAqC,CAC5C,mBAAyC;IAEzC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,WAAmB,EACnB,SAAiB,EACjB,UAA+C,EAAE;IAEjD,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,mBAAmB,GAAG,wBAAwB,CAClD,OAAO,CAAC,mBAAmB,CAC5B,CAAC;IACF,MAAM,WAAW,GAA0C;QACzD,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,WAAW;wBACjB,SAAS,EAAE;4BACT,GAAG,EAAE,yBAAyB,WAAW,EAAE;yBAC5C;qBACF;oBACD;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mGAAmG;qBAC1G;iBACF;aACF;SACF;KACF,CAAC;IAEF,MAAM,kBAAkB,GAAG,qCAAqC,CAC9D,mBAAmB,CACpB,CAAC;IAEF,IAAI,kBAAkB,EAAE,CAAC;QACvB,WAAW,CAAC,oBAAoB,GAAG,kBAAkB,CAAC;IACxD,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -1,2 +1,2 @@
1
- export {};
1
+ import "dotenv/config";
2
2
  //# sourceMappingURL=demo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../test/demo.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../test/demo.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC"}
package/dist/test/demo.js CHANGED
@@ -1,3 +1,4 @@
1
+ import "dotenv/config";
1
2
  import { convertPdfPageToImage } from "../src/pdfConverter.js";
2
3
  import * as fs from "node:fs/promises";
3
4
  import * as path from "node:path";
@@ -55,9 +56,7 @@ async function main() {
55
56
  console.error("\nPlease set environment variables:");
56
57
  console.error(" QWEN_API_URL - Qwen API endpoint URL");
57
58
  console.error(" QWEN_API_KEY - Your Qwen API key\n");
58
- console.error("Windows (PowerShell):");
59
- console.error(' $env:QWEN_API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"');
60
- console.error(' $env:QWEN_API_KEY = "your-api-key-here"\n');
59
+ console.error("The project automatically loads a local .env file when present, so you can store the values there instead of exporting them every time.\n");
61
60
  process.exit(1);
62
61
  }
63
62
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../test/demo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../test/demo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openaiCompatibleRequest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiCompatibleRequest.test.d.ts","sourceRoot":"","sources":["../../test/openaiCompatibleRequest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import assert from "node:assert/strict";
2
+ import { buildOpenAICompatibleRequest, supportedVllmReasoningParsers, } from "../src/openaiCompatibleRequest.js";
3
+ function run() {
4
+ const sampleImage = Buffer.from("sample-image");
5
+ const genericRequest = buildOpenAICompatibleRequest(sampleImage, "moonshotai/Kimi-K2.6-Vision-Instruct");
6
+ assert.equal(genericRequest.chat_template_kwargs, undefined);
7
+ const kimiRequest = buildOpenAICompatibleRequest(sampleImage, "moonshotai/Kimi-K2.6-Vision-Instruct", { vllmReasoningParser: "kimi_k2" });
8
+ assert.deepEqual(kimiRequest.chat_template_kwargs, { thinking: false });
9
+ const qwenRequest = buildOpenAICompatibleRequest(sampleImage, "Qwen/Qwen3-VL-235B-A22B-Instruct", { vllmReasoningParser: "qwen3" });
10
+ assert.deepEqual(qwenRequest.chat_template_kwargs, {
11
+ enable_thinking: false,
12
+ });
13
+ assert.throws(() => buildOpenAICompatibleRequest(sampleImage, "moonshotai/Kimi-K2.6", {
14
+ vllmReasoningParser: "unknown-parser",
15
+ }), {
16
+ message: new RegExp(`Supported values: ${supportedVllmReasoningParsers.join(", ")}`),
17
+ });
18
+ console.log("✓ OpenAI-compatible request builder tests passed");
19
+ }
20
+ run();
21
+ //# sourceMappingURL=openaiCompatibleRequest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiCompatibleRequest.test.js","sourceRoot":"","sources":["../../test/openaiCompatibleRequest.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,mCAAmC,CAAC;AAE3C,SAAS,GAAG;IACV,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAEhD,MAAM,cAAc,GAAG,4BAA4B,CACjD,WAAW,EACX,sCAAsC,CACvC,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,4BAA4B,CAC9C,WAAW,EACX,sCAAsC,EACtC,EAAE,mBAAmB,EAAE,SAAS,EAAE,CACnC,CAAC;IACF,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAExE,MAAM,WAAW,GAAG,4BAA4B,CAC9C,WAAW,EACX,kCAAkC,EAClC,EAAE,mBAAmB,EAAE,OAAO,EAAE,CACjC,CAAC;IACF,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,oBAAoB,EAAE;QACjD,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CACH,4BAA4B,CAAC,WAAW,EAAE,sBAAsB,EAAE;QAChE,mBAAmB,EAAE,gBAAgB;KACtC,CAAC,EACJ;QACE,OAAO,EAAE,IAAI,MAAM,CACjB,qBAAqB,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChE;KACF,CACF,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;AAClE,CAAC;AAED,GAAG,EAAE,CAAC"}
@@ -1,2 +1,2 @@
1
- export {};
1
+ import "dotenv/config";
2
2
  //# sourceMappingURL=pdfToMarkdown.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pdfToMarkdown.test.d.ts","sourceRoot":"","sources":["../../test/pdfToMarkdown.test.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"pdfToMarkdown.test.d.ts","sourceRoot":"","sources":["../../test/pdfToMarkdown.test.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC"}
@@ -1,31 +1,15 @@
1
+ import "dotenv/config";
1
2
  import { convertPdfPageToImage } from "../src/pdfConverter.js";
3
+ import { buildOpenAICompatibleRequest } from "../src/openaiCompatibleRequest.js";
2
4
  import * as fs from "node:fs/promises";
3
5
  import * as path from "node:path";
4
6
  /**
5
7
  * Convert image to markdown using Qwen VL API
6
8
  */
7
- async function convertImageToMarkdown(imageBuffer, apiUrl, apiKey) {
8
- const base64Image = imageBuffer.toString("base64");
9
- const requestBody = {
10
- model: "Qwen3-VL-235B-A22B-Instruct",
11
- messages: [
12
- {
13
- role: "user",
14
- content: [
15
- {
16
- type: "image_url",
17
- image_url: {
18
- url: `data:image/png;base64,${base64Image}`,
19
- },
20
- },
21
- {
22
- type: "text",
23
- text: "Please convert this image to markdown format. Extract all text, tables, and structure accurately.",
24
- },
25
- ],
26
- },
27
- ],
28
- };
9
+ async function convertImageToMarkdown(imageBuffer, apiUrl, apiKey, modelName, vllmReasoningParser) {
10
+ const requestBody = buildOpenAICompatibleRequest(imageBuffer, modelName, {
11
+ vllmReasoningParser,
12
+ });
29
13
  const response = await fetch(apiUrl, {
30
14
  method: "POST",
31
15
  headers: {
@@ -56,6 +40,8 @@ async function testPdfToMarkdown() {
56
40
  const testPdfPath = path.join(process.cwd(), "test", "test.pdf");
57
41
  const apiUrl = process.env.QWEN_API_URL;
58
42
  const apiKey = process.env.QWEN_API_KEY;
43
+ const modelName = process.env.QWEN_MODEL || "Qwen3-VL-235B-A22B-Instruct";
44
+ const vllmReasoningParser = process.env.VLLM_REASONING_PARSER;
59
45
  // Test 1: PDF to Image conversion
60
46
  console.log("Test 1: Convert PDF page to image");
61
47
  let imageBuffer;
@@ -87,22 +73,16 @@ async function testPdfToMarkdown() {
87
73
  // Test 2: Check API credentials
88
74
  console.log("\nTest 2: Verify API credentials");
89
75
  if (!apiUrl || !apiKey) {
90
- console.log("⚠ Test 2 skipped: QWEN_API_URL and QWEN_API_KEY environment variables not set");
91
- console.log("\nTo test full PDF to markdown conversion, set environment variables:");
92
- console.log(" Windows (PowerShell):");
93
- console.log(' $env:QWEN_API_URL = "http://osl4420:13000/v1/chat/completions"');
94
- console.log(' $env:QWEN_API_KEY = "sk-*****"');
95
- console.log("\n Linux/Mac:");
96
- console.log(' export QWEN_API_URL="https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"');
97
- console.log(' export QWEN_API_KEY="your-api-key-here"');
76
+ console.log("⚠ Test 2 skipped: QWEN_API_URL and QWEN_API_KEY were not found in process.env or the project .env file");
77
+ console.log("\nAdd the credentials to the project .env file or export them in your shell, then rerun npm run test:full.");
98
78
  return;
99
79
  }
100
80
  console.log("✓ Test 2 passed: API credentials found");
101
81
  // Test 3: Full conversion - Image to Markdown
102
82
  console.log("\nTest 3: Convert image to markdown using Qwen VL API");
103
83
  try {
104
- console.log(" Sending request to Qwen VL API...");
105
- const markdown = await convertImageToMarkdown(imageBuffer, apiUrl, apiKey);
84
+ console.log(" Sending request to the OpenAI-compatible vision API...");
85
+ const markdown = await convertImageToMarkdown(imageBuffer, apiUrl, apiKey, modelName, vllmReasoningParser);
106
86
  if (!markdown || typeof markdown !== "string") {
107
87
  throw new Error("Expected markdown string but got: " + typeof markdown);
108
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pdfToMarkdown.test.js","sourceRoot":"","sources":["../../test/pdfToMarkdown.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pdfToMarkdown.test.js","sourceRoot":"","sources":["../../test/pdfToMarkdown.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-to-markdown-mcp",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "MCP server that converts PDF pages to markdown using Qwen VL model",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -12,7 +12,7 @@
12
12
  "build": "tsc",
13
13
  "start": "node dist/src/index.js",
14
14
  "dev": "tsc --watch",
15
- "test": "tsc && node dist/test/convertPdfPageToImage.test.js",
15
+ "test": "tsc && node dist/test/convertPdfPageToImage.test.js && node dist/test/openaiCompatibleRequest.test.js",
16
16
  "test:full": "tsc && node dist/test/pdfToMarkdown.test.js",
17
17
  "test:all": "npm test && npm run test:full",
18
18
  "demo": "tsc && node dist/test/demo.js"
@@ -28,11 +28,17 @@
28
28
  "dependencies": {
29
29
  "@modelcontextprotocol/sdk": "^1.27.1",
30
30
  "canvas": "3.2.0",
31
- "pdfjs-dist": "4.8.69"
31
+ "dotenv": "^16.6.1",
32
+ "pdfjs-dist": "4.8.69",
33
+ "zod": "^3.25.76"
32
34
  },
33
35
  "overrides": {
34
- "hono":"4.12.5",
35
- "ajv":"8.18.0"
36
+ "hono":"4.12.18",
37
+ "ajv":"8.18.0",
38
+ "fast-uri":"3.1.2",
39
+ "ip-address":"10.2.0",
40
+ "@hono/node-server":"1.19.14",
41
+ "path-to-regexp":"8.4.2"
36
42
  },
37
43
  "devDependencies": {
38
44
  "@types/node": "^22.10.2",
package/src/index.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import "dotenv/config";
3
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
6
  import * as fs from "node:fs/promises";
6
7
  import * as path from "node:path";
7
8
  import { z } from "zod";
9
+ import { buildOpenAICompatibleRequest } from "./openaiCompatibleRequest.js";
8
10
  import { convertPdfPageToImage } from "./pdfConverter.js";
9
11
 
10
12
  interface QwenVLResponse {
@@ -26,30 +28,12 @@ async function convertImageToMarkdown(
26
28
  imageBuffer: Buffer,
27
29
  apiUrl: string,
28
30
  apiKey: string,
29
- modelName: string
31
+ modelName: string,
32
+ vllmReasoningParser?: string
30
33
  ): Promise<string> {
31
- const base64Image = imageBuffer.toString("base64");
32
-
33
- const requestBody = {
34
- model: modelName,
35
- messages: [
36
- {
37
- role: "user",
38
- content: [
39
- {
40
- type: "image_url",
41
- image_url: {
42
- url: `data:image/png;base64,${base64Image}`,
43
- },
44
- },
45
- {
46
- type: "text",
47
- text: "Please convert this image to markdown format. Extract all text, tables, and structure accurately.",
48
- },
49
- ],
50
- },
51
- ],
52
- };
34
+ const requestBody = buildOpenAICompatibleRequest(imageBuffer, modelName, {
35
+ vllmReasoningParser,
36
+ });
53
37
 
54
38
  const response = await fetch(apiUrl, {
55
39
  method: "POST",
@@ -90,6 +74,7 @@ async function main() {
90
74
  const apiUrl = process.env.QWEN_API_URL;
91
75
  const apiKey = process.env.QWEN_API_KEY;
92
76
  const modelName = process.env.QWEN_MODEL || "Qwen3-VL-235B-A22B-Instruct";
77
+ const vllmReasoningParser = process.env.VLLM_REASONING_PARSER;
93
78
 
94
79
  if (!apiUrl || !apiKey) {
95
80
  throw new Error(
@@ -166,7 +151,8 @@ async function main() {
166
151
  imageBuffer,
167
152
  apiUrl,
168
153
  apiKey,
169
- modelName
154
+ modelName,
155
+ vllmReasoningParser
170
156
  );
171
157
 
172
158
  return {
@@ -0,0 +1,105 @@
1
+ export const supportedVllmReasoningParsers = ["kimi_k2", "qwen3"] as const;
2
+
3
+ export type VllmReasoningParser =
4
+ (typeof supportedVllmReasoningParsers)[number];
5
+
6
+ type VisionContentPart =
7
+ | {
8
+ type: "image_url";
9
+ image_url: {
10
+ url: string;
11
+ };
12
+ }
13
+ | {
14
+ type: "text";
15
+ text: string;
16
+ };
17
+
18
+ export interface OpenAICompatibleChatCompletionRequest {
19
+ model: string;
20
+ messages: Array<{
21
+ role: "user";
22
+ content: VisionContentPart[];
23
+ }>;
24
+ chat_template_kwargs?: Record<string, boolean>;
25
+ }
26
+
27
+ interface BuildOpenAICompatibleRequestOptions {
28
+ vllmReasoningParser?: string;
29
+ }
30
+
31
+ function parseVllmReasoningParser(
32
+ vllmReasoningParser?: string
33
+ ): VllmReasoningParser | undefined {
34
+ if (!vllmReasoningParser) {
35
+ return undefined;
36
+ }
37
+
38
+ const normalizedParser = vllmReasoningParser
39
+ .trim()
40
+ .toLowerCase()
41
+ .replace(/[\s-]+/g, "_");
42
+
43
+ if (normalizedParser === "kimi_k2" || normalizedParser === "qwen3") {
44
+ return normalizedParser;
45
+ }
46
+
47
+ throw new Error(
48
+ `Unsupported VLLM_REASONING_PARSER \"${vllmReasoningParser}\". Supported values: ${supportedVllmReasoningParsers.join(", ")}.`
49
+ );
50
+ }
51
+
52
+ function getThinkingDisabledChatTemplateKwargs(
53
+ vllmReasoningParser?: VllmReasoningParser
54
+ ): Record<string, boolean> | undefined {
55
+ if (!vllmReasoningParser) {
56
+ return undefined;
57
+ }
58
+
59
+ if (vllmReasoningParser === "kimi_k2") {
60
+ return { thinking: false };
61
+ }
62
+
63
+ return { enable_thinking: false };
64
+ }
65
+
66
+ export function buildOpenAICompatibleRequest(
67
+ imageBuffer: Buffer,
68
+ modelName: string,
69
+ options: BuildOpenAICompatibleRequestOptions = {}
70
+ ): OpenAICompatibleChatCompletionRequest {
71
+ const base64Image = imageBuffer.toString("base64");
72
+ const vllmReasoningParser = parseVllmReasoningParser(
73
+ options.vllmReasoningParser
74
+ );
75
+ const requestBody: OpenAICompatibleChatCompletionRequest = {
76
+ model: modelName,
77
+ messages: [
78
+ {
79
+ role: "user",
80
+ content: [
81
+ {
82
+ type: "image_url",
83
+ image_url: {
84
+ url: `data:image/png;base64,${base64Image}`,
85
+ },
86
+ },
87
+ {
88
+ type: "text",
89
+ text: "Please convert this image to markdown format. Extract all text, tables, and structure accurately.",
90
+ },
91
+ ],
92
+ },
93
+ ],
94
+ };
95
+
96
+ const chatTemplateKwargs = getThinkingDisabledChatTemplateKwargs(
97
+ vllmReasoningParser
98
+ );
99
+
100
+ if (chatTemplateKwargs) {
101
+ requestBody.chat_template_kwargs = chatTemplateKwargs;
102
+ }
103
+
104
+ return requestBody;
105
+ }
package/test/demo.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import "dotenv/config";
1
2
  import { convertPdfPageToImage } from "../src/pdfConverter.js";
2
3
  import * as fs from "node:fs/promises";
3
4
  import * as path from "node:path";
@@ -88,9 +89,9 @@ async function main() {
88
89
  console.error("\nPlease set environment variables:");
89
90
  console.error(" QWEN_API_URL - Qwen API endpoint URL");
90
91
  console.error(" QWEN_API_KEY - Your Qwen API key\n");
91
- console.error("Windows (PowerShell):");
92
- console.error(' $env:QWEN_API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"');
93
- console.error(' $env:QWEN_API_KEY = "your-api-key-here"\n');
92
+ console.error(
93
+ "The project automatically loads a local .env file when present, so you can store the values there instead of exporting them every time.\n"
94
+ );
94
95
  process.exit(1);
95
96
  }
96
97
 
@@ -0,0 +1,47 @@
1
+ import assert from "node:assert/strict";
2
+ import {
3
+ buildOpenAICompatibleRequest,
4
+ supportedVllmReasoningParsers,
5
+ } from "../src/openaiCompatibleRequest.js";
6
+
7
+ function run() {
8
+ const sampleImage = Buffer.from("sample-image");
9
+
10
+ const genericRequest = buildOpenAICompatibleRequest(
11
+ sampleImage,
12
+ "moonshotai/Kimi-K2.6-Vision-Instruct"
13
+ );
14
+ assert.equal(genericRequest.chat_template_kwargs, undefined);
15
+
16
+ const kimiRequest = buildOpenAICompatibleRequest(
17
+ sampleImage,
18
+ "moonshotai/Kimi-K2.6-Vision-Instruct",
19
+ { vllmReasoningParser: "kimi_k2" }
20
+ );
21
+ assert.deepEqual(kimiRequest.chat_template_kwargs, { thinking: false });
22
+
23
+ const qwenRequest = buildOpenAICompatibleRequest(
24
+ sampleImage,
25
+ "Qwen/Qwen3-VL-235B-A22B-Instruct",
26
+ { vllmReasoningParser: "qwen3" }
27
+ );
28
+ assert.deepEqual(qwenRequest.chat_template_kwargs, {
29
+ enable_thinking: false,
30
+ });
31
+
32
+ assert.throws(
33
+ () =>
34
+ buildOpenAICompatibleRequest(sampleImage, "moonshotai/Kimi-K2.6", {
35
+ vllmReasoningParser: "unknown-parser",
36
+ }),
37
+ {
38
+ message: new RegExp(
39
+ `Supported values: ${supportedVllmReasoningParsers.join(", ")}`
40
+ ),
41
+ }
42
+ );
43
+
44
+ console.log("✓ OpenAI-compatible request builder tests passed");
45
+ }
46
+
47
+ run();
@@ -1,4 +1,6 @@
1
+ import "dotenv/config";
1
2
  import { convertPdfPageToImage } from "../src/pdfConverter.js";
3
+ import { buildOpenAICompatibleRequest } from "../src/openaiCompatibleRequest.js";
2
4
  import * as fs from "node:fs/promises";
3
5
  import * as path from "node:path";
4
6
 
@@ -20,30 +22,13 @@ interface QwenVLResponse {
20
22
  async function convertImageToMarkdown(
21
23
  imageBuffer: Buffer,
22
24
  apiUrl: string,
23
- apiKey: string
25
+ apiKey: string,
26
+ modelName: string,
27
+ vllmReasoningParser?: string
24
28
  ): Promise<string> {
25
- const base64Image = imageBuffer.toString("base64");
26
-
27
- const requestBody = {
28
- model: "Qwen3-VL-235B-A22B-Instruct",
29
- messages: [
30
- {
31
- role: "user",
32
- content: [
33
- {
34
- type: "image_url",
35
- image_url: {
36
- url: `data:image/png;base64,${base64Image}`,
37
- },
38
- },
39
- {
40
- type: "text",
41
- text: "Please convert this image to markdown format. Extract all text, tables, and structure accurately.",
42
- },
43
- ],
44
- },
45
- ],
46
- };
29
+ const requestBody = buildOpenAICompatibleRequest(imageBuffer, modelName, {
30
+ vllmReasoningParser,
31
+ });
47
32
 
48
33
  const response = await fetch(apiUrl, {
49
34
  method: "POST",
@@ -86,6 +71,8 @@ async function testPdfToMarkdown() {
86
71
  const testPdfPath = path.join(process.cwd(), "test", "test.pdf");
87
72
  const apiUrl = process.env.QWEN_API_URL;
88
73
  const apiKey = process.env.QWEN_API_KEY;
74
+ const modelName = process.env.QWEN_MODEL || "Qwen3-VL-235B-A22B-Instruct";
75
+ const vllmReasoningParser = process.env.VLLM_REASONING_PARSER;
89
76
 
90
77
  // Test 1: PDF to Image conversion
91
78
  console.log("Test 1: Convert PDF page to image");
@@ -124,14 +111,12 @@ async function testPdfToMarkdown() {
124
111
  // Test 2: Check API credentials
125
112
  console.log("\nTest 2: Verify API credentials");
126
113
  if (!apiUrl || !apiKey) {
127
- console.log("⚠ Test 2 skipped: QWEN_API_URL and QWEN_API_KEY environment variables not set");
128
- console.log("\nTo test full PDF to markdown conversion, set environment variables:");
129
- console.log(" Windows (PowerShell):");
130
- console.log(' $env:QWEN_API_URL = "http://osl4420:13000/v1/chat/completions"');
131
- console.log(' $env:QWEN_API_KEY = "sk-*****"');
132
- console.log("\n Linux/Mac:");
133
- console.log(' export QWEN_API_URL="https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"');
134
- console.log(' export QWEN_API_KEY="your-api-key-here"');
114
+ console.log(
115
+ " Test 2 skipped: QWEN_API_URL and QWEN_API_KEY were not found in process.env or the project .env file"
116
+ );
117
+ console.log(
118
+ "\nAdd the credentials to the project .env file or export them in your shell, then rerun npm run test:full."
119
+ );
135
120
  return;
136
121
  }
137
122
 
@@ -140,8 +125,14 @@ async function testPdfToMarkdown() {
140
125
  // Test 3: Full conversion - Image to Markdown
141
126
  console.log("\nTest 3: Convert image to markdown using Qwen VL API");
142
127
  try {
143
- console.log(" Sending request to Qwen VL API...");
144
- const markdown = await convertImageToMarkdown(imageBuffer, apiUrl, apiKey);
128
+ console.log(" Sending request to the OpenAI-compatible vision API...");
129
+ const markdown = await convertImageToMarkdown(
130
+ imageBuffer,
131
+ apiUrl,
132
+ apiKey,
133
+ modelName,
134
+ vllmReasoningParser
135
+ );
145
136
 
146
137
  if (!markdown || typeof markdown !== "string") {
147
138
  throw new Error("Expected markdown string but got: " + typeof markdown);