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
| Name | Required | Description | Default |
|---|---|---|---|
| file1 | Yes | ||
| file2 | Yes | ||
| encoding | No | utf-8 | |
| format | No | text |
Implementation Reference
- mcp_filesystem/server.py:567-614 (handler)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)}"
- mcp_filesystem/advanced.py:509-584 (helper)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}")
- mcp_filesystem/server.py:567-567 (registration)The @mcp.tool() decorator registers the compare_files function as an MCP tool.@mcp.tool()