get_page_meta
Analyze files to determine page count and physical sheet requirements before printing. Pre-renders documents when necessary to provide accurate printing metadata.
Instructions
Get page count and physical sheet information for a file before printing. Pre-renders the file (if needed) and returns page metadata including page count and physical sheets required.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| files | Yes | Array of files to get metadata for (use single-element array for one file) |
Implementation Reference
- src/tools/print.ts:122-161 (registration)Registration of the 'get_page_meta' tool with MCP server, including input schema and batch handler that delegates to handlePageMetaserver.registerTool( "get_page_meta", { title: "Get Page Metadata", description: "Get page count and physical sheet information for a file before printing. Pre-renders the file (if needed) and returns page metadata including page count and physical sheets required.", inputSchema: { files: z .array( z.object({ file_path: z.string().describe("Full path to the file to get page metadata for"), options: z .string() .optional() .describe( "Additional CUPS options for duplex detection (e.g., 'sides=two-sided-long-edge')" ), ...renderingParametersSchema, }) ) .describe("Array of files to get metadata for (use single-element array for one file)"), }, }, async ({ files }) => { // Check for large batch size const batchSizeWarning = checkBatchSizeLimit(files.length, "files") if (batchSizeWarning) { return batchSizeWarning } // Process each file in the batch const results: PageMetaResult[] = [] for (const fileSpec of files) { const result = await handlePageMeta(fileSpec) results.push(result) } return formatPageMetaResults(results) } )
- src/tools/batch-helpers.ts:285-335 (handler)Core handler function that implements the get_page_meta tool logic: prepares/renders file, extracts PDF page count, calculates physical sheets considering duplex, handles errors and cleanup.export async function handlePageMeta(spec: FilePageMetaSpec): Promise<PageMetaResult> { const { file_path, options, line_numbers, color_scheme, font_size, line_spacing, force_markdown_render, force_code_render, } = spec try { // Use shared rendering function const { actualFilePath, renderedPdf, renderType } = await prepareFileForPrinting({ filePath: file_path, lineNumbers: line_numbers, colorScheme: color_scheme, fontSize: font_size, lineSpacing: line_spacing, forceMarkdownRender: force_markdown_render, forceCodeRender: force_code_render, }) try { // Get page count from the file const pdfPages = await getPdfPageCount(actualFilePath) const isDuplex = isDuplexEnabled(options) const physicalSheets = calculatePhysicalSheets(pdfPages, isDuplex) return { success: true, file_path, pages: pdfPages, sheets: physicalSheets, duplex: isDuplex, renderType, } } finally { // Clean up rendered PDF if it was created cleanupRenderedPdf(renderedPdf) } } catch (error) { const message = error instanceof Error ? error.message : String(error) return { success: false, file_path, error: `Failed to get page metadata: ${message}`, } } }
- src/tools/print.ts:21-52 (schema)Shared Zod schema for rendering parameters used in inputSchema for both print_file and get_page_meta tools.const renderingParametersSchema = { line_numbers: z .boolean() .optional() .describe("Show line numbers when rendering code files (overrides global setting)"), color_scheme: z .string() .optional() .describe( "Syntax highlighting color scheme for code files (e.g., 'github', 'monokai', 'atom-one-light')" ), font_size: z .string() .optional() .describe("Font size for code files (e.g., '8pt', '10pt', '12pt')"), line_spacing: z .string() .optional() .describe("Line spacing for code files (e.g., '1', '1.5', '2')"), force_markdown_render: z .boolean() .optional() .describe( "Force markdown rendering to PDF (true=always render, false=never render, undefined=use config)" ), force_code_render: z .boolean() .optional() .describe( "Force code rendering to PDF with syntax highlighting (true=always render, false=never render, undefined=use config)" ), }
- src/tools/batch-helpers.ts:350-380 (helper)Formats the batch results from handlePageMeta into a readable MCP text response.export function formatPageMetaResults(results: PageMetaResult[]): { content: Array<{ type: "text"; text: string }> } { const successful = results.filter((r) => r.success) const failed = results.filter((r) => !r.success) let text = `Page Metadata Results: ${successful.length}/${results.length} successful` if (failed.length > 0) { text += `, ${failed.length} failed` } text += "\n\n" // Show successful metadata for (const result of successful) { text += `✓ ${result.file_path}\n ${result.pages} pages (${result.sheets} sheets${formatDuplexInfo(result.duplex)})${formatRenderInfo(result.renderType)}\n\n` } // Show failed metadata for (const result of failed) { text += `✗ ${result.file_path}\n ${result.error}\n\n` } return { content: [ { type: "text", text: text.trim(), }, ], } }
- src/utils.ts:543-598 (helper)Core utility function that prepares files for printing by rendering markdown/code to PDF if needed. Used by both print_file and get_page_meta tools.export async function prepareFileForPrinting(options: RenderOptions): Promise<RenderResult> { // Validate file path security validateFilePath(options.filePath) let actualFilePath = options.filePath let renderedPdf: string | null = null let renderType = "" // Check if file should be auto-rendered to PDF (markdown) const shouldRenderMarkdown = options.forceMarkdownRender !== undefined ? options.forceMarkdownRender && MARKDOWN_EXTENSIONS.some((ext) => options.filePath.toLowerCase().endsWith(`.${ext}`)) : shouldRenderToPdf(options.filePath) if (shouldRenderMarkdown) { try { renderedPdf = await renderMarkdownToPdf(options.filePath) actualFilePath = renderedPdf renderType = "markdown → PDF" } catch (error) { // If fallback is enabled, use original file; otherwise throw error if (config.fallbackOnRenderError) { console.error(`Warning: Failed to render ${options.filePath}, using as-is:`, error) } else { throw error } } } // Check if file should be rendered as code with syntax highlighting else if ( options.forceCodeRender !== undefined ? options.forceCodeRender : await shouldRenderCode(options.filePath) ) { try { renderedPdf = await renderCodeToPdf(options.filePath, { lineNumbers: options.lineNumbers, colorScheme: options.colorScheme, fontSize: options.fontSize, lineSpacing: options.lineSpacing, }) actualFilePath = renderedPdf renderType = "code → PDF (syntax highlighted)" } catch (error) { // If fallback is enabled, use original file; otherwise throw error if (config.fallbackOnRenderError) { console.error(`Warning: Failed to render code ${options.filePath}, using as-is:`, error) } else { throw error } } } return { actualFilePath, renderedPdf, renderType } }