@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.
- package/dist/index.d.ts +1 -3
- package/dist/index.js +189 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/dist/client.d.ts +0 -3
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -9
- package/dist/client.js.map +0 -1
- package/dist/constants.d.ts +0 -4
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -12
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/tools/compress-pdf.d.ts +0 -3
- package/dist/tools/compress-pdf.d.ts.map +0 -1
- package/dist/tools/compress-pdf.js +0 -23
- package/dist/tools/compress-pdf.js.map +0 -1
- package/dist/tools/html-to-pdf.d.ts +0 -3
- package/dist/tools/html-to-pdf.d.ts.map +0 -1
- package/dist/tools/html-to-pdf.js +0 -18
- package/dist/tools/html-to-pdf.js.map +0 -1
- package/dist/tools/index.d.ts +0 -3
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -13
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/merge-pdf.d.ts +0 -3
- package/dist/tools/merge-pdf.d.ts.map +0 -1
- package/dist/tools/merge-pdf.js +0 -24
- package/dist/tools/merge-pdf.js.map +0 -1
- package/dist/tools/office-to-pdf.d.ts +0 -3
- package/dist/tools/office-to-pdf.d.ts.map +0 -1
- package/dist/tools/office-to-pdf.js +0 -40
- package/dist/tools/office-to-pdf.js.map +0 -1
- package/dist/tools/url-to-pdf.d.ts +0 -3
- package/dist/tools/url-to-pdf.d.ts.map +0 -1
- package/dist/tools/url-to-pdf.js +0 -18
- package/dist/tools/url-to-pdf.js.map +0 -1
- package/dist/utils/encoding.d.ts +0 -3
- package/dist/utils/encoding.d.ts.map +0 -1
- package/dist/utils/encoding.js +0 -8
- package/dist/utils/encoding.js.map +0 -1
- package/dist/utils/error-handler.d.ts +0 -7
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/error-handler.js +0 -16
- package/dist/utils/error-handler.js.map +0 -1
- package/dist/utils/response.d.ts +0 -7
- package/dist/utils/response.d.ts.map +0 -1
- package/dist/utils/response.js +0 -10
- package/dist/utils/response.js.map +0 -1
package/dist/index.d.ts
CHANGED
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 "
|
|
5
|
-
import {
|
|
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
|
-
|
|
8
|
-
|
|
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.
|
|
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.
|
|
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
package/dist/client.d.ts.map
DELETED
|
@@ -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
|
package/dist/client.js.map
DELETED
|
@@ -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"}
|
package/dist/constants.d.ts
DELETED
|
@@ -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
|
package/dist/constants.d.ts.map
DELETED
|
@@ -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
|
package/dist/constants.js.map
DELETED
|
@@ -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"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,aAAa,CAAC"}
|
|
@@ -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 +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"}
|
package/dist/tools/index.d.ts
DELETED
|
@@ -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"}
|
package/dist/tools/index.js
DELETED
|
@@ -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
|
package/dist/tools/index.js.map
DELETED
|
@@ -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 +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"}
|
package/dist/tools/merge-pdf.js
DELETED
|
@@ -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 +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 +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"}
|
package/dist/tools/url-to-pdf.js
DELETED
|
@@ -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"}
|
package/dist/utils/encoding.d.ts
DELETED
|
@@ -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"}
|
package/dist/utils/encoding.js
DELETED
|
@@ -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 +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"}
|
package/dist/utils/response.d.ts
DELETED
|
@@ -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"}
|
package/dist/utils/response.js
DELETED
|
@@ -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"}
|