GitHub PR自动生成工具

一款基于Model Context Protocol (MCP)的GitHub Pull Request自动生成工具,提供变更分析、PR内容生成和GitHub API集成功能。

  • by yunhalee05
  • Kotlin
  • 本地部署
  • 更新于
在 GitHub 查看 yunhalee05/github-mcp

使用说明

GitHub MCP服务器

用于生成交互式GitHub Pull请求的Model Context Protocol(MCP)服务器。

通过分步工作流提供Git更改分析、PR内容自动生成、GitHub API集成等功能。

🚀 主要功能

  • 逐步PR创建工作流:选择分支→分析更改→生成PR内容→生成GitHub PR
  • 快速PR创建:使用一个命令运行整个工作流(pr_smart)
  • 分析Git更改:提交历史记录、更改的文件、按文件类型分类
  • 智能PR内容生成:根据提交消息和更改自动生成
  • 支持动态PR模板:自动检测特定于存储库的自定义模板
  • JIRA门票绑定:PR标题和正文中自动包含JIRA票号
  • GitHub API集成:PR创建,分支推送自动化
  • 自动检测工作目录:可直接用于任何项目

📋 要求

  • Java 21+
  • 等级9.2+
  • Git
  • GitHub Personal Access Token(需要repo权限)
  • Claude Code或Claude Desktop

🛠️ 安装

方法1:在Claude Code中 claude mcp add 使用(建议)

claude mcp add github-mcp -s user \
  -e GITHUB_TOKEN=ghp_your_token_here \
  -e PR_BASE_BRANCH=develop \
  -e PR_JIRA_PREFIX=PROJ \
  -- java -jar https://github.com/yunhalee05/github-mcp/releases/download/v1.0.0/github_mcp-0.0.1-SNAPSHOT.jar

方法2:直接修改配置文件

Claude Code设置

设置文件位置: ~/.claude/settings.json

{
  "mcpServers": {
    "github-mcp": {
      "command": "java",
      "args": [
        "-jar",
        "/path/to/github-mcp/build/libs/github-mcp-1.0-SNAPSHOT.jar"
      ],
      "env": {
        "GITHUB_TOKEN": "ghp_your_token_here",
        "PR_BASE_BRANCH": "develop",
        "PR_JIRA_PREFIX": "PROJ",
        "PR_TEMPLATE_PATH": "/path/to/custom/template.md"
      }
    }
  }
}

Claude桌面设置

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "github-mcp": {
      "command": "java",
      "args": [
        "-jar",
        "/path/to/github-mcp/build/libs/github-mcp-1.0-SNAPSHOT.jar"
      ],
      "env": {
        "GITHUB_TOKEN": "ghp_your_token_here",
        "PR_BASE_BRANCH": "develop",
        "PR_JIRA_PREFIX": "PROJ",
        "PR_TEMPLATE_PATH": "/path/to/custom/template.md"
      }
    }
  }
}

环境变量说明

环境变量 必需 默认值 说明
GITHUB_TOKEN --GitHub Personal Access Token(需要repo权限)
PR_BASE_BRANCH development默认Base分支
PR_JIRA_PREFIX PROJ JIRA票务修复程序
PR_TEMPLATE_PATH 自动检测 自定义PR模板文件路径

重要事项:

  • 自动检测工作目录 -无需设置环境变量
  • 自动使用Claude Code/Desktop运行的目录
  • AI在执行上下文中自动传递工作目录

生成GitHub Token

  1. https://github.com/settings/tokens连接
  2. “生成新令牌(经典)”클릭
  3. 选择所需权限:
    • repo (全部)
    • workflow (可选)
  4. 复制生成的令牌并将其添加到配置文件

构建

# 프로젝트 클론
git clone https://github.com/YOUR_USERNAME/github-mcp.git
cd github-mcp

# 빌드
./gradlew clean build

# JAR 파일 확인
ls -la build/libs/github-mcp-1.0-SNAPSHOT.jar

🏗️ 体系结构

项目结构

src/main/kotlin/com/yunhalee/github_mcp/
├── McpServer.kt                     # MCP 서버 메인 엔트리포인트
├── component/
│   └── TemplateLoader.kt           # PR 템플릿 로더
├── service/
│   ├── GitService.kt               # Git 명령어 실행 서비스 (싱글톤)
│   └── GitHubService.kt            # GitHub API 호출 서비스
└── tool/
    ├── ToolContext.kt              # Tool 공유 컨텍스트
    ├── ToolRegistry.kt             # Tool 등록 관리자
    ├── StartPrWorkflowTool.kt      # PR 워크플로우 시작
    ├── SelectBaseBranchTool.kt     # Base 브랜치 선택 및 분석
    ├── GeneratePrContentTool.kt    # PR 내용 생성
    ├── CreatePrConfirmedTool.kt    # PR 생성 실행
    ├── GetCurrentBranchTool.kt     # 현재 브랜치 확인
    └── PrSmartTool.kt              # 빠른 PR 생성 (워크플로우 통합)

