redact_area
Mark specific rectangular areas on PDF pages for redaction by defining coordinates, allowing precise content removal before final document saving.
Instructions
Redact a specific rectangular area on a PDF page.
This tool adds a redaction annotation for a specific rectangular area defined by coordinates. The redactions are not yet applied to the document - use save_redacted_pdf to apply and save.
Args: pdf_path: Path to the PDF file (must be already loaded) page_number: Page number to redact (1-indexed) x0: Left x coordinate of the rectangle y0: Top y coordinate of the rectangle x1: Right x coordinate of the rectangle y1: Bottom y coordinate of the rectangle fill_color: RGB color tuple (0-1 range) for the redaction box. Default is black. ctx: MCP context for logging
Returns: Confirmation message
Raises: ToolError: If the PDF is not loaded, page doesn't exist, or redaction fails
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fill_color | No | RGB color for redaction (values 0-1). Default is black (0,0,0) | |
| page_number | Yes | Page number (1-indexed) | |
| pdf_path | Yes | Path to the loaded PDF file | |
| x0 | Yes | Left x coordinate | |
| x1 | Yes | Right x coordinate | |
| y0 | Yes | Top y coordinate | |
| y1 | Yes | Bottom y coordinate |
Implementation Reference
- src/redact_mcp/server.py:207-285 (handler)The handler function for the 'redact_area' tool. It adds a redaction annotation to a rectangular area on a specific page of a loaded PDF using PyMuPDF. Includes input schema via Annotated Fields, logic for validation, rect creation, and annotation addition.@mcp.tool async def redact_area( pdf_path: Annotated[str, Field(description="Path to the loaded PDF file")], page_number: Annotated[int, Field(description="Page number (1-indexed)", ge=1)], x0: Annotated[float, Field(description="Left x coordinate")], y0: Annotated[float, Field(description="Top y coordinate")], x1: Annotated[float, Field(description="Right x coordinate")], y1: Annotated[float, Field(description="Bottom y coordinate")], fill_color: Annotated[tuple[float, float, float], Field( description="RGB color for redaction (values 0-1). Default is black (0,0,0)" )] = (0, 0, 0), ctx: Context = None ) -> str: """Redact a specific rectangular area on a PDF page. This tool adds a redaction annotation for a specific rectangular area defined by coordinates. The redactions are not yet applied to the document - use save_redacted_pdf to apply and save. Args: pdf_path: Path to the PDF file (must be already loaded) page_number: Page number to redact (1-indexed) x0: Left x coordinate of the rectangle y0: Top y coordinate of the rectangle x1: Right x coordinate of the rectangle y1: Bottom y coordinate of the rectangle fill_color: RGB color tuple (0-1 range) for the redaction box. Default is black. ctx: MCP context for logging Returns: Confirmation message Raises: ToolError: If the PDF is not loaded, page doesn't exist, or redaction fails """ try: path = Path(pdf_path).resolve() path_str = str(path) await ctx.info(f"Redacting area on page {page_number} in: {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] # Validate page number if page_number < 1 or page_number > len(doc): raise ToolError( f"Invalid page number {page_number}. PDF has {len(doc)} pages." ) # Validate color values if not all(0 <= c <= 1 for c in fill_color): raise ToolError("RGB color values must be between 0 and 1") # Get the page (0-indexed internally) page = doc[page_number - 1] # Create rectangle and add redaction rect = fitz.Rect(x0, y0, x1, y1) page.add_redact_annot(rect, fill=fill_color) await ctx.info(f"Added area redaction on page {page_number}") return ( f"Added redaction for area ({x0}, {y0}, {x1}, {y1}) on page {page_number}.\n" + "Note: Redaction is marked but not yet applied. " + "Use save_redacted_pdf to apply and save the changes." ) except ToolError: raise except Exception as e: await ctx.error(f"Failed to redact area: {str(e)}") raise ToolError(f"Failed to redact area: {str(e)}")