Skip to main content
Glama
safurrier

MCP Filesystem Server

compare_files

Compare two text files to identify differences between them. Specify file paths, encoding, and output format to analyze changes in content.

Instructions

Compare two text files and show differences.

Args:
    file1: First file path
    file2: Second file path
    encoding: Text encoding (default: utf-8)
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Comparison results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file1Yes
file2Yes
encodingNoutf-8
formatNotext

Implementation Reference

  • MCP tool registration and handler for 'compare_files'. Decorated with @mcp.tool(), handles input parameters, delegates core comparison to advanced component, and formats output as text or JSON.
    @mcp.tool()
    async def compare_files(
        file1: str,
        file2: str,
        ctx: Context,
        encoding: str = "utf-8",
        format: str = "text",
    ) -> str:
        """Compare two text files and show differences.
    
        Args:
            file1: First file path
            file2: Second file path
            encoding: Text encoding (default: utf-8)
            format: Output format ('text' or 'json')
            ctx: MCP context
    
        Returns:
            Comparison results
        """
        try:
            components = get_components()
            result = await components["advanced"].compare_files(file1, file2, encoding)
    
            if format.lower() == "json":
                return json.dumps(result, indent=2)
    
            # Format as text
            similarity_pct = f"{result['similarity'] * 100:.1f}%"
    
            if result["are_identical"]:
                return "Files are identical (100% similarity)"
    
            lines = [
                f"Comparing {file1} with {file2}",
                f"Similarity: {similarity_pct}",
                f"Lines added: {result['added_lines']}",
                f"Lines removed: {result['removed_lines']}",
                "",
                "Diff:",
                result["diff"],
            ]
    
            return "\n".join(lines)
    
        except Exception as e:
            return f"Error comparing files: {str(e)}"
  • Core helper function implementing the file comparison logic using difflib.unified_diff for differences, line counts, similarity ratio, and identity check. Validates paths and handles errors.
    async def compare_files(
        self, file1: Union[str, Path], file2: Union[str, Path], encoding: str = "utf-8"
    ) -> Dict:
        """Compare two text files and show differences.
    
        Args:
            file1: First file path
            file2: Second file path
            encoding: Text encoding (default: utf-8)
    
        Returns:
            Dictionary with comparison results
    
        Raises:
            ValueError: If paths are outside allowed directories
        """
        import difflib
    
        path1, allowed1 = await self.validator.validate_path(file1)
        if not allowed1:
            raise ValueError(f"Path outside allowed directories: {file1}")
    
        path2, allowed2 = await self.validator.validate_path(file2)
        if not allowed2:
            raise ValueError(f"Path outside allowed directories: {file2}")
    
        try:
            content1 = await anyio.to_thread.run_sync(path1.read_text, encoding)
            content2 = await anyio.to_thread.run_sync(path2.read_text, encoding)
    
            # Get file names for display
            name1 = path1.name
            name2 = path2.name
    
            # Split into lines
            lines1 = content1.splitlines()
            lines2 = content2.splitlines()
    
            # Calculate differences
            diff = list(
                difflib.unified_diff(
                    lines1, lines2, fromfile=name1, tofile=name2, lineterm=""
                )
            )
    
            # Count added, removed, and changed lines
            added = sum(
                1
                for line in diff
                if line.startswith("+") and not line.startswith("+++")
            )
            removed = sum(
                1
                for line in diff
                if line.startswith("-") and not line.startswith("---")
            )
    
            # Calculate similarity ratio
            matcher = difflib.SequenceMatcher(None, content1, content2)
            similarity = matcher.ratio()
    
            return {
                "diff": "\n".join(diff),
                "added_lines": added,
                "removed_lines": removed,
                "similarity": similarity,
                "are_identical": content1 == content2,
            }
    
        except FileNotFoundError as e:
            raise FileNotFoundError(f"File not found: {e}")
        except PermissionError as e:
            raise ValueError(f"Permission denied: {e}")
        except UnicodeDecodeError as e:
            raise ValueError(f"Cannot decode file as {encoding}: {e}")
  • The @mcp.tool() decorator registers the compare_files function as an MCP tool.
    @mcp.tool()
Behavior2/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 mentions the tool 'shows differences' but doesn't disclose important behavioral traits: what type of comparison is performed (line-by-line, character-level?), whether it's read-only or modifies files, what happens with binary files, error handling, or performance characteristics. The description is minimal beyond the basic operation.

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?

The description is perfectly structured and concise. It starts with the core purpose, then lists parameters with clear explanations, and ends with the return statement. Every sentence earns its place with no wasted words. The bullet-like format for parameters is efficient and scannable.

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

Completeness3/5

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

Given 4 parameters with no schema descriptions and no output schema, the description does a reasonable job explaining parameters but leaves gaps. It doesn't describe the comparison algorithm, error conditions, or what the output looks like (beyond mentioning 'text' or 'json' format). For a comparison tool with behavioral complexity, more context about the comparison method and output structure would be helpful.

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?

With 0% schema description coverage, the description must compensate, and it does so effectively. It clearly explains all 4 parameters: 'file1' and 'file2' as file paths, 'encoding' with its default, and 'format' with valid values. This adds significant meaning beyond the bare schema. The only minor gap is not explaining what 'text' vs 'json' format outputs look like.

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

Purpose4/5

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

The description clearly states the tool's purpose: 'Compare two text files and show differences.' This is a specific verb ('compare') with clear resources ('two text files') and outcome ('show differences'). However, it doesn't explicitly differentiate from sibling tools like 'find_duplicate_files' or 'search_files', which might involve file comparison in different contexts.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. With many sibling tools for file operations (e.g., 'find_duplicate_files', 'grep_files', 'search_files'), there's no indication of when this specific comparison tool is appropriate versus other file analysis tools. No exclusions or prerequisites are mentioned.

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/safurrier/mcp-filesystem'

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