├── .gitignore
├── .idea
├── .gitignore
├── encodings.xml
├── misc.xml
└── vcs.xml
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── devoxx
│ │ └── agentic
│ │ └── github
│ │ ├── GitHubMcpApplication.java
│ │ └── tools
│ │ ├── AbstractToolService.java
│ │ ├── BranchService.java
│ │ ├── CommitService.java
│ │ ├── ContentService.java
│ │ ├── GitHubClientFactory.java
│ │ ├── GitHubEnv.java
│ │ ├── IssueService.java
│ │ ├── PullRequestService.java
│ │ └── RepositoryService.java
└── resources
│ ├── application.properties
│ └── mcp-servers-config.json
└── test
└── java
└── com
└── devoxx
└── agentic
└── github
├── ClientStdio.java
└── GitHubServiceTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Store
39 | /.idea/
40 | /.env
41 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Stephan Janssen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GitHub MCP Server
2 |
3 | This project implements a Model Context Protocol (MCP) server for GitHub API access. It provides a set of tools that allow LLM agents to interact with GitHub repositories, issues, pull requests, and other GitHub resources.
4 |
5 | ## Features
6 |
7 | The server provides the following GitHub operations:
8 |
9 | - **Repository Management**
10 | - List repositories for the authenticated user
11 | - Get repository details
12 | - Search for repositories
13 |
14 | - **Issue Management**
15 | - List issues with filtering options
16 | - Get detailed information about issues
17 | - Create new issues
18 | - Add comments to issues
19 | - Search for issues
20 |
21 | - **Pull Request Management**
22 | - List pull requests with filtering options
23 | - Get detailed information about pull requests
24 | - Create comments on pull requests
25 | - Merge pull requests
26 |
27 | - **Branch Management**
28 | - List branches in a repository
29 | - Create new branches
30 |
31 | - **Commit Management**
32 | - Get detailed information about commits
33 | - List commits with filtering options
34 | - Search for commits by message
35 |
36 | - **Content Management**
37 | - Get file contents from repositories
38 | - List directory contents
39 | - Create or update files
40 | - Search for code within repositories
41 |
42 | These operations are exposed as tools for Large Language Models using the Model Context Protocol (MCP), allowing AI systems to safely interact with GitHub through its API.
43 |
44 | ### Claude Desktop
45 |
46 |
47 | ### DevoxxGenie IDEA plugin
48 |
49 |
50 |
51 | ## Getting Started
52 |
53 | ### Prerequisites
54 |
55 | - Java 17 or higher
56 | - Maven 3.6+
57 | - Spring Boot 3.3.6
58 | - Spring AI MCP Server components
59 | - A GitHub account and personal access token
60 |
61 | ### Building the Project
62 |
63 | Build the project using Maven:
64 |
65 | ```bash
66 | mvn clean package
67 | ```
68 |
69 | ### Running the Server
70 |
71 | Run the server using the following command:
72 |
73 | ```bash
74 | java -jar target/GitHubMCP-1.0-SNAPSHOT.jar
75 | ```
76 |
77 | The server can use STDIO for communication with MCP clients or can be run as a web server.
78 |
79 | ## Environment Variables
80 |
81 | The GitHub MCP server supports the following environment variables for authentication:
82 |
83 | - `GITHUB_TOKEN` or `GITHUB_PERSONAL_ACCESS_TOKEN`: Your GitHub personal access token
84 | - `GITHUB_HOST`: The base URL of your GitHub instance (e.g., `github.com` or `github.mycompany.com` for GitHub Enterprise)
85 | - `GITHUB_REPOSITORY`: Default repository to use if not specified in API calls (e.g., `owner/repo`)
86 |
87 | You can set these environment variables when launching the MCP server, and the GitHub services will use them as default values. This allows you to avoid having to provide authentication details with every API call.
88 |
89 | ## Usage with MCP Clients
90 |
91 | ### Using with Claude Desktop
92 |
93 | Edit your claude_desktop_config.json file with the following:
94 |
95 | ```json
96 | {
97 | "mcpServers": {
98 | "github": {
99 | "command": "java",
100 | "args": [
101 | "-Dspring.ai.mcp.server.stdio=true",
102 | "-Dspring.main.web-application-type=none",
103 | "-Dlogging.pattern.console=",
104 | "-jar",
105 | "/path/to/GitHubMCP/target/GitHubMCP-1.0-SNAPSHOT.jar"
106 | ],
107 | "env": {
108 | "GITHUB_TOKEN": "your-github-token-here",
109 | "GITHUB_HOST": "github.com",
110 | "GITHUB_REPOSITORY": "your-username/your-repository"
111 | }
112 | }
113 | }
114 | }
115 | ```
116 |
117 | ### Using with DevoxxGenie or similar MCP clients
118 |
119 | 1. In your MCP client, access the MCP Server configuration screen
120 | 2. Configure the server with the following settings:
121 | - **Name**: `GitHub` (or any descriptive name)
122 | - **Transport Type**: `STDIO`
123 | - **Command**: Full path to your Java executable
124 | - **Arguments**:
125 | ```
126 | -Dspring.ai.mcp.server.stdio=true
127 | -Dspring.main.web-application-type=none
128 | -Dlogging.pattern.console=
129 | -jar
130 | /path/to/GitHubMCP/target/GitHubMCP-1.0-SNAPSHOT.jar
131 | ```
132 | - **Environment Variables**:
133 | ```
134 | GITHUB_TOKEN=your-github-token-here
135 | GITHUB_HOST=github.com
136 | GITHUB_REPOSITORY=your-username/your-repository
137 | ```
138 |
139 | ## Security Considerations
140 |
141 | When using this server, be aware that:
142 | - You need to provide a GitHub personal access token for authentication
143 | - The LLM agent will have access to create, read, and modify GitHub resources
144 | - Consider running the server with appropriate permissions and in a controlled environment
145 | - Ensure your token has only the minimum required permissions for your use case
146 |
147 | ## Example Usage
148 |
149 | ### With Environment Variables
150 |
151 | If you've configured the MCP server with environment variables, you can simply ask:
152 |
153 | ```
154 | Can you get a list of open issues in my GitHub repository?
155 | ```
156 |
157 | Claude will use the GitHub services with the pre-configured authentication details to fetch the open issues from your GitHub repository and summarize them.
158 |
159 | ### With Explicit Repository
160 |
161 | You can override the default repository by specifying it in your request:
162 |
163 | ```
164 | Can you list the pull requests for the anthropics/claude-playground repository?
165 | ```
166 |
167 | The GitHub service will use your authentication token but query the specified repository instead of the default one.
168 |
169 | ## Available Services
170 |
171 | The GitHub MCP server is organized into several service classes, each providing different functionality:
172 |
173 | 1. **RepositoryService**
174 | - `listRepositories`: List repositories for the authenticated user
175 | - `getRepository`: Get detailed information about a specific repository
176 | - `searchRepositories`: Search for repositories matching a query
177 |
178 | 2. **IssueService**
179 | - `listIssues`: List issues for a repository with filtering options
180 | - `getIssue`: Get detailed information about a specific issue
181 | - `createIssue`: Create a new issue in a repository
182 | - `addIssueComment`: Add a comment to an issue
183 | - `searchIssues`: Search for issues matching a query
184 |
185 | 3. **PullRequestService**
186 | - `listPullRequests`: List pull requests for a repository with filtering options
187 | - `getPullRequest`: Get detailed information about a specific pull request
188 | - `createPullRequestComment`: Add a comment to a pull request
189 | - `mergePullRequest`: Merge a pull request with specified merge method
190 |
191 | 4. **BranchService**
192 | - `listBranches`: List branches in a repository with filtering options
193 | - `createBranch`: Create a new branch from a specified reference
194 |
195 | 5. **CommitService**
196 | - `getCommitDetails`: Get detailed information about a specific commit
197 | - `listCommits`: List commits in a repository with filtering options
198 | - `findCommitByMessage`: Search for commits containing specific text in their messages
199 |
200 | 6. **ContentService**
201 | - `getFileContents`: Get the contents of a file in a repository
202 | - `listDirectoryContents`: List contents of a directory in a repository
203 | - `createOrUpdateFile`: Create or update a file in a repository
204 | - `searchCode`: Search for code within repositories
205 |
206 | Each service provides methods that can be called by LLM agents through the MCP protocol, allowing them to interact with GitHub in a structured and controlled manner.
207 |
208 | ## Enterprise GitHub Support
209 |
210 | This MCP server supports both GitHub.com and GitHub Enterprise instances. To use with GitHub Enterprise, set the `GITHUB_HOST` environment variable to your enterprise GitHub URL.
211 |
212 | ## Limitations
213 |
214 | - The server requires a valid GitHub personal access token with appropriate permissions
215 | - Rate limiting is subject to GitHub API limits
216 | - Some operations may require specific permissions on the token
217 | - Large repositories or files may encounter performance limitations
218 |
219 | ## Contributing
220 |
221 | Contributions are welcome! Please feel free to submit a Pull Request.
222 |
223 | ## License
224 |
225 | This project is licensed under the MIT License - see the LICENSE file for details.
226 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.springframework.boot
8 | spring-boot-starter-parent
9 | 3.3.6
10 |
11 |
12 |
13 | com.devoxx.agentic
14 | GitHubMCP
15 | 1.0-SNAPSHOT
16 |
17 |
18 | 17
19 | 17
20 | UTF-8
21 |
22 |
23 |
24 |
25 |
26 | org.springframework.ai
27 | spring-ai-bom
28 | 1.0.0-SNAPSHOT
29 | pom
30 | import
31 |
32 |
33 |
34 |
35 |
36 |
37 | org.springframework.ai
38 | spring-ai-starter-mcp-server-webmvc
39 |
40 |
41 |
42 | org.springframework
43 | spring-web
44 |
45 |
46 |
47 | com.fasterxml.jackson.core
48 | jackson-databind
49 | 2.15.2
50 |
51 |
52 |
53 | io.github.cdimascio
54 | dotenv-java
55 | 3.0.0
56 |
57 |
58 |
59 |
60 | org.kohsuke
61 | github-api
62 | 1.317
63 |
64 |
65 |
66 |
67 | org.junit.jupiter
68 | junit-jupiter
69 | test
70 |
71 |
72 |
73 | org.mockito
74 | mockito-junit-jupiter
75 | test
76 |
77 |
78 |
79 | org.mockito
80 | mockito-core
81 | test
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | org.springframework.boot
90 | spring-boot-maven-plugin
91 |
92 |
93 | org.apache.maven.plugins
94 | maven-surefire-plugin
95 |
96 |
97 |
98 |
99 |
100 |
101 | Central Portal Snapshots
102 | central-portal-snapshots
103 | https://central.sonatype.com/repository/maven-snapshots/
104 |
105 | false
106 |
107 |
108 | true
109 |
110 |
111 |
112 | spring-milestones
113 | Spring Milestones
114 | https://repo.spring.io/milestone
115 |
116 | false
117 |
118 |
119 |
120 | spring-snapshots
121 | Spring Snapshots
122 | https://repo.spring.io/snapshot
123 |
124 | false
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/src/main/java/com/devoxx/agentic/github/GitHubMcpApplication.java:
--------------------------------------------------------------------------------
1 | package com.devoxx.agentic.github;
2 |
3 | import com.devoxx.agentic.github.tools.BranchService;
4 | import com.devoxx.agentic.github.tools.CommitService;
5 | import com.devoxx.agentic.github.tools.ContentService;
6 | import com.devoxx.agentic.github.tools.IssueService;
7 | import com.devoxx.agentic.github.tools.PullRequestService;
8 | import com.devoxx.agentic.github.tools.RepositoryService;
9 | import org.springframework.ai.tool.ToolCallbackProvider;
10 | import org.springframework.ai.tool.method.MethodToolCallbackProvider;
11 | import org.springframework.boot.SpringApplication;
12 | import org.springframework.boot.autoconfigure.SpringBootApplication;
13 | import org.springframework.context.annotation.Bean;
14 |
15 | @SpringBootApplication
16 | public class GitHubMcpApplication {
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(GitHubMcpApplication.class, args);
20 | }
21 |
22 | @Bean
23 | public ToolCallbackProvider mcpServices(IssueService issueService,
24 | PullRequestService pullRequestService,
25 | RepositoryService repositoryService,
26 | BranchService branchService,
27 | CommitService commitService,
28 | ContentService contentService) {
29 | return MethodToolCallbackProvider.builder()
30 | .toolObjects(issueService, pullRequestService, repositoryService, branchService, commitService, contentService)
31 | .build();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/devoxx/agentic/github/tools/AbstractToolService.java:
--------------------------------------------------------------------------------
1 | package com.devoxx.agentic.github.tools;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | public class AbstractToolService {
9 |
10 | protected static final String SUCCESS = "success";
11 | protected static final String ERROR = "error";
12 |
13 | protected final ObjectMapper mapper = new ObjectMapper();
14 |
15 | protected String errorMessage(String errorMessage) {
16 | Map result = new HashMap<>();
17 | result.put(SUCCESS, false);
18 | result.put(ERROR, errorMessage);
19 | try {
20 | return mapper.writeValueAsString(result);
21 | } catch (Exception ex) {
22 | return "{\"success\": false, \"error\": \"Failed to serialize error result\"}";
23 | }
24 | }
25 |
26 | protected String successMessage(Map result) {
27 | result.put(SUCCESS, true);
28 | try {
29 | return mapper.writeValueAsString(result);
30 | } catch (Exception ex) {
31 | return "{\"success\": false, \"error\": \"Failed to serialize success result\"}";
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/devoxx/agentic/github/tools/BranchService.java:
--------------------------------------------------------------------------------
1 | package com.devoxx.agentic.github.tools;
2 |
3 | import org.kohsuke.github.*;
4 | import org.springframework.ai.tool.annotation.Tool;
5 | import org.springframework.ai.tool.annotation.ToolParam;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.io.IOException;
9 | import java.util.*;
10 |
11 | /**
12 | * Service for GitHub branch-related operations
13 | */
14 | @Service
15 | public class BranchService extends AbstractToolService {
16 |
17 | @Tool(description = """
18 | List branches in a repository.
19 | Returns a list of branches with their details.
20 | """)
21 | public String listBranches(
22 | @ToolParam(description = "Repository name in format 'owner/repo'", required = false) String repository,
23 | @ToolParam(description = "Filter branches by prefix", required = false) String filter,
24 | @ToolParam(description = "Maximum number of branches to return", required = false) Integer limit
25 | ) {
26 | Map result = new HashMap<>();
27 |
28 | try {
29 | Optional env = GitHubClientFactory.getEnvironment();
30 | if (env.isEmpty()) {
31 | return errorMessage("GitHub is not configured correctly");
32 | }
33 |
34 | GitHubEnv githubEnv = env.get();
35 | GitHub github = GitHubClientFactory.createClient(githubEnv);
36 |
37 | // Use provided repository or default from environment
38 | String repoName = (repository != null && !repository.isEmpty()) ?
39 | repository : githubEnv.getFullRepository();
40 |
41 | if (repoName == null || repoName.isEmpty()) {
42 | return errorMessage("Repository name is required");
43 | }
44 |
45 | GHRepository repo = github.getRepository(repoName);
46 |
47 | List