核心组件

1. Registered Tool模式

使用Kotlin MCP SDK的正式模式定义工具:

fun createStartPrWorkflowTool(context: ToolContext) = RegisteredTool(
    Tool(
        name = "start_pr_workflow",
        description = "PR 생성 워크플로우를 시작합니다...",
        inputSchema = ToolSchema(
            properties = buildJsonObject {
                put("working_dir", buildJsonObject {
                    put("type", "string")
                    put("description", "현재 작업 디렉토리 경로 - REQUIRED")
                })
            },
            required = listOf("working_dir")
        )
    )
) { request ->
    val workingDir = request.arguments?.get("working_dir")?.jsonPrimitive?.content
        ?: return@RegisteredTool CallToolResult(
            content = listOf(TextContent(text = "❌ working_dir이 필요합니다.")),
            isError = true
        )

    // Tool 로직 구현
    CallToolResult(content = listOf(TextContent(text = result)))
}

2. 工具上下文

所有Tool共享的上下文:

data class ToolContext(
    val defaultBaseBranch: String,
    val jiraPrefix: String,
    val githubService: GitHubService?,
    val prTemplatePath: String? = null
) {
    val gitService = GitService()  // 싱글톤 인스턴스

    private val templateLoader: TemplateLoader by lazy {
        TemplateLoader(customTemplatePath = prTemplatePath)
    }

    fun loadPrTemplate(workingDir: String): String {
        return templateLoader.loadPrTemplate(workingDir)
    }
}

主要更改:

  • defaultWorkingDir 删除-不再需要
  • gitService 添加单色实例
  • templateLoader 通过延迟初始化加载PR模板

3. GitService(单色模式)

处理所有Git任务, workingDir接受作为方法参数:

class GitService {
    suspend fun getCurrentBranch(workingDir: String): Result<String>
    suspend fun getBranches(workingDir: String): Result<List<String>>
    suspend fun getDiff(workingDir: String, baseBranch: String, currentBranch: String): Result<String>
    suspend fun getChangedFiles(workingDir: String, baseBranch: String, currentBranch: String): Result<List<String>>
    suspend fun getCommits(workingDir: String, baseBranch: String, currentBranch: String): Result<List<String>>
    suspend fun getCommitCount(workingDir: String, baseBranch: String, currentBranch: String): Result<Int>
    suspend fun pushBranch(workingDir: String, branch: String): Result<String>
    suspend fun fetchBranch(workingDir: String, branch: String): Result<String>
    suspend fun checkRemoteBranchExists(workingDir: String, branch: String): Result<Boolean>
    suspend fun getRepositoryInfo(workingDir: String): Result<Map<String, String>>
}

设计特点:

  • 使用单色图案重复使用实例
  • workingDir接收为方法参数,而不是实例变量
  • MCP服务器可以同时处理多个项目

4. 模板加载器

动态加载PR模板:

class TemplateLoader(private val customTemplatePath: String? = null) {
    fun loadPrTemplate(workingDir: String): String {
        val templatePaths = listOf(
            "$workingDir/.github/PULL_REQUEST_TEMPLATE.md",
            "$workingDir/.github/pull_request_template.md",
            "$workingDir/docs/pull_request_template.md",
            customTemplatePath
        )

        for (path in templatePaths) {
            path?.let {
                val file = File(it)
                if (file.exists() && file.isFile) {
                    return file.readText()
                }
            }
        }

        return DEFAULT_PR_TEMPLATE
    }
}

5. 工具注册表

集中管理Tool注册:

class ToolRegistry(private val context: ToolContext) {
    fun getAllTools(): List<RegisteredTool> = listOf(
        createStartPrWorkflowTool(context),
        createSelectBaseBranchTool(context),
        createGeneratePrContentTool(context),
        createCreatePrConfirmedTool(context),
        createGetCurrentBranchTool(context),
        createPrSmartTool(context)
    )

    fun registerAll(server: Server) {
        getAllTools().forEach { tool ->
            server.addTool(tool.tool, tool.handler)
        }
    }
}

📚 可用的工具

1. start_pr_workflow -启动PR工作流

启动PR创建工作流。

参数:

  • working_dir (必需):工作目录路径(AI自动传递)

动作:

  • 检查当前Git分支
  • 检查main/master分支
  • 返回可用的base分支列表

下一步: 如果用户选择base分支, select_base_branch 呼叫

2. select_base_branch -选择Base分支

选择Base分支并分析更改。

参数:

  • base_branch (必需):Base分支名称
  • working_dir (必需):工作目录路径(AI自动传递)

动作:

  • 验证和fetch分支的存在
  • 查看更改的文件列表
  • 提交历史分析
  • 按文件类型分类

