Skip to main content
Glama
marc-hanheide

PDF Redaction MCP Server

list_applied_redactions

View all text redactions applied to PDF documents to prevent duplicate redactions and track processed content.

Instructions

List all redactions that have been applied to loaded PDF(s).

This tool shows which texts have been marked for redaction in each PDF, helping to avoid duplicate redactions and track what has already been processed.

Args: pdf_path: Optional path to a specific PDF. If not provided, lists all PDFs. ctx: MCP context for logging

Returns: List of applied redactions for the specified PDF(s)

Raises: ToolError: If a specific PDF path is provided but not loaded

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pdf_pathNoOptional path to a specific PDF file. If not provided, lists redactions for all loaded PDFs

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The handler function for the 'list_applied_redactions' tool. It retrieves and formats the list of texts that have been redacted from one or all loaded PDFs using the global _applied_redactions dictionary. Includes input schema via Annotated[Field]. Registered via @mcp.tool decorator.
    @mcp.tool
    async def list_applied_redactions(
        pdf_path: Annotated[str | None, Field(
            description="Optional path to a specific PDF file. If not provided, lists redactions for all loaded PDFs"
        )] = None,
        ctx: Context = None
    ) -> str:
        """List all redactions that have been applied to loaded PDF(s).
        
        This tool shows which texts have been marked for redaction in each PDF,
        helping to avoid duplicate redactions and track what has already been processed.
        
        Args:
            pdf_path: Optional path to a specific PDF. If not provided, lists all PDFs.
            ctx: MCP context for logging
            
        Returns:
            List of applied redactions for the specified PDF(s)
            
        Raises:
            ToolError: If a specific PDF path is provided but not loaded
        """
        try:
            if pdf_path:
                # List redactions for a specific PDF
                path = Path(pdf_path).resolve()
                path_str = str(path)
                
                if path_str not in _loaded_pdfs:
                    raise ToolError(f"PDF not loaded: {path}")
                
                redactions = _applied_redactions.get(path_str, [])
                
                if not redactions:
                    await ctx.info(f"No redactions applied to: {path}")
                    return f"No redactions have been applied to: {path}"
                
                redaction_list = "\n".join(f"  - '{text}'" for text in redactions)
                result = (
                    f"Applied redactions for: {path}\n"
                    f"Total: {len(redactions)} text(s) redacted\n\n"
                    f"{redaction_list}"
                )
                
                await ctx.info(f"Listed {len(redactions)} redaction(s) for {path}")
                return result
                
            else:
                # List redactions for all loaded PDFs
                if not _applied_redactions:
                    await ctx.info("No redactions applied to any PDF")
                    return "No redactions have been applied to any loaded PDFs."
                
                results = []
                total_count = 0
                
                for pdf_path_str, redactions in _applied_redactions.items():
                    if redactions:  # Only show PDFs with redactions
                        redaction_list = "\n".join(f"    - '{text}'" for text in redactions)
                        results.append(
                            f"  {pdf_path_str}:\n"
                            f"    Total: {len(redactions)} text(s)\n"
                            f"{redaction_list}"
                        )
                        total_count += len(redactions)
                
                if not results:
                    await ctx.info("No redactions applied to any PDF")
                    return "No redactions have been applied to any loaded PDFs."
                
                result = (
                    f"Applied redactions across all loaded PDFs:\n"
                    f"Total PDFs with redactions: {len(results)}\n"
                    f"Total texts redacted: {total_count}\n\n"
                    + "\n\n".join(results)
                )
                
                await ctx.info(f"Listed redactions for {len(results)} PDF(s), {total_count} total texts")
                return result
                
        except ToolError:
            raise
        except Exception as e:
            await ctx.error(f"Failed to list redactions: {str(e)}")
            raise ToolError(f"Failed to list redactions: {str(e)}")
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses behavioral traits: it lists applied redactions, helps avoid duplicates, tracks processed items, and raises ToolError for unloaded PDFs. However, it doesn't mention performance aspects like rate limits or detailed error handling beyond ToolError.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, followed by benefits, args, returns, and raises sections. Every sentence earns its place: no fluff, efficiently structured with clear sections for different aspects of the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (1 parameter, no nested objects), no annotations, but with an output schema (so return values are documented elsewhere), the description is complete. It covers purpose, usage, parameters, returns, and error conditions adequately for a listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds value by explaining the optional nature of pdf_path ('If not provided, lists all PDFs') and the context parameter ('MCP context for logging'), which clarifies usage beyond the schema's technical details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List' and resource 'redactions that have been applied to loaded PDF(s)', specifying it shows which texts have been marked for redaction. It distinguishes from siblings like list_loaded_pdfs (which lists PDFs, not redactions) and redact_area/redact_text (which apply redactions, not list them).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: 'helping to avoid duplicate redactions and track what has already been processed.' It implies when not to use (e.g., for applying redactions, use redact_area/redact_text instead) and provides context about loaded PDFs, though it doesn't name alternatives directly beyond the sibling context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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