Skip to main content
Glama
split-pdf.ts3.79 kB
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import fs from 'fs-extra'; import path from 'path'; import { PDFDocument } from 'pdf-lib'; export default function registerSplitPdfTool(server: McpServer) { server.registerTool( 'split-pdf', { title: 'Split PDF File', description: 'Splits a PDF file into separate pages or page ranges.', inputSchema: { input_file: z.string().describe('Input PDF file path'), output_dir: z.string().describe('Output directory for split PDF files'), split_mode: z.enum(['pages', 'ranges']).optional().default('pages').describe('Split mode: pages or ranges'), page_ranges: z.array(z.string()).optional().describe('Page ranges (e.g., ["1-3", "5", "7-9"]) - required for ranges mode'), }, }, async (params: { input_file: string; output_dir: string; split_mode?: 'pages' | 'ranges'; page_ranges?: string[] }) => { try { const { input_file, output_dir, split_mode = 'pages', page_ranges } = params; // Validate input file exists if (!(await fs.pathExists(input_file))) { return { content: [{ type: 'text', text: `Error: Input file does not exist: ${input_file}` }], isError: true, }; } // Ensure output directory exists await fs.ensureDir(output_dir); // Load the input PDF const fileBuffer = await fs.readFile(input_file); const pdf = await PDFDocument.load(fileBuffer); const totalPages = pdf.getPageCount(); let splitPages: number[][] = []; if (split_mode === 'pages') { // Split each page into separate files for (let i = 0; i < totalPages; i++) { splitPages.push([i]); } } else if (split_mode === 'ranges' && page_ranges) { // Parse page ranges for (const range of page_ranges) { const pages: number[] = []; if (range.includes('-')) { const [start, end] = range.split('-').map(Number); for (let i = start - 1; i < Math.min(end, totalPages); i++) { pages.push(i); } } else { const pageNum = parseInt(range) - 1; if (pageNum >= 0 && pageNum < totalPages) { pages.push(pageNum); } } if (pages.length > 0) { splitPages.push(pages); } } } else { return { content: [{ type: 'text', text: 'Error: page_ranges is required for ranges mode' }], isError: true, }; } const createdFiles: string[] = []; // Create split PDF files for (let i = 0; i < splitPages.length; i++) { const pages = splitPages[i]; if (pages.length === 0) continue; const newPdf = await PDFDocument.create(); // Copy the specified pages const copiedPages = await newPdf.copyPages(pdf, pages); copiedPages.forEach((page) => newPdf.addPage(page)); const outputPath = path.join(output_dir, `split_${i + 1}.pdf`); const pdfBytes = await newPdf.save(); await fs.writeFile(outputPath, pdfBytes); createdFiles.push(outputPath); } return { content: [ { type: 'text', text: `Successfully split PDF into ${createdFiles.length} files:\n${createdFiles.join('\n')}`, }, ], }; } catch (error: any) { return { content: [{ type: 'text', text: `Error splitting PDF: ${error.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/Yussefgafer/MyMCP'

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