@neat-pdf/mcp 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/index.d.ts +1 -3
  2. package/dist/index.js +189 -4
  3. package/dist/index.js.map +1 -1
  4. package/package.json +5 -3
  5. package/dist/client.d.ts +0 -3
  6. package/dist/client.d.ts.map +0 -1
  7. package/dist/client.js +0 -9
  8. package/dist/client.js.map +0 -1
  9. package/dist/constants.d.ts +0 -4
  10. package/dist/constants.d.ts.map +0 -1
  11. package/dist/constants.js +0 -12
  12. package/dist/constants.js.map +0 -1
  13. package/dist/index.d.ts.map +0 -1
  14. package/dist/tools/compress-pdf.d.ts +0 -3
  15. package/dist/tools/compress-pdf.d.ts.map +0 -1
  16. package/dist/tools/compress-pdf.js +0 -23
  17. package/dist/tools/compress-pdf.js.map +0 -1
  18. package/dist/tools/html-to-pdf.d.ts +0 -3
  19. package/dist/tools/html-to-pdf.d.ts.map +0 -1
  20. package/dist/tools/html-to-pdf.js +0 -18
  21. package/dist/tools/html-to-pdf.js.map +0 -1
  22. package/dist/tools/index.d.ts +0 -3
  23. package/dist/tools/index.d.ts.map +0 -1
  24. package/dist/tools/index.js +0 -13
  25. package/dist/tools/index.js.map +0 -1
  26. package/dist/tools/merge-pdf.d.ts +0 -3
  27. package/dist/tools/merge-pdf.d.ts.map +0 -1
  28. package/dist/tools/merge-pdf.js +0 -24
  29. package/dist/tools/merge-pdf.js.map +0 -1
  30. package/dist/tools/office-to-pdf.d.ts +0 -3
  31. package/dist/tools/office-to-pdf.d.ts.map +0 -1
  32. package/dist/tools/office-to-pdf.js +0 -40
  33. package/dist/tools/office-to-pdf.js.map +0 -1
  34. package/dist/tools/url-to-pdf.d.ts +0 -3
  35. package/dist/tools/url-to-pdf.d.ts.map +0 -1
  36. package/dist/tools/url-to-pdf.js +0 -18
  37. package/dist/tools/url-to-pdf.js.map +0 -1
  38. package/dist/utils/encoding.d.ts +0 -3
  39. package/dist/utils/encoding.d.ts.map +0 -1
  40. package/dist/utils/encoding.js +0 -8
  41. package/dist/utils/encoding.js.map +0 -1
  42. package/dist/utils/error-handler.d.ts +0 -7
  43. package/dist/utils/error-handler.d.ts.map +0 -1
  44. package/dist/utils/error-handler.js +0 -16
  45. package/dist/utils/error-handler.js.map +0 -1
  46. package/dist/utils/response.d.ts +0 -7
  47. package/dist/utils/response.d.ts.map +0 -1
  48. package/dist/utils/response.js +0 -10
  49. package/dist/utils/response.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,3 +1 @@
