Skip to content

Pr

pr

GitPRTool — create GitHub pull requests via gh CLI.

GitPRTool

Bases: AXMTool

Create a GitHub pull request with optional auto-merge.

Registered as git_pr via axm.tools entry point.

Source code in packages/axm-git/src/axm_git/tools/pr.py
class GitPRTool(AXMTool):
    """Create a GitHub pull request with optional auto-merge.

    Registered as ``git_pr`` via axm.tools entry point.
    """

    @property
    def name(self) -> str:
        """Tool name used for MCP registration."""
        return "git_pr"

    def execute(  # type: ignore[override]
        self,
        *,
        title: str,
        body: str | None = None,
        base: str = "main",
        auto_merge: bool = True,
        path: str = ".",
        **kwargs: Any,
    ) -> ToolResult:
        """Create a GitHub pull request.

        Args:
            title: PR title (required).
            body: PR body/description.
            base: Base branch (default ``main``).
            auto_merge: Enable auto-merge with squash (default ``True``).
            path: Repository path.

        Returns:
            ToolResult with ``pr_url`` and ``pr_number`` on success.
        """
        resolved = Path(path).resolve()

        # 1. Verify this is a git repo.
        check = run_git(["rev-parse", "--git-dir"], resolved)
        if check.returncode != 0:
            return not_a_repo_error(check.stderr, resolved)

        # 2. Check gh availability.
        if not gh_available():
            return ToolResult(
                success=False,
                error="gh CLI not available",
            )

        # 3. Create the PR.
        create_args = ["pr", "create", "--title", title, "--base", base]
        if body:
            create_args.extend(["--body", body])

        result = run_gh(create_args, resolved)
        if result.returncode != 0:
            return ToolResult(
                success=False,
                error=result.stderr.strip() or result.stdout.strip(),
            )

        pr_url = result.stdout.strip()
        pr_number = pr_url.rstrip("/").rsplit("/", maxsplit=1)[-1]

        # 4. Enable auto-merge if requested.
        if auto_merge:
            merge_result = run_gh(
                ["pr", "merge", pr_number, "--auto", "--squash"],
                resolved,
            )
            return ToolResult(
                success=True,
                data={
                    "pr_url": pr_url,
                    "pr_number": pr_number,
                    "auto_merge": merge_result.returncode == 0,
                },
            )

        return ToolResult(
            success=True,
            data={
                "pr_url": pr_url,
                "pr_number": pr_number,
                "auto_merge": False,
            },
        )
name property

Tool name used for MCP registration.

execute(*, title, body=None, base='main', auto_merge=True, path='.', **kwargs)

Create a GitHub pull request.

Parameters:

Name Type Description Default
title str

PR title (required).

required
body str | None

PR body/description.

None
base str

Base branch (default main).

'main'
auto_merge bool

Enable auto-merge with squash (default True).

True
path str

Repository path.

'.'

Returns:

Type Description
ToolResult

ToolResult with pr_url and pr_number on success.

Source code in packages/axm-git/src/axm_git/tools/pr.py
def execute(  # type: ignore[override]
    self,
    *,
    title: str,
    body: str | None = None,
    base: str = "main",
    auto_merge: bool = True,
    path: str = ".",
    **kwargs: Any,
) -> ToolResult:
    """Create a GitHub pull request.

    Args:
        title: PR title (required).
        body: PR body/description.
        base: Base branch (default ``main``).
        auto_merge: Enable auto-merge with squash (default ``True``).
        path: Repository path.

    Returns:
        ToolResult with ``pr_url`` and ``pr_number`` on success.
    """
    resolved = Path(path).resolve()

    # 1. Verify this is a git repo.
    check = run_git(["rev-parse", "--git-dir"], resolved)
    if check.returncode != 0:
        return not_a_repo_error(check.stderr, resolved)

    # 2. Check gh availability.
    if not gh_available():
        return ToolResult(
            success=False,
            error="gh CLI not available",
        )

    # 3. Create the PR.
    create_args = ["pr", "create", "--title", title, "--base", base]
    if body:
        create_args.extend(["--body", body])

    result = run_gh(create_args, resolved)
    if result.returncode != 0:
        return ToolResult(
            success=False,
            error=result.stderr.strip() or result.stdout.strip(),
        )

    pr_url = result.stdout.strip()
    pr_number = pr_url.rstrip("/").rsplit("/", maxsplit=1)[-1]

    # 4. Enable auto-merge if requested.
    if auto_merge:
        merge_result = run_gh(
            ["pr", "merge", pr_number, "--auto", "--squash"],
            resolved,
        )
        return ToolResult(
            success=True,
            data={
                "pr_url": pr_url,
                "pr_number": pr_number,
                "auto_merge": merge_result.returncode == 0,
            },
        )

    return ToolResult(
        success=True,
        data={
            "pr_url": pr_url,
            "pr_number": pr_number,
            "auto_merge": False,
        },
    )