Skip to main content
Glama
theoklitosBam7

MCP Git Commit Generator

generate_commit_message

Generate conventional commit messages automatically from staged git changes. Analyzes git diffs and repository status to create properly formatted commits following conventional commit standards. Supports custom commit types and scopes.

Instructions

Prepare a structured analysis and instruction block for generating a Conventional Commit message from staged git changes only.

Behavior: - Validates the repository path and operates on the provided repo or CWD. - Collects staged diff, porcelain status, and a name-status summary. - Incorporates optional user preferences for commit_type and scope. - Returns a single formatted string that includes context plus strict output instructions for an LLM to produce a Conventional Commit.

Args: repo_path: Optional path to the target git repository. If not provided, uses the current working directory. commit_type: Optional commit type (feat, fix, docs, style, refactor, perf, build, ci, test, chore, revert) scope: Optional scope of the change

Returns: A formatted prompt containing git change context and clear output rules for generating a Conventional Commit message

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
repo_pathNo
commit_typeNo
scopeNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for the 'generate_commit_message' tool. It is decorated with @mcp.tool() and retrieves staged git diff, status, and file changes, then constructs a formatted prompt for generating a Conventional Commit message.
    def generate_commit_message(
        repo_path: Optional[str] = None,
        commit_type: Optional[str] = None,
        scope: Optional[str] = None,
    ) -> str:
        """
        Prepare a structured analysis and instruction block for generating a
        Conventional Commit message from staged git changes only.
    
        Behavior:
            - Validates the repository path and operates on the provided repo or CWD.
            - Collects staged diff, porcelain status, and a name-status summary.
            - Incorporates optional user preferences for commit_type and scope.
            - Returns a single formatted string that includes context plus strict
              output instructions for an LLM to produce a Conventional Commit.
    
        Args:
            repo_path: Optional path to the target git repository. If not provided, uses the current working directory.
            commit_type: Optional commit type (feat, fix, docs, style, refactor, perf, build, ci, test, chore, revert)
            scope: Optional scope of the change
    
        Returns:
            A formatted prompt containing git change context and clear output rules
            for generating a Conventional Commit message
        """
        try:
            valid_repo_path = _get_valid_repo_path(repo_path)
            if not valid_repo_path:
                return f"Path '{repo_path or os.getcwd()}' is not a valid git repository."
            cwd = valid_repo_path
            # Get staged changes
            diff_result = subprocess.run(
                ["git", "diff", "--cached"],
                capture_output=True,
                text=True,
                check=True,
                cwd=cwd,
            )
    
            if not diff_result.stdout.strip():
                return "No staged changes found. Please stage your changes with 'git add' first."
    
            # Get git status for context
            status_result = subprocess.run(
                ["git", "status", "--porcelain"],
                capture_output=True,
                text=True,
                check=True,
                cwd=cwd,
            )
    
            # Get list of changed files for better analysis
            files_result = subprocess.run(
                ["git", "diff", "--cached", "--name-status"],
                capture_output=True,
                text=True,
                check=True,
                cwd=cwd,
            )
    
            diff_preview = diff_result.stdout[:1500]
            analysis = textwrap.dedent(f"""
            ## Git Change Analysis for Conventional Commit Message
    
            ### Changed Files:
            {files_result.stdout}
    
            ### File Status Summary:
            {status_result.stdout}
    
            ### Diff Preview (first 1500 chars):
            {diff_preview}
    
            ### User Preferences:
                - Requested commit type: {commit_type or "auto-detect based on changes"}
                - Requested scope: {scope or "auto-detect based on files changed"}
    
            ### Task
            Write a Conventional Commit message for the STAGED changes only.
    
            ### Output format (return ONLY this)
            First line: type(scope): subject
            Add blank line before body
            Body paragraphs, each line <= 72 chars; bullets in body starting with "- "
            Optional footers (each on its own line), e.g.:
            BREAKING CHANGE: description
    
            ### Example generated commit message
            feat(core): add new feature
    
            - Implement new feature in core module
            - Update documentation
    
            BREAKING CHANGE: this change removes the old API method
    
            ### Rules
            - If commit_type or scope is provided above, USE THEM as-is.
            - If not provided, infer an appropriate type and a concise scope (or omit scope if unclear).
            - Subject: use imperative mood, start lowercase, no trailing period, <= 50 chars.
            - Body: use imperative mood (e.g. Update, Add etc.); explain WHAT and WHY, wrap at 72 chars; omit if subject suffices.
            - Use domain-specific terms; avoid generic phrases.
            - Do NOT mention "staged", "diff", or counts of files/lines.
            - Do NOT include markdown headers, code fences, or extra commentary.
            - Prefer a broad scope if many files; derive scope from top-level dirs when clear.
            - If there is a breaking change (e.g., API removal/rename), add a BREAKING CHANGE footer.
            - Keep the response to ONLY the commit message in the format above.
    
            ### Common types
            feat, fix, docs, style, refactor, perf, build, ci, test, chore, revert
            """)
    
            return analysis.strip()
    
        except subprocess.CalledProcessError as e:
            error_msg = e.stderr or e.stdout or str(e)
            return f"Git command failed: {error_msg}"
        except FileNotFoundError:
            return "Git is not installed or not found in PATH"
        except OSError as e:
            return f"OS error occurred: {str(e)}"
  • The tool is registered via the @mcp.tool() decorator on the FastMCP server instance named 'mcp', defined at line 14.
    @mcp.tool()
  • Helper function used by generate_commit_message to resolve and validate that a given path is a valid Git repository (contains a .git directory).
    def _get_valid_repo_path(repo_path: Optional[str]) -> Optional[str]:
        """
        Resolve and validate the git repository path.
        Returns the valid repo path if valid, otherwise None.
        """
        logger = logging.getLogger(__name__)
        # Resolve user tilde and symlinks to a canonical path
        resolved = (
            os.path.realpath(os.path.expanduser(repo_path)) if repo_path else os.getcwd()
        )
        logger.info("[get_valid_repo_path] Resolved repository path: %s", resolved)
        if not os.path.isdir(resolved) or not os.path.exists(
            os.path.join(resolved, ".git")
        ):
            return None
        return resolved
Behavior4/5

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

The description details validation, data collection (staged diff, porcelain, name-status), incorporation of user preferences, and output format. Since no annotations are provided, the description adequately covers behavioral traits.

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 well-structured with clear sections for behavior and args, front-loads the purpose, and uses concise bullet points without unnecessary words.

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

Completeness4/5

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

Given the optional parameters and presence of output schema, the description covers purpose, behavior, and parameter semantics adequately, though it could briefly mention that the output is a string.

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 adds meaning by explaining each parameter's role: repo_path defaults to CWD, commit_type lists allowed types, and scope describes change scope, compensating for schema gaps.

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 it prepares a structured analysis and instruction block for generating a Conventional Commit message from staged git changes, with specific verb and resource, and distinguishes from sibling check_git_status.

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

Usage Guidelines3/5

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

The description implies usage for generating commit messages but does not explicitly state when to use this tool versus the sibling check_git_status or provide guidance on prerequisites or exclusions.

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/theoklitosBam7/mcp-git-commit-generator'

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