Skip to main content
Glama
Arcia125

Git Workflow Automation MCP Server

by Arcia125

create_pull_request

Create GitHub pull requests with automated authentication handling to streamline code review workflows. Specify title, description, branches, and preview changes before submission.

Instructions

Create a GitHub pull request with proper authentication handling

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
titleYesPull request title
bodyYesPull request description
baseBranchNoBase branch (target)main
headBranchNoHead branch (source, defaults to current branch)
workingDirNoWorking directory path
dryRunNoPreview without executing

Implementation Reference

  • The core handler function implementing the create_pull_request tool logic. Uses GitHub CLI (gh pr create) with authentication handling via token clearing and PowerShell escaping.
    async function createPullRequest(
      title: string,
      body: string,
      baseBranch: string = 'main',
      headBranch?: string,
      workingDir?: string,
      dryRun: boolean = false
    ): Promise<WorkflowResult> {
      try {
        if (dryRun) {
          return {
            success: true,
            message: "Dry run: Would create pull request",
            details: {
              title,
              body,
              baseBranch,
              headBranch
            }
          };
        }
    
        // Get current branch if not specified
        if (!headBranch) {
          const git = getGit(workingDir);
          headBranch = await git.revparse(['--abbrev-ref', 'HEAD']);
        }
    
        // Create PR using GitHub CLI with cleared tokens and proper escaping
        const command = `gh pr create --title "${title}" --body "${body}" --base ${baseBranch} --head ${headBranch}`;
        const result = await executeGitHubCommand(command, {
          title,
          body,
          cwd: workingDir
        });
    
        // Extract PR URL from output
        const prUrl = result.stdout.trim();
    
        return {
          success: true,
          message: "Successfully created pull request",
          details: {
            url: prUrl,
            title,
            baseBranch,
            headBranch
          }
        };
      } catch (error: any) {
        return {
          success: false,
          message: "Failed to create pull request",
          error: `Failed to create pull request: ${error.message}`
        };
      }
    }
  • src/index.ts:452-486 (registration)
    Tool registration in ListToolsRequestSchema handler, including name, description, and input schema definition.
      name: "create_pull_request",
      description: "Create a GitHub pull request with proper authentication handling",
      inputSchema: {
        type: "object",
        properties: {
          title: {
            type: "string",
            description: "Pull request title"
          },
          body: {
            type: "string",
            description: "Pull request description"
          },
          baseBranch: {
            type: "string",
            description: "Base branch (target)",
            default: "main"
          },
          headBranch: {
            type: "string",
            description: "Head branch (source, defaults to current branch)"
          },
          workingDir: {
            type: "string",
            description: "Working directory path"
          },
          dryRun: {
            type: "boolean",
            description: "Preview without executing",
            default: false
          }
        },
        required: ["title", "body"]
      }
    },
  • src/index.ts:595-604 (registration)
    Dispatch logic in CallToolRequestSchema handler that routes to the createPullRequest function.
    case "create_pull_request":
      result = await createPullRequest(
        args?.title as string,
        args?.body as string,
        (args?.baseBranch as string) || 'main',
        args?.headBranch as string,
        args?.workingDir as string,
        (args?.dryRun as boolean) || false
      );
      break;
  • Supporting helper function for safely executing GitHub CLI commands with environment token clearing and PowerShell string escaping, crucial for the PR creation.
    async function executeGitHubCommand(
      baseCommand: string,
      options?: {
        title?: string;
        body?: string;
        cwd?: string;
      }
    ): Promise<{ stdout: string; stderr: string }> {
      let tempBodyFile: string | null = null;
    
      try {
        let finalCommand = baseCommand;
    
        // If we have a body, write it to a temporary file to avoid PowerShell parsing issues
        if (options?.body) {
          tempBodyFile = join(tmpdir(), `gh-pr-body-${Date.now()}.txt`);
          writeFileSync(tempBodyFile, options.body, 'utf8');
    
          // Replace --body with --body-file, handling both quoted and unquoted body content
          finalCommand = finalCommand.replace(/--body\s+"[^"]*"/, `--body-file "${tempBodyFile}"`);
          finalCommand = finalCommand.replace(/--body\s+[^\s]+/, `--body-file "${tempBodyFile}"`);
        }
    
        // If we have a title, properly escape it for PowerShell
        if (options?.title) {
          const escapedTitle = escapePowerShellString(options.title);
          finalCommand = finalCommand.replace(/--title\s+"([^"]*)"/, `--title '${escapedTitle}'`);
        }
    
        // Build the PowerShell command with proper token clearing
        const powerShellCommand = `powershell -Command "Remove-Item Env:GH_TOKEN -ErrorAction SilentlyContinue; Remove-Item Env:GITHUB_TOKEN -ErrorAction SilentlyContinue; ${finalCommand}"`;
    
        const result = await execAsync(powerShellCommand, {
          cwd: options?.cwd || process.cwd(),
          maxBuffer: 1024 * 1024 // 1MB buffer
        });
    
        return result;
      } catch (error: any) {
        throw new Error(`Command failed: ${error.message}\nStdout: ${error.stdout}\nStderr: ${error.stderr}`);
      } finally {
        // Clean up temporary file
        if (tempBodyFile) {
          try {
            unlinkSync(tempBodyFile);
          } catch (e) {
            // Ignore cleanup errors
          }
        }
      }
    }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'proper authentication handling' which hints at auth requirements, but doesn't specify what those requirements are, whether this is a mutating operation, what happens on success/failure, or any rate limits. For a tool that creates GitHub pull requests (a significant write operation), this is inadequate behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that gets straight to the point. It's appropriately sized for the tool's complexity, though it could potentially be more structured with additional context about the tool's role in the workflow.

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

Completeness2/5

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

For a tool that creates GitHub pull requests (a significant mutating operation) with no annotations and no output schema, the description is incomplete. It doesn't explain what the tool returns, what happens on success/failure, authentication specifics, or how it relates to sibling tools. The mention of 'proper authentication handling' is insufficient given the complexity of the operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, so all parameters are documented in the schema itself. The description adds no additional parameter information beyond what's already in the schema. According to scoring rules, when schema_description_coverage is high (>80%), the baseline is 3 even with no param info in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('create') and resource ('GitHub pull request'), making the purpose immediately understandable. However, it doesn't differentiate this tool from its siblings like 'merge_pull_request' or explain how it fits within the broader git workflow context.

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

Usage Guidelines2/5

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

The description mentions 'proper authentication handling' which implies some context about authentication requirements, but provides no explicit guidance on when to use this tool versus alternatives like 'complete_git_workflow' or 'git_commit_and_push'. There's no mention of prerequisites, sequencing, or when-not-to-use scenarios.

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/Arcia125/git-workflow-mcp-server'

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