Skip to main content
Glama
server.py7.49 kB
#!/usr/bin/env python3 """ Git Helper MCP Server Provides git repository information and statistics tools for Claude """ import subprocess import json from typing import Any from mcp.server import Server from mcp.types import Tool, TextContent import mcp.server.stdio def run_git_command(args: list[str], cwd: str = ".") -> dict[str, Any]: """Run a git command and return the result""" try: result = subprocess.run( ["git"] + args, cwd=cwd, capture_output=True, text=True, check=True ) return {"success": True, "output": result.stdout.strip(), "error": None} except subprocess.CalledProcessError as e: return {"success": False, "output": None, "error": e.stderr.strip()} except Exception as e: return {"success": False, "output": None, "error": str(e)} # Create the MCP server app = Server("git-helper") @app.list_tools() async def list_tools() -> list[Tool]: """List available git tools""" return [ Tool( name="get_status", description="Get the current git repository status (staged, unstaged, untracked files)", inputSchema={ "type": "object", "properties": { "repo_path": { "type": "string", "description": "Path to git repository (defaults to current directory)", "default": "." } } } ), Tool( name="list_branches", description="List all branches in the repository with current branch highlighted", inputSchema={ "type": "object", "properties": { "repo_path": { "type": "string", "description": "Path to git repository", "default": "." } } } ), Tool( name="get_commit_history", description="Get recent commit history with messages and authors", inputSchema={ "type": "object", "properties": { "repo_path": { "type": "string", "description": "Path to git repository", "default": "." }, "limit": { "type": "integer", "description": "Number of commits to show", "default": 10 } }, "required": [] } ), Tool( name="get_branch_info", description="Get detailed information about a branch (current or specified)", inputSchema={ "type": "object", "properties": { "repo_path": { "type": "string", "description": "Path to git repository", "default": "." }, "branch": { "type": "string", "description": "Branch name (defaults to current branch)" } } } ), Tool( name="get_diff", description="Get git diff (changes in working directory or staged changes)", inputSchema={ "type": "object", "properties": { "repo_path": { "type": "string", "description": "Path to git repository", "default": "." }, "staged": { "type": "boolean", "description": "Show staged changes instead of unstaged", "default": False } } } ) ] @app.call_tool() async def call_tool(name: str, arguments: Any) -> list[TextContent]: """Handle tool calls""" repo_path = arguments.get("repo_path", ".") if name == "get_status": result = run_git_command(["status", "--short"], repo_path) if result["success"]: output = result["output"] if result["output"] else "Working directory clean" return [TextContent(type="text", text=f"Git Status:\n{output}")] else: return [TextContent(type="text", text=f"Error: {result['error']}")] elif name == "list_branches": result = run_git_command(["branch", "-a"], repo_path) if result["success"]: return [TextContent(type="text", text=f"Branches:\n{result['output']}")] else: return [TextContent(type="text", text=f"Error: {result['error']}")] elif name == "get_commit_history": limit = arguments.get("limit", 10) result = run_git_command( ["log", f"-{limit}", "--pretty=format:%h - %s (%an, %ar)"], repo_path ) if result["success"]: return [TextContent(type="text", text=f"Recent Commits:\n{result['output']}")] else: return [TextContent(type="text", text=f"Error: {result['error']}")] elif name == "get_branch_info": branch = arguments.get("branch") if branch: # Get info about specific branch result = run_git_command(["log", branch, "-1", "--pretty=format:%h - %s (%an, %ar)"], repo_path) else: # Get current branch name and info branch_result = run_git_command(["branch", "--show-current"], repo_path) if not branch_result["success"]: return [TextContent(type="text", text=f"Error: {branch_result['error']}")] current_branch = branch_result["output"] result = run_git_command(["log", "-1", "--pretty=format:%h - %s (%an, %ar)"], repo_path) if result["success"]: return [TextContent(type="text", text=f"Current Branch: {current_branch}\nLast Commit: {result['output']}")] else: return [TextContent(type="text", text=f"Error: {result['error']}")] if result["success"]: return [TextContent(type="text", text=f"Branch Info:\n{result['output']}")] else: return [TextContent(type="text", text=f"Error: {result['error']}")] elif name == "get_diff": staged = arguments.get("staged", False) args = ["diff", "--cached"] if staged else ["diff"] result = run_git_command(args, repo_path) if result["success"]: output = result["output"] if result["output"] else "No changes" diff_type = "Staged" if staged else "Unstaged" return [TextContent(type="text", text=f"{diff_type} Changes:\n{output}")] else: return [TextContent(type="text", text=f"Error: {result['error']}")] else: return [TextContent(type="text", text=f"Unknown tool: {name}")] async def main(): """Run the MCP server""" async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await app.run( read_stream, write_stream, app.create_initialization_options() ) if __name__ == "__main__": import asyncio asyncio.run(main())

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/LetsCodeTheBrain/git-helper-mcp'

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