1
- #!/usr/bin/env node
2
- import "./client.js";
3
- //# sourceMappingURL=index.d.ts.map
1
+ export { };
package/dist/index.js CHANGED
@@ -1,13 +1,198 @@
1
1
  #!/usr/bin/env node
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import "./client.js";
5
- import { registerTools } from "./tools/index.js";
4
+ import { NeatPdf } from "@neat-pdf/sdk";
5
+ import { z } from "@hono/zod-openapi";
6
+ import { compressPdfOptionsSchema, htmlToPdfRequestSchema, officeToPdfOptionsSchema, urlToPdfRequestSchema } from "@neat-pdf/shared";
7
+
8
+ //#region src/constants.ts
9
+ const INVALID_API_KEYS = ["${NEAT_PDF_API_KEY}", "your-api-key"];
10
+ const SIGNUP_MESSAGE = `
11
+ API key required. Get 100 free PDF generations:
12
+
13
+ 1. Sign up at https://neat-pdf.com
14
+ 2. Create an API key in your dashboard
15
+ 3. Set NEAT_PDF_API_KEY in your environment
16
+
17
+ Example: NEAT_PDF_API_KEY=your-key npx @neat-pdf/mcp
18
+ `;
19
+ const UPGRADE_MESSAGE = "No credits remaining. Upgrade your plan at https://neat-pdf.com/pricing";
20
+
21
+ //#endregion
22
+ //#region src/client.ts
23
+ const apiKey = process.env.NEAT_PDF_API_KEY;
24
+ if (!apiKey || INVALID_API_KEYS.includes(apiKey)) {
25
+ console.error(SIGNUP_MESSAGE);
26
+ process.exit(1);
27
+ }
28
+ const client = new NeatPdf({ apiKey });
29
+
30
+ //#endregion
31
+ //#region src/utils/encoding.ts
32
+ async function blobToBase64(blob) {
33
+ const buffer = await blob.arrayBuffer();
34
+ return Buffer.from(buffer).toString("base64");
35
+ }
36
+ function base64ToBlob(base64, mimeType = "application/pdf") {
37
+ return new Blob([Buffer.from(base64, "base64")], { type: mimeType });
38
+ }
39
+
40
+ //#endregion
41
+ //#region src/utils/error-handler.ts
42
+ function textResponse(text) {
43
+ return { content: [{
44
+ type: "text",
45
+ text
46
+ }] };
47
+ }
48
+ function handleError(error) {
49
+ const err = error;
50
+ if (err.status === 402) return textResponse(UPGRADE_MESSAGE);
51
+ if (err.status === 401) return textResponse("Invalid API key. Check your NEAT_PDF_API_KEY.");
52
+ const details = JSON.stringify(error, Object.getOwnPropertyNames(error), 2);
53
+ return textResponse(`Error: ${err.message || "Unknown error"}\n\nDetails:\n${details}`);
54
+ }
55
+
56
+ //#endregion
57
+ //#region src/utils/response.ts
58
+ function formatPdfResponse(base64, action) {
59
+ const sizeKb = Math.round(base64.length * .75 / 1024);
60
+ return { content: [{
61
+ type: "text",
62
+ text: `PDF ${action} successfully (${sizeKb} KB)`
63
+ }, {
64
+ type: "text",
65
+ text: `data:application/pdf;base64,${base64}`
66
+ }] };
67
+ }
68
+
69
+ //#endregion
70
+ //#region src/tools/compress-pdf.ts
71
+ function registerCompressPdf(server$1) {
72
+ server$1.registerTool("neat_compress_pdf", {
73
+ description: "Compress an existing PDF file. Accepts base64-encoded PDF, returns compressed base64-encoded PDF.",
74
+ inputSchema: {
75
+ file: z.string().describe("Base64-encoded PDF file to compress"),
76
+ ...compressPdfOptionsSchema.shape
77
+ }
78
+ }, async ({ file,...options }) => {
79
+ const blob = base64ToBlob(file);
80
+ const result = await client.compressPdf({ body: {
81
+ file: blob,
82
+ ...options
83
+ } });
84
+ if (result.error) return handleError(result.error);
85
+ const base64 = await blobToBase64(result.data);
86
+ return formatPdfResponse(base64, "compressed");
87
+ });
88
+ }
89
+
90
+ //#endregion
91
+ //#region src/tools/html-to-pdf.ts
92
+ function registerHtmlToPdf(server$1) {
93
+ server$1.registerTool("neat_html_to_pdf", {
94
+ description: "Convert HTML string to PDF. Returns base64-encoded PDF.",
95
+ inputSchema: htmlToPdfRequestSchema.shape
96
+ }, async ({ html,...options }) => {
97
+ const result = await client.htmlToPdf({ body: {
98
+ html,
99
+ ...options
100
+ } });
101
+ if (result.error) return handleError(result.error);
102
+ const base64 = await blobToBase64(result.data);
103
+ return formatPdfResponse(base64, "generated");
104
+ });
105
+ }
106
+
107
+ //#endregion
108
+ //#region src/tools/merge-pdf.ts
109
+ function registerMergePdf(server$1) {
110
+ server$1.registerTool("neat_merge_pdf", {
111
+ description: "Merge multiple PDF files into one. Accepts array of base64-encoded PDFs, returns merged base64-encoded PDF.",
112
+ inputSchema: { files: z.array(z.string()).min(2).describe("Array of base64-encoded PDF files to merge (order determines output order)") }
113
+ }, async ({ files }) => {
114
+ const blobs = files.map((f) => base64ToBlob(f));
115
+ const result = await client.mergePdf({ body: { files: blobs } });
116
+ if (result.error) return handleError(result.error);
117
+ const base64 = await blobToBase64(result.data);
118
+ return formatPdfResponse(base64, "merged");
119
+ });
120
+ }
121
+
122
+ //#endregion
123
+ //#region src/tools/office-to-pdf.ts
124
+ const MIME_TYPES = {
125
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
126
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
127
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
128
+ doc: "application/msword",
129
+ xls: "application/vnd.ms-excel",
130
+ ppt: "application/vnd.ms-powerpoint",
131
+ odt: "application/vnd.oasis.opendocument.text",
132
+ ods: "application/vnd.oasis.opendocument.spreadsheet",
133
+ odp: "application/vnd.oasis.opendocument.presentation",
134
+ rtf: "application/rtf",
135
+ txt: "text/plain",
136
+ csv: "text/csv"
137
+ };
138
+ function registerOfficeToPdf(server$1) {
139
+ server$1.registerTool("neat_office_to_pdf", {
140
+ description: "Convert Office documents (DOCX, XLSX, PPTX, etc.) to PDF. Accepts base64-encoded file, returns base64-encoded PDF.",
141
+ inputSchema: {
142
+ file: z.string().describe("Base64-encoded Office file to convert"),
143
+ filename: z.string().describe("Original filename with extension (e.g., 'document.docx')"),
144
+ ...officeToPdfOptionsSchema.shape
145
+ }
146
+ }, async ({ file, filename, landscape }) => {
147
+ const ext = filename.split(".").pop()?.toLowerCase() ?? "";
148
+ const mimeType = MIME_TYPES[ext] ?? "application/octet-stream";
149
+ const blob = base64ToBlob(file, mimeType);
150
+ const result = await client.officeToPdf({ body: {
151
+ file: blob,
152
+ landscape
153
+ } });
154
+ if (result.error) return handleError(result.error);
155
+ const base64 = await blobToBase64(result.data);
156
+ return formatPdfResponse(base64, "generated");
157
+ });
158
+ }
159
+
160
+ //#endregion
161
+ //#region src/tools/url-to-pdf.ts
162
+ function registerUrlToPdf(server$1) {
163
+ server$1.registerTool("neat_url_to_pdf", {
164
+ description: "Convert a webpage URL to PDF. Returns base64-encoded PDF.",
165
+ inputSchema: urlToPdfRequestSchema.shape
166
+ }, async ({ url,...options }) => {
167
+ const result = await client.urlToPdf({ body: {
168
+ url,
169
+ ...options
170
+ } });
171
+ if (result.error) return handleError(result.error);
172
+ const base64 = await blobToBase64(result.data);
173
+ return formatPdfResponse(base64, "generated");
174
+ });
175
+ }
176
+
177
+ //#endregion
178
+ //#region src/tools/index.ts
179
+ function registerTools(server$1) {
180
+ registerHtmlToPdf(server$1);
181
+ registerUrlToPdf(server$1);
182
+ registerCompressPdf(server$1);
183
+ registerOfficeToPdf(server$1);
184
+ registerMergePdf(server$1);
185
+ }
186
+
187
+ //#endregion
188
+ //#region src/index.ts
6
189
  const server = new McpServer({
7
- name: "neat-pdf",
8
- version: "0.1.0",
190
+ name: "neat-pdf",
191
+ version: "0.1.0"
9
192
  });
