Skip to main content
Glama
theoklitosBam7

MCP Git Commit Generator

generate_commit_message

Generate Conventional Commit messages from staged git changes. Analyzes diffs to create properly formatted commit messages following conventional commit standards.

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

Implementation Reference

  • Core implementation of the generate_commit_message MCP tool handler. Validates git repo, retrieves staged changes (diff, status, name-status), incorporates optional type/scope, and returns a detailed LLM prompt enforcing Conventional Commit format with strict output rules.
    @mcp.tool()
    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)}"
  • Input/output schema for the tool defined by function signature and comprehensive docstring describing parameters, behavior, and return value.
    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
        """
  • FastMCP decorator that registers generate_commit_message as an MCP tool on the mcp server instance.
    @mcp.tool()
  • Utility function called by the handler to resolve and validate the git repository path, handling tilde expansion and checking for .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
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