gurupdf-mcp 0.1.0 → 0.1.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/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # GuruPDF MCP — convert PDFs & 100+ file formats from your AI agent
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/gurupdf-mcp.svg)](https://www.npmjs.com/package/gurupdf-mcp)
4
- [![npm downloads](https://img.shields.io/npm/dm/gurupdf-mcp.svg)](https://www.npmjs.com/package/gurupdf-mcp)
5
- [![license: MIT](https://img.shields.io/npm/l/gurupdf-mcp.svg)](./LICENSE)
4
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/GuruPDF/gurupdf-mcp/blob/main/LICENSE)
6
5
 
7
6
  A free **[Model Context Protocol](https://modelcontextprotocol.io) (MCP) server** that lets Claude, Cursor, VS Code, Windsurf and other AI agents **convert, compress, merge, split and edit PDFs — and convert between 100+ file formats** (Word, Excel, PowerPoint, JPG, PNG, HEIC, ebooks, and more), right on your own machine. Powered by [GuruPDF](https://gurupdf.com).
8
7
 
package/dist/client.js CHANGED
@@ -45,8 +45,17 @@ export class GuruPdfClient {
45
45
  }
46
46
  if (!res.ok) {
47
47
  const err = parsed?.error ?? {};
48
- throw new GuruPdfError(err.message ?? `Request failed (HTTP ${res.status})`, {
49
- code: err.code ?? `HTTP_${res.status}`,
48
+ // Laravel validation errors come back as { message, errors: { field: [msg,…] } }
49
+ // with no `error` wrapper — surface those instead of a bare "HTTP 422".
50
+ const validation = parsed?.errors && typeof parsed.errors === "object"
51
+ ? Object.values(parsed.errors).flat().filter(Boolean)
52
+ : [];
53
+ const message = (err.message ??
54
+ (validation.length ? validation.join(" ") : undefined) ??
55
+ parsed?.message ??
56
+ `Request failed (HTTP ${res.status})`).replace(/\bfiles\.\d+\b/g, "file");
57
+ throw new GuruPdfError(message, {
58
+ code: err.code ?? parsed?.code ?? `HTTP_${res.status}`,
50
59
  status: res.status,
51
60
  meta: parsed?.meta ?? err.meta,
52
61
  retryAfter,
@@ -99,7 +108,7 @@ export class GuruPdfClient {
99
108
  /* ignore */
100
109
  }
101
110
  const err = parsed?.error ?? {};
102
- throw new GuruPdfError(err.message ?? `Download failed (HTTP ${res.status})`, {
111
+ throw new GuruPdfError(err.message ?? parsed?.message ?? `Download failed (HTTP ${res.status})`, {
103
112
  code: err.code ?? `HTTP_${res.status}`,
104
113
  status: res.status,
105
114
  meta: parsed?.meta,
package/dist/index.js CHANGED
@@ -52,7 +52,7 @@ async function pollUntilDone(uuid, timeoutMs = 5 * 60 * 1000) {
52
52
  }
53
53
  return (await client.getConversion(uuid)).data;
54
54
  }
55
- const server = new McpServer({ name: "gurupdf", version: "0.1.0" });
55
+ const server = new McpServer({ name: "gurupdf", version: "0.1.2" });
56
56
  server.tool("convert_file", "Convert or process a local file (or URL) with GuruPDF. Convert between 100+ formats (PDF ⇄ Word/Excel/PowerPoint, images, ebooks, etc.) or run a PDF tool (compress, merge, split, rotate, protect, watermark, OCR…). Saves the result next to the input and returns the path.", {
57
57
  input: z
58
58
  .union([z.string(), z.array(z.string())])
@@ -74,7 +74,15 @@ server.tool("convert_file", "Convert or process a local file (or URL) with GuruP
74
74
  const urlMode = inputs.length === 1 && isUrl(inputs[0]);
75
75
  const inputExt = urlMode ? "" : extname(inputs[0]).toLowerCase();
76
76
  const tools = await catalog();
77
- const tool = resolveTool(tools, to, inputExt);
77
+ // URL inputs only work with URL tools (e.g. url-to-pdf). resolveTool keys off the
78
+ // input extension, which is empty for a URL, so route URL mode explicitly — otherwise
79
+ // it falls through to the shortest-slug file tool (merge-pdf, …) and the API 422s.
80
+ const tool = urlMode
81
+ ? tools.find((t) => t.slug === to) ??
82
+ tools.find((t) => (t.accepted_formats?.length ?? 0) === 0 &&
83
+ t.output_format?.toLowerCase() === "." + to.replace(/^\./, "").toLowerCase()) ??
84
+ tools.find((t) => (t.accepted_formats?.length ?? 0) === 0)
85
+ : resolveTool(tools, to, inputExt);
78
86
  if (!tool) {
79
87
  return text(`I couldn't find a GuruPDF tool to turn ${inputExt || "that input"} into "${to}". ` +
80
88
  `Run list_conversions${inputExt ? ` with from_format "${inputExt.slice(1)}"` : ""} to see the options.`);
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "gurupdf-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Model Context Protocol server for GuruPDF — convert, compress, merge and edit PDFs and 100+ file formats from any AI agent (Claude, Cursor, VS Code, Windsurf).",
5
5
  "license": "MIT",
6
+ "mcpName": "io.github.GuruPDF/gurupdf-mcp",
6
7
  "type": "module",
7
8
  "bin": {
8
9
  "gurupdf-mcp": "dist/index.js"