10
193
  registerTools(server);
11
194
  const transport = new StdioServerTransport();
12
195
  await server.connect(transport);
196
+
197
+ //#endregion
13
198
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,aAAa,CAAC,MAAM,CAAC,CAAC;AAEtB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","names":["blob: Blob","base64: string","mimeType: string","text: string","error: unknown","base64: string","action: string","server: McpServer","server: McpServer","server: McpServer","MIME_TYPES: Record<string, string>","server: McpServer","server: McpServer","server: McpServer","server"],"sources":["../src/constants.ts","../src/client.ts","../src/utils/encoding.ts","../src/utils/error-handler.ts","../src/utils/response.ts","../src/tools/compress-pdf.ts","../src/tools/html-to-pdf.ts","../src/tools/merge-pdf.ts","../src/tools/office-to-pdf.ts","../src/tools/url-to-pdf.ts","../src/tools/index.ts","../src/index.ts"],"sourcesContent":["export const INVALID_API_KEYS = [\"${NEAT_PDF_API_KEY}\", \"your-api-key\"];\n\nexport const SIGNUP_MESSAGE = `\nAPI key required. Get 100 free PDF generations:\n\n 1. Sign up at https://neat-pdf.com\n 2. Create an API key in your dashboard\n 3. Set NEAT_PDF_API_KEY in your environment\n\nExample: NEAT_PDF_API_KEY=your-key npx @neat-pdf/mcp\n`;\n\nexport const UPGRADE_MESSAGE =\n \"No credits remaining. Upgrade your plan at https://neat-pdf.com/pricing\";\n","import { NeatPdf } from \"@neat-pdf/sdk\";\nimport { INVALID_API_KEYS, SIGNUP_MESSAGE } from \"./constants.js\";\n\nconst apiKey = process.env.NEAT_PDF_API_KEY;\n\nif (!apiKey || INVALID_API_KEYS.includes(apiKey)) {\n console.error(SIGNUP_MESSAGE);\n process.exit(1);\n}\n\nexport const client = new NeatPdf({ apiKey });\n","export async function blobToBase64(blob: Blob): Promise<string> {\n const buffer = await blob.arrayBuffer();\n return Buffer.from(buffer).toString(\"base64\");\n}\n\nexport function base64ToBlob(base64: string, mimeType: string = \"application/pdf\"): Blob {\n return new Blob([Buffer.from(base64, \"base64\")], { type: mimeType });\n}\n","import { UPGRADE_MESSAGE } from \"../constants.js\";\n\nfunction textResponse(text: string) {\n return { content: [{ type: \"text\" as const, text }] };\n}\n\nexport function handleError(error: unknown) {\n const err = error as { status?: number; message?: string };\n\n if (err.status === 402) {\n return textResponse(UPGRADE_MESSAGE);\n }\n\n if (err.status === 401) {\n return textResponse(\"Invalid API key. Check your NEAT_PDF_API_KEY.\");\n }\n\n const details = JSON.stringify(error, Object.getOwnPropertyNames(error), 2);\n return textResponse(`Error: ${err.message || \"Unknown error\"}\\n\\nDetails:\\n${details}`);\n}\n","export function formatPdfResponse(base64: string, action: string) {\n const sizeKb = Math.round((base64.length * 0.75) / 1024);\n return {\n content: [\n { type: \"text\" as const, text: `PDF ${action} successfully (${sizeKb} KB)` },\n { type: \"text\" as const, text: `data:application/pdf;base64,${base64}` },\n ],\n };\n}\n","import { z } from \"@hono/zod-openapi\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { compressPdfOptionsSchema } from \"@neat-pdf/shared\";\nimport { client } from \"../client.js\";\nimport { base64ToBlob, blobToBase64 } from \"../utils/encoding.js\";\nimport { handleError } from \"../utils/error-handler.js\";\nimport { formatPdfResponse } from \"../utils/response.js\";\n\nexport function registerCompressPdf(server: McpServer): void {\n server.registerTool(\n \"neat_compress_pdf\",\n {\n description:\n \"Compress an existing PDF file. Accepts base64-encoded PDF, returns compressed base64-encoded PDF.\",\n inputSchema: {\n file: z.string().describe(\"Base64-encoded PDF file to compress\"),\n ...compressPdfOptionsSchema.shape,\n },\n },\n async ({ file, ...options }) => {\n const blob = base64ToBlob(file);\n const result = await client.compressPdf({ body: { file: blob, ...options } });\n if (result.error) return handleError(result.error);\n\n const base64 = await blobToBase64(result.data!);\n return formatPdfResponse(base64, \"compressed\");\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { htmlToPdfRequestSchema } from \"@neat-pdf/shared\";\nimport { client } from \"../client.js\";\nimport { blobToBase64 } from \"../utils/encoding.js\";\nimport { handleError } from \"../utils/error-handler.js\";\nimport { formatPdfResponse } from \"../utils/response.js\";\n\nexport function registerHtmlToPdf(server: McpServer): void {\n server.registerTool(\n \"neat_html_to_pdf\",\n {\n description: \"Convert HTML string to PDF. Returns base64-encoded PDF.\",\n inputSchema: htmlToPdfRequestSchema.shape,\n },\n async ({ html, ...options }) => {\n const result = await client.htmlToPdf({ body: { html, ...options } });\n if (result.error) return handleError(result.error);\n\n const base64 = await blobToBase64(result.data!);\n return formatPdfResponse(base64, \"generated\");\n },\n );\n}\n","import { z } from \"@hono/zod-openapi\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { client } from \"../client.js\";\nimport { base64ToBlob, blobToBase64 } from \"../utils/encoding.js\";\nimport { handleError } from \"../utils/error-handler.js\";\nimport { formatPdfResponse } from \"../utils/response.js\";\n\nexport function registerMergePdf(server: McpServer): void {\n server.registerTool(\n \"neat_merge_pdf\",\n {\n description:\n \"Merge multiple PDF files into one. Accepts array of base64-encoded PDFs, returns merged base64-encoded PDF.\",\n inputSchema: {\n files: z\n .array(z.string())\n .min(2)\n .describe(\"Array of base64-encoded PDF files to merge (order determines output order)\"),\n },\n },\n async ({ files }) => {\n const blobs = files.map((f) => base64ToBlob(f));\n const result = await client.mergePdf({ body: { files: blobs } });\n if (result.error) return handleError(result.error);\n\n const base64 = await blobToBase64(result.data!);\n return formatPdfResponse(base64, \"merged\");\n },\n );\n}\n","import { z } from \"@hono/zod-openapi\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { officeToPdfOptionsSchema } from \"@neat-pdf/shared\";\nimport { client } from \"../client.js\";\nimport { base64ToBlob, blobToBase64 } from \"../utils/encoding.js\";\nimport { handleError } from \"../utils/error-handler.js\";\nimport { formatPdfResponse } from \"../utils/response.js\";\n\nconst MIME_TYPES: Record<string, string> = {\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n doc: \"application/msword\",\n xls: \"application/vnd.ms-excel\",\n ppt: \"application/vnd.ms-powerpoint\",\n odt: \"application/vnd.oasis.opendocument.text\",\n ods: \"application/vnd.oasis.opendocument.spreadsheet\",\n odp: \"application/vnd.oasis.opendocument.presentation\",\n rtf: \"application/rtf\",\n txt: \"text/plain\",\n csv: \"text/csv\",\n};\n\nexport function registerOfficeToPdf(server: McpServer): void {\n server.registerTool(\n \"neat_office_to_pdf\",\n {\n description:\n \"Convert Office documents (DOCX, XLSX, PPTX, etc.) to PDF. Accepts base64-encoded file, returns base64-encoded PDF.\",\n inputSchema: {\n file: z.string().describe(\"Base64-encoded Office file to convert\"),\n filename: z.string().describe(\"Original filename with extension (e.g., 'document.docx')\"),\n ...officeToPdfOptionsSchema.shape,\n },\n },\n async ({ file, filename, landscape }) => {\n const ext = filename.split(\".\").pop()?.toLowerCase() ?? \"\";\n const mimeType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n const blob = base64ToBlob(file, mimeType);\n\n const result = await client.officeToPdf({ body: { file: blob, landscape } });\n if (result.error) return handleError(result.error);\n\n const base64 = await blobToBase64(result.data!);\n return formatPdfResponse(base64, \"generated\");\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { urlToPdfRequestSchema } from \"@neat-pdf/shared\";\nimport { client } from \"../client.js\";\nimport { blobToBase64 } from \"../utils/encoding.js\";\nimport { handleError } from \"../utils/error-handler.js\";\nimport { formatPdfResponse } from \"../utils/response.js\";\n\nexport function registerUrlToPdf(server: McpServer): void {\n server.registerTool(\n \"neat_url_to_pdf\",\n {\n description: \"Convert a webpage URL to PDF. Returns base64-encoded PDF.\",\n inputSchema: urlToPdfRequestSchema.shape,\n },\n async ({ url, ...options }) => {\n const result = await client.urlToPdf({ body: { url, ...options } });\n if (result.error) return handleError(result.error);\n\n const base64 = await blobToBase64(result.data!);\n return formatPdfResponse(base64, \"generated\");\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerCompressPdf } from \"./compress-pdf.js\";\nimport { registerHtmlToPdf } from \"./html-to-pdf.js\";\nimport { registerMergePdf } from \"./merge-pdf.js\";\nimport { registerOfficeToPdf } from \"./office-to-pdf.js\";\nimport { registerUrlToPdf } from \"./url-to-pdf.js\";\n\nexport function registerTools(server: McpServer): void {\n registerHtmlToPdf(server);\n registerUrlToPdf(server);\n registerCompressPdf(server);\n registerOfficeToPdf(server);\n registerMergePdf(server);\n}\n","#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport \"./client.js\";\nimport { registerTools } from \"./tools/index.js\";\n\nconst server = new McpServer({\n name: \"neat-pdf\",\n version: \"0.1.0\",\n});\n\nregisterTools(server);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neat-pdf/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "MCP server for PDF generation with Neat PDF",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -47,10 +47,12 @@
47
47
  "clean": "rm -rf dist"
48
48
  },
