Skip to main content
Glama
marc-hanheide

PDF Redaction MCP Server

save_redacted_pdf

Apply redaction annotations to PDF documents and save the redacted version to a new file with '_redacted' appended to the original filename or a custom output path.

Instructions

Apply all redactions and save the redacted PDF.

This tool applies all pending redaction annotations to the PDF and saves it. By default, it saves to a new file with '_redacted' appended to the original filename.

Args: pdf_path: Path to the PDF file (must be already loaded) output_path: Optional custom output path. If not provided, saves as '<original_name>_redacted.pdf' ctx: MCP context for logging

Returns: Path to the saved redacted PDF

Raises: ToolError: If the PDF is not loaded or save fails

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pdf_pathYesPath to the loaded PDF file
output_pathNoOptional output path. If not provided, appends '_redacted' to the original filename

Implementation Reference

  • The handler function decorated with @mcp.tool that implements the save_redacted_pdf tool. It applies all pending redaction annotations to the loaded PDF document and saves it to a new file, either at a specified output_path or by appending '_redacted' to the original filename.
    @mcp.tool
    async def save_redacted_pdf(
        pdf_path: Annotated[str, Field(description="Path to the loaded PDF file")],
        output_path: Annotated[str | None, Field(
            description="Optional output path. If not provided, appends '_redacted' to the original filename"
        )] = None,
        ctx: Context = None
    ) -> str:
        """Apply all redactions and save the redacted PDF.
        
        This tool applies all pending redaction annotations to the PDF and saves it.
        By default, it saves to a new file with '_redacted' appended to the original
        filename.
        
        Args:
            pdf_path: Path to the PDF file (must be already loaded)
            output_path: Optional custom output path. If not provided, saves as
                        '<original_name>_redacted.pdf'
            ctx: MCP context for logging
            
        Returns:
            Path to the saved redacted PDF
            
        Raises:
            ToolError: If the PDF is not loaded or save fails
        """
        try:
            path = Path(pdf_path).resolve()
            path_str = str(path)
            
            await ctx.info(f"Saving redacted PDF: {path}")
            
            # Check if PDF is loaded
            if path_str not in _loaded_pdfs:
                raise ToolError(
                    f"PDF not loaded. Please load it first using load_pdf: {path}"
                )
            
            doc = _loaded_pdfs[path_str]
            
            # Determine output path
            if output_path:
                out_path = Path(output_path).resolve()
            else:
                # Append '_redacted' to the original filename
                out_path = path.parent / f"{path.stem}_redacted{path.suffix}"
            
            # Count total redactions before applying
            total_redactions = 0
            for page in doc:
                # Apply redactions on this page
                redact_count = page.apply_redactions()
                if redact_count:
                    total_redactions += 1  # Note: apply_redactions returns True if any were applied
            
            # Save the document
            doc.save(str(out_path))
            
            await ctx.info(f"Saved redacted PDF to: {out_path}")
            
            return (
                f"Successfully applied redactions and saved to: {out_path}\n"
                f"Redactions applied on {total_redactions} page(s)."
            )
            
        except ToolError:
            raise
        except Exception as e:
            await ctx.error(f"Failed to save redacted PDF: {str(e)}")
            raise ToolError(f"Failed to save redacted PDF: {str(e)}")

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/marc-hanheide/redact_mcp'

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