pdf_embed_qr_code
Add QR codes or barcodes to PDF pages at precise positions to encode data like URLs, contact details, or product information directly into documents.
Instructions
Embed a QR code or barcode into a specific page of a PDF at given coordinates. Supports qrcode, code128, datamatrix, ean13, pdf417, and azteccode.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Absolute path to the source PDF file | |
| content | Yes | Data to encode in the QR code or barcode | |
| outputPath | Yes | Absolute path for the output PDF | |
| page | Yes | Target page number (1-indexed) | |
| x | Yes | X position in points from the left edge | |
| y | Yes | Y position in points from the bottom edge | |
| size | No | Size of the QR code/barcode in points. Defaults to 100. | |
| type | No | Barcode type. Defaults to qrcode. |
Implementation Reference
- src/tools/manipulate.ts:461-565 (handler)The tool `pdf_embed_qr_code` is defined and implemented in `src/tools/manipulate.ts`. It registers the tool with the MCP server, defines its input schema using `zod`, and handles the logic for generating a barcode (using `bwip-js`) and embedding it into a specified page of a PDF using `pdf-lib`.
// ── pdf_embed_qr_code ─────────────────────────────────────────────── server.registerTool( "pdf_embed_qr_code", { description: "Embed a QR code or barcode into a specific page of a PDF at given coordinates. Supports qrcode, code128, datamatrix, ean13, pdf417, and azteccode.", inputSchema: z .object({ filePath: z .string() .max(4096) .describe("Absolute path to the source PDF file"), content: z .string() .min(1) .max(4096) .describe("Data to encode in the QR code or barcode"), outputPath: z .string() .max(4096) .describe("Absolute path for the output PDF"), page: z .number() .int() .min(1) .describe("Target page number (1-indexed)"), x: z .number() .describe("X position in points from the left edge"), y: z .number() .describe("Y position in points from the bottom edge"), size: z .number() .min(10) .max(1000) .optional() .describe("Size of the QR code/barcode in points. Defaults to 100."), type: z .enum(["qrcode", "code128", "datamatrix", "ean13", "pdf417", "azteccode"]) .optional() .describe("Barcode type. Defaults to qrcode."), }) .strict(), annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, async ({ filePath, content, outputPath, page, x, y, size, type }) => { try { const resolvedPath = await validatePdfPath(filePath); await validateFileSize(resolvedPath); const resolvedOutput = await validateOutputPath(outputPath, filePath); const barcodeType = type ?? "qrcode"; const barcodeSize = size ?? 100; // Generate barcode as PNG buffer const pngBuffer = await bwipToBuffer({ bcid: barcodeType, text: content, scale: 3, includetext: false, }); const pdfDoc = await loadExistingPdf(resolvedPath); const totalPages = pdfDoc.getPageCount(); if (page > totalPages) { return toolError( `Page ${page} exceeds document length (${totalPages} pages).` ); } const image = await pdfDoc.embedPng(pngBuffer); const targetPage = pdfDoc.getPage(page - 1); targetPage.drawImage(image, { x, y, width: barcodeSize, height: barcodeSize, }); await savePdf(pdfDoc, resolvedOutput); const fileSize = await getFileSize(resolvedOutput); return toolSuccess({ outputPath: resolvedOutput, page, type: barcodeType, position: { x, y }, size: barcodeSize, fileSize, }); } catch (error) { return toolError( error instanceof Error ? error.message : String(error) ); } } );