Skip to main content
Glama

create-simple-pdf

Generate basic PDF documents with text content using this simplified tool. Supports emoji rendering and document title metadata for straightforward PDF creation.

Instructions

Create a simple PDF with just text content. A simplified version of create-pdf for basic use cases. Supports emoji rendering.

Input Schema

NameRequiredDescriptionDefault
filenameNoOptional filename for the PDF (defaults to "document.pdf"). SECURITY: Filenames are sanitized and written to a sandboxed directory: • Default: ~/.mcp-pdf/ • Override: Set PDF_OUTPUT_DIR environment variable • Path traversal attempts (.., /, etc) are blocked • Only alphanumeric, spaces, hyphens, underscores, and dots allowed • If file exists, timestamp is appended automatically
textYesText content for the PDF
titleNoDocument title metadata

Input Schema (JSON Schema)

{ "properties": { "filename": { "description": "Optional filename for the PDF (defaults to \"document.pdf\").\n\nSECURITY: Filenames are sanitized and written to a sandboxed directory:\n• Default: ~/.mcp-pdf/\n• Override: Set PDF_OUTPUT_DIR environment variable\n• Path traversal attempts (.., /, etc) are blocked\n• Only alphanumeric, spaces, hyphens, underscores, and dots allowed\n• If file exists, timestamp is appended automatically", "type": "string" }, "text": { "description": "Text content for the PDF", "type": "string" }, "title": { "description": "Document title metadata", "type": "string" } }, "required": [ "text" ], "type": "object" }

Implementation Reference

  • The async handler function that executes the tool: creates PDFDocument, handles emoji rendering, generates PDF buffer, saves to file with UUID, returns success message with resource info or error.
    async (args: CreateSimplePdfArgs) => { const { filename = 'document.pdf', text, title } = args; try { const doc = new PDFDocument({ info: { ...(title && { Title: title }), ...(filename && { Subject: filename }), }, }); const chunks: Buffer[] = []; doc.on('data', (c: Buffer) => chunks.push(c)); const pdfPromise = new Promise<Buffer>((resolve, reject) => { doc.on('end', () => resolve(Buffer.concat(chunks))); doc.on('error', reject); }); const containsEmoji = hasEmoji(text); const emojiAvailable = containsEmoji ? registerEmojiFont() : false; const fonts = await setupFonts(doc); const { regular: regularFont } = fonts; renderTextWithEmoji(doc, text, 12, regularFont, emojiAvailable); doc.end(); const pdfBuffer = await pdfPromise; const uuid = crypto.randomUUID(); const storedFilename = `${uuid}.pdf`; const { fullPath } = await writePdfToFile(pdfBuffer, storedFilename, config.storageDir); const includePath = config.includePath; return { content: [ { type: 'text' as const, text: ['PDF created successfully', `Resource: mcp-pdf://${uuid}`, includePath ? `Output: ${fullPath}` : undefined, `Size: ${pdfBuffer.length} bytes`, filename !== 'document.pdf' ? `Filename: ${filename}` : undefined].filter(Boolean).join('\n'), }, ], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: 'text' as const, text: `Error creating PDF: ${message}` }], isError: true }; } }
  • Zod-based input schema defining parameters: filename (optional), text (required), title (optional).
    inputSchema: { filename: z.string().optional().describe('Optional logical filename (metadata only). Storage uses UUID. Defaults to "document.pdf".'), text: z.string().describe('Text content for the PDF'), title: z.string().optional().describe('Document title metadata'), } as Record<string, z.ZodTypeAny>,
  • src/server.ts:27-27 (registration)
    Top-level registration call that invokes the tool's register function to add 'create-simple-pdf' tool to the MCP server.
    registerCreateSimplePdfTool(server, serverConfig);
  • The registration function exported by the tool module, which calls server.registerTool with name, spec (title, desc, schema), and handler.
    export function registerCreateSimplePdfTool(server: McpServer, config: PdfServerConfig) { server.registerTool( 'create-simple-pdf', { title: 'Create Simple PDF', description: 'Create a simple PDF with just text content. Supports emoji rendering.', inputSchema: { filename: z.string().optional().describe('Optional logical filename (metadata only). Storage uses UUID. Defaults to "document.pdf".'), text: z.string().describe('Text content for the PDF'), title: z.string().optional().describe('Document title metadata'), } as Record<string, z.ZodTypeAny>, }, async (args: CreateSimplePdfArgs) => { const { filename = 'document.pdf', text, title } = args; try { const doc = new PDFDocument({ info: { ...(title && { Title: title }), ...(filename && { Subject: filename }), }, }); const chunks: Buffer[] = []; doc.on('data', (c: Buffer) => chunks.push(c)); const pdfPromise = new Promise<Buffer>((resolve, reject) => { doc.on('end', () => resolve(Buffer.concat(chunks))); doc.on('error', reject); }); const containsEmoji = hasEmoji(text); const emojiAvailable = containsEmoji ? registerEmojiFont() : false; const fonts = await setupFonts(doc); const { regular: regularFont } = fonts; renderTextWithEmoji(doc, text, 12, regularFont, emojiAvailable); doc.end(); const pdfBuffer = await pdfPromise; const uuid = crypto.randomUUID(); const storedFilename = `${uuid}.pdf`; const { fullPath } = await writePdfToFile(pdfBuffer, storedFilename, config.storageDir); const includePath = config.includePath; return { content: [ { type: 'text' as const, text: ['PDF created successfully', `Resource: mcp-pdf://${uuid}`, includePath ? `Output: ${fullPath}` : undefined, `Size: ${pdfBuffer.length} bytes`, filename !== 'document.pdf' ? `Filename: ${filename}` : undefined].filter(Boolean).join('\n'), }, ], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: 'text' as const, text: `Error creating PDF: ${message}` }], isError: true }; } } ); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcp-z/mcp-pdf'

If you have feedback or need assistance with the MCP directory API, please join our Discord server