49
49
  "dependencies": {
50
+ "@asteasolutions/zod-to-openapi": "^8.0.0",
50
51
  "@hono/zod-openapi": "^0.19.0",
51
52
  "@modelcontextprotocol/sdk": "^1.0.0",
52
- "@neat-pdf/sdk": "^0.1.6",
53
- "@neat-pdf/shared": "workspace:*"
53
+ "@neat-pdf/sdk": "^0.1.7",
54
+ "@neat-pdf/shared": "workspace:*",
55
+ "zod": "^4.0.0"
54
56
  },
55
57
  "devDependencies": {
56
58
  "@types/node": "^22.10.5",
package/dist/client.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { NeatPdf } from "@neat-pdf/sdk";
2
- export declare const client: NeatPdf;
3
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAUxC,eAAO,MAAM,MAAM,SAA0B,CAAC"}
package/dist/client.js DELETED
@@ -1,9 +0,0 @@
1
- import { NeatPdf } from "@neat-pdf/sdk";
2
- import { INVALID_API_KEYS, SIGNUP_MESSAGE } from "./constants.js";
3
- const apiKey = process.env.NEAT_PDF_API_KEY;
4
- if (!apiKey || INVALID_API_KEYS.includes(apiKey)) {
5
- console.error(SIGNUP_MESSAGE);
6
- process.exit(1);
7
- }
8
- export const client = new NeatPdf({ apiKey });
9
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;AAE5C,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IACjD,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC"}
@@ -1,4 +0,0 @@
1
- export declare const INVALID_API_KEYS: string[];
2
- export declare const SIGNUP_MESSAGE = "\nAPI key required. Get 100 free PDF generations:\n\n 1. Sign up at https://neat-pdf.com\n 2. Create an API key in your dashboard\n 3. Set NEAT_PDF_API_KEY in your environment\n\nExample: NEAT_PDF_API_KEY=your-key npx @neat-pdf/mcp\n";
3
- export declare const UPGRADE_MESSAGE = "No credits remaining. Upgrade your plan at https://neat-pdf.com/pricing";
4
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,UAA0C,CAAC;AAExE,eAAO,MAAM,cAAc,iPAQ1B,CAAC;AAEF,eAAO,MAAM,eAAe,4EAC+C,CAAC"}
package/dist/constants.js DELETED
@@ -1,12 +0,0 @@
1
- export const INVALID_API_KEYS = ["${NEAT_PDF_API_KEY}", "your-api-key"];
2
- export const SIGNUP_MESSAGE = `
3
- API key required. Get 100 free PDF generations:
4
-
5
- 1. Sign up at https://neat-pdf.com
6
- 2. Create an API key in your dashboard
7
- 3. Set NEAT_PDF_API_KEY in your environment
8
-
9
- Example: NEAT_PDF_API_KEY=your-key npx @neat-pdf/mcp
10
- `;
11
- export const UPGRADE_MESSAGE = "No credits remaining. Upgrade your plan at https://neat-pdf.com/pricing";
12
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;CAQ7B,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAC1B,yEAAyE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,aAAa,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerCompressPdf(server: McpServer): void;
3
- //# sourceMappingURL=compress-pdf.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compress-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/compress-pdf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoB3D"}
@@ -1,23 +0,0 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { compressPdfOptionsSchema } from "@neat-pdf/shared";
3
- import { client } from "../client.js";
4
- import { base64ToBlob, blobToBase64 } from "../utils/encoding.js";
5
- import { handleError } from "../utils/error-handler.js";
6
- import { formatPdfResponse } from "../utils/response.js";
7
- export function registerCompressPdf(server) {
8
- server.registerTool("neat_compress_pdf", {
9
- description: "Compress an existing PDF file. Accepts base64-encoded PDF, returns compressed base64-encoded PDF.",
10
- inputSchema: {
11
- file: z.string().describe("Base64-encoded PDF file to compress"),
12
- ...compressPdfOptionsSchema.shape,
13
- },
14
- }, async ({ file, ...options }) => {
15
- const blob = base64ToBlob(file);
16
- const result = await client.compressPdf({ body: { file: blob, ...options } });
17
- if (result.error)
18
- return handleError(result.error);
19
- const base64 = await blobToBase64(result.data);
20
- return formatPdfResponse(base64, "compressed");
21
- });
22
- }
23
- //# sourceMappingURL=compress-pdf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compress-pdf.js","sourceRoot":"","sources":["../../src/tools/compress-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,WAAW,EACT,mGAAmG;QACrG,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;YAChE,GAAG,wBAAwB,CAAC,KAAK;SAClC;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;QAChD,OAAO,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjD,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerHtmlToPdf(server: McpServer): void;
3
- //# sourceMappingURL=html-to-pdf.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"html-to-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/html-to-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAezD"}
@@ -1,18 +0,0 @@
1
- import { htmlToPdfRequestSchema } from "@neat-pdf/shared";
2
- import { client } from "../client.js";
3
- import { blobToBase64 } from "../utils/encoding.js";
4
- import { handleError } from "../utils/error-handler.js";
5
- import { formatPdfResponse } from "../utils/response.js";
6
- export function registerHtmlToPdf(server) {
7
- server.registerTool("neat_html_to_pdf", {
8
- description: "Convert HTML string to PDF. Returns base64-encoded PDF.",
9
- inputSchema: htmlToPdfRequestSchema.shape,
10
- }, async ({ html, ...options }) => {
11
- const result = await client.htmlToPdf({ body: { html, ...options } });
12
- if (result.error)
13
- return handleError(result.error);
14
- const base64 = await blobToBase64(result.data);
15
- return formatPdfResponse(base64, "generated");
16
- });
17
- }
18
- //# sourceMappingURL=html-to-pdf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"html-to-pdf.js","sourceRoot":"","sources":["../../src/tools/html-to-pdf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,WAAW,EAAE,yDAAyD;QACtE,WAAW,EAAE,sBAAsB,CAAC,KAAK;KAC1C,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;QAChD,OAAO,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerTools(server: McpServer): void;
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAMrD"}
@@ -1,13 +0,0 @@
1
- import { registerCompressPdf } from "./compress-pdf.js";
2
- import { registerHtmlToPdf } from "./html-to-pdf.js";
3
- import { registerMergePdf } from "./merge-pdf.js";
4
- import { registerOfficeToPdf } from "./office-to-pdf.js";
5
- import { registerUrlToPdf } from "./url-to-pdf.js";
6
- export function registerTools(server) {
7
- registerHtmlToPdf(server);
8
- registerUrlToPdf(server);
9
- registerCompressPdf(server);
10
- registerOfficeToPdf(server);
11
- registerMergePdf(server);
12
- }
13
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,aAAa,CAAC,MAAiB;IAC7C,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerMergePdf(server: McpServer): void;
3
- //# sourceMappingURL=merge-pdf.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"merge-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/merge-pdf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBxD"}
@@ -1,24 +0,0 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { client } from "../client.js";
3
- import { base64ToBlob, blobToBase64 } from "../utils/encoding.js";
4
- import { handleError } from "../utils/error-handler.js";
5
- import { formatPdfResponse } from "../utils/response.js";
6
- export function registerMergePdf(server) {
7
- server.registerTool("neat_merge_pdf", {
8
- description: "Merge multiple PDF files into one. Accepts array of base64-encoded PDFs, returns merged base64-encoded PDF.",
9
- inputSchema: {
10
- files: z
11
- .array(z.string())
12
- .min(2)
13
- .describe("Array of base64-encoded PDF files to merge (order determines output order)"),
14
- },
15
- }, async ({ files }) => {
16
- const blobs = files.map((f) => base64ToBlob(f));
17
- const result = await client.mergePdf({ body: { files: blobs } });
18
- if (result.error)
19
- return handleError(result.error);
20
- const base64 = await blobToBase64(result.data);
21
- return formatPdfResponse(base64, "merged");
22
- });
23
- }
24
- //# sourceMappingURL=merge-pdf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"merge-pdf.js","sourceRoot":"","sources":["../../src/tools/merge-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,6GAA6G;QAC/G,WAAW,EAAE;YACX,KAAK,EAAE,CAAC;iBACL,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,4EAA4E,CAAC;SAC1F;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;QAChD,OAAO,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerOfficeToPdf(server: McpServer): void;
3
- //# sourceMappingURL=office-to-pdf.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"office-to-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/office-to-pdf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsBzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwB3D"}
@@ -1,40 +0,0 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { officeToPdfOptionsSchema } from "@neat-pdf/shared";
3
- import { client } from "../client.js";
4
- import { base64ToBlob, blobToBase64 } from "../utils/encoding.js";
5
- import { handleError } from "../utils/error-handler.js";
6
- import { formatPdfResponse } from "../utils/response.js";
7
- const MIME_TYPES = {
8
- docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
9
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
10
- pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
11
- doc: "application/msword",
12
- xls: "application/vnd.ms-excel",
13
- ppt: "application/vnd.ms-powerpoint",
14
- odt: "application/vnd.oasis.opendocument.text",
15
- ods: "application/vnd.oasis.opendocument.spreadsheet",
16
- odp: "application/vnd.oasis.opendocument.presentation",
17
- rtf: "application/rtf",
18
- txt: "text/plain",
19
- csv: "text/csv",
20
- };
21
- export function registerOfficeToPdf(server) {
22
- server.registerTool("neat_office_to_pdf", {
23
- description: "Convert Office documents (DOCX, XLSX, PPTX, etc.) to PDF. Accepts base64-encoded file, returns base64-encoded PDF.",
24
- inputSchema: {
25
- file: z.string().describe("Base64-encoded Office file to convert"),
26
- filename: z.string().describe("Original filename with extension (e.g., 'document.docx')"),
27
- ...officeToPdfOptionsSchema.shape,
28
- },
29
- }, async ({ file, filename, landscape }) => {
30
- const ext = filename.split(".").pop()?.toLowerCase() ?? "";
31
- const mimeType = MIME_TYPES[ext] ?? "application/octet-stream";
32
- const blob = base64ToBlob(file, mimeType);
33
- const result = await client.officeToPdf({ body: { file: blob, landscape } });
34
- if (result.error)
35
- return handleError(result.error);
36
- const base64 = await blobToBase64(result.data);
37
- return formatPdfResponse(base64, "generated");
38
- });
39
- }
40
- //# sourceMappingURL=office-to-pdf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"office-to-pdf.js","sourceRoot":"","sources":["../../src/tools/office-to-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,GAA2B;IACzC,IAAI,EAAE,yEAAyE;IAC/E,IAAI,EAAE,mEAAmE;IACzE,IAAI,EAAE,2EAA2E;IACjF,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,0BAA0B;IAC/B,GAAG,EAAE,+BAA+B;IACpC,GAAG,EAAE,yCAAyC;IAC9C,GAAG,EAAE,gDAAgD;IACrD,GAAG,EAAE,iDAAiD;IACtD,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,UAAU;CAChB,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EACT,oHAAoH;QACtH,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YAClE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC;YACzF,GAAG,wBAAwB,CAAC,KAAK;SAClC;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;QACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;QAC/D,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC7E,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;QAChD,OAAO,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerUrlToPdf(server: McpServer): void;
3
- //# sourceMappingURL=url-to-pdf.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"url-to-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/url-to-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAexD"}
@@ -1,18 +0,0 @@
1
- import { urlToPdfRequestSchema } from "@neat-pdf/shared";
2
- import { client } from "../client.js";
3
- import { blobToBase64 } from "../utils/encoding.js";
4
- import { handleError } from "../utils/error-handler.js";
5
- import { formatPdfResponse } from "../utils/response.js";
6
- export function registerUrlToPdf(server) {
7
- server.registerTool("neat_url_to_pdf", {
8
- description: "Convert a webpage URL to PDF. Returns base64-encoded PDF.",
9
- inputSchema: urlToPdfRequestSchema.shape,
10
- }, async ({ url, ...options }) => {
11
- const result = await client.urlToPdf({ body: { url, ...options } });
12
- if (result.error)
13
- return handleError(result.error);
14
- const base64 = await blobToBase64(result.data);
15
- return formatPdfResponse(base64, "generated");
16
- });
17
- }
18
- //# sourceMappingURL=url-to-pdf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"url-to-pdf.js","sourceRoot":"","sources":["../../src/tools/url-to-pdf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EAAE,2DAA2D;QACxE,WAAW,EAAE,qBAAqB,CAAC,KAAK;KACzC,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;QAChD,OAAO,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,3 +0,0 @@
1
- export declare function blobToBase64(blob: Blob): Promise<string>;
2
- export declare function base64ToBlob(base64: string, mimeType?: string): Blob;
3
- //# sourceMappingURL=encoding.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAAA,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA0B,GAAG,IAAI,CAEvF"}
@@ -1,8 +0,0 @@
1
- export async function blobToBase64(blob) {
2
- const buffer = await blob.arrayBuffer();
3
- return Buffer.from(buffer).toString("base64");
4
- }
5
- export function base64ToBlob(base64, mimeType = "application/pdf") {
6
- return new Blob([Buffer.from(base64, "base64")], { type: mimeType });
7
- }
8
- //# sourceMappingURL=encoding.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAU;IAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,WAAmB,iBAAiB;IAC/E,OAAO,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AACvE,CAAC"}
@@ -1,7 +0,0 @@
1
- export declare function handleError(error: unknown): {
2
- content: {
3
- type: "text";
4
- text: string;
5
- }[];
6
- };
7
- //# sourceMappingURL=error-handler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAMA,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO;;;;;EAazC"}
@@ -1,16 +0,0 @@
1
- import { UPGRADE_MESSAGE } from "../constants.js";
2
- function textResponse(text) {
3
- return { content: [{ type: "text", text }] };
4
- }
5
- export function handleError(error) {
6
- const err = error;
7
- if (err.status === 402) {
8
- return textResponse(UPGRADE_MESSAGE);
9
- }
10
- if (err.status === 401) {
11
- return textResponse("Invalid API key. Check your NEAT_PDF_API_KEY.");
12
- }
13
- const details = JSON.stringify(error, Object.getOwnPropertyNames(error), 2);
14
- return textResponse(`Error: ${err.message || "Unknown error"}\n\nDetails:\n${details}`);
15
- }
16
- //# sourceMappingURL=error-handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,GAAG,GAAG,KAA8C,CAAC;IAE3D,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC,+CAA+C,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5E,OAAO,YAAY,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,eAAe,iBAAiB,OAAO,EAAE,CAAC,CAAC;AAC1F,CAAC"}
@@ -1,7 +0,0 @@
1
- export declare function formatPdfResponse(base64: string, action: string): {
2
- content: {
3
- type: "text";
4
- text: string;
5
- }[];
6
- };
7
- //# sourceMappingURL=response.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;EAQ/D"}
@@ -1,10 +0,0 @@
1
- export function formatPdfResponse(base64, action) {
2
- const sizeKb = Math.round((base64.length * 0.75) / 1024);
3
- return {
4
- content: [
5
- { type: "text", text: `PDF ${action} successfully (${sizeKb} KB)` },
6
- { type: "text", text: `data:application/pdf;base64,${base64}` },
7
- ],
8
- };
9
- }
10
- //# sourceMappingURL=response.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAAc;IAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACzD,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,MAAM,kBAAkB,MAAM,MAAM,EAAE;YAC5E,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,+BAA+B,MAAM,EAAE,EAAE;SACzE;KACF,CAAC;AACJ,CAAC"}