下一步: 如果用户输入JIRA票证 generate_pr_content 呼叫

3. generate_pr_content -创建PR内容

根据JIRA票证和更改创建PR标题和正文。

参数:

  • base_branch (必需):Base分支
  • jira_ticket (必需):JIRA票号(如果没有,则为“无”)
  • additional_context (可选):其他上下文
  • working_dir (必需):工作目录路径(AI自动传递)

动作:

  • Git diff分析
  • 创建PR标题(包括JIRA票证)
  • 自动检测和加载存储库中的PR模板
  • 要求AI汇总更改并创建模板

模板优先级:

  1. .github/PULL_REQUEST_TEMPLATE.md
  2. .github/pull_request_template.md
  3. docs/pull_request_template.md
  4. PR_TEMPLATE_PATH 环境变量路径
  5. 默认内置模板

下一步: 用户确认后 create_pr_confirmed 呼叫

4. create_pr_confirmed -运行PR创建

实际上,您正在创建GitHub PR。

参数:

  • title (必需):PR标题
  • body (必需):PR正文
  • base_branch (必需):Base分支
  • working_dir (必需):工作目录路径(AI自动传递)

动作:

  • 分支push(如果不在远程)
  • 查看Repository信息(提取owner/repo)
  • 使用GitHub API创建PR
  • 返回生成的PR URL

5. get_current_branch -检查当前分支

检查当前Git分支。

参数:

  • working_dir (必需):工作目录路径(AI自动传递)

动作:

  • 返回当前品牌致命值

6. pr_smart -快速PR创建

一次运行整个工作流。

参数:

  • base_branch (必需):Base分支
  • jira_ticket (可选):JIRA票号
  • additional_context (可选):其他上下文
  • working_dir (必需):工作目录路径(AI自动传递)

动作:

  • 验证分支→分析更改→一次处理PR内容生成
  • 向用户展示生成的PR内容并请求确认
  • 确认时 create_pr_confirmed 呼叫

🔧 开发指南

添加新工具

1.创建Tool文件

src/main/kotlin/com/yunhalee/github_mcp/tool/YourNewTool.kt:

2.注册ToolRegistry

src/main/kotlin/com/yunhalee/github_mcp/tool/ToolRegistry.kt:

fun getAllTools(): List<RegisteredTool> = listOf(
    createStartPrWorkflowTool(context),
    createSelectBaseBranchTool(context),
    // ...
    createYourNewTool(context)  // 추가!
)

3.构建和测试

./gradlew clean build
java -jar build/libs/github-mcp-1.0-SNAPSHOT.jar

使用GitService/GithubService

重要信息: GitService是单色的。 workingDir作为方法参数传递。

使用PR模板

// ToolContext를 통해 템플릿 로드
val template = context.loadPrTemplate(workingDir)

// 템플릿은 실행 저장소의 .github/PULL_REQUEST_TEMPLATE.md 또는
// PR_TEMPLATE_PATH 환경변수 경로에서 자동으로 로드됩니다

🌟 工作原理

自动检测工作目录

这个MCP服务器 自动检测工作目录进行:

  1. Claude Code/Desktop运行时,将当前工作目录传递到AI运行上下文
  2. AI <env>Working directory: /path/to/project</env> 读取信息
  3. 每次调用Tool时,AI将自动 working_dir 将路径传递给参数
  4. MCP服务器在其目录中运行Git命令

优点:

  • 每个项目无需单独设置
  • 无论在哪个项目上运行Claude Code/Desktop,都会自动识别该项目的Git存储库
  • 简化设置文件-无需将WORKING_DIR指定为环境变量
  • 可以同时处理多个项目

MCP通信方式

MCP服务器 工作室(标准输入/输出)通信:

  • 无需HTTP服务器
  • 不需要Spring Boot Context
  • 不需要Dependency Injection
  • 纯Kotlin+MCP SDK就足够了

结果:

  • 13 MB的轻量级JAR(使用Spring Boot时为30-40 MB)
  • 快速启动时间
  • 明确的依赖性

📦 依赖性

dependencies {
    // MCP SDK
    implementation("io.modelcontextprotocol:kotlin-sdk:0.8.0")

    // Ktor Client (HTTP 요청)
    implementation("io.ktor:ktor-client-cio:3.3.2")
    implementation("io.ktor:ktor-client-content-negotiation:3.3.2")
    implementation("io.ktor:ktor-serialization-kotlinx-json:3.3.2")

    // Kotlin IO (STDIO 통신)
    implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.5.4")

    // Logging
    implementation("org.slf4j:slf4j-simple:2.0.16")
}

🔗 参考资料

📝 快速入门

详细的安装和使用方法包括: QUICKSTART.md请参考。

📝 许可证

这个项目是个人项目。

🤝 贡献

请将错误报告或功能建议登记为问题。