raja_github_mcp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
github_mcp/__init__.py ADDED
File without changes
@@ -0,0 +1,13 @@
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ load_dotenv()
5
+
6
+ TOKEN = os.getenv("GITHUB_TOKEN")
7
+
8
+ HEADERS = {
9
+ "Authorization": f"Bearer {TOKEN}",
10
+ "Accept": "application/vnd.github+json"
11
+ }
12
+
13
+ BASE_URL = "https://api.github.com"
github_mcp/main.py ADDED
@@ -0,0 +1,7 @@
1
+ #from github_mcp.tools import mcp # write this when you are deploying
2
+ from .tools import mcp
3
+ def main():
4
+ print("Starting GitHub MCP...")
5
+ mcp.run(transport="stdio")
6
+ if __name__ == "__main__":
7
+ main()
github_mcp/test.py ADDED
@@ -0,0 +1,2 @@
1
+
2
+
github_mcp/tools.py ADDED
@@ -0,0 +1,324 @@
1
+ from fastmcp import FastMCP
2
+ from .github_client import HEADERS, BASE_URL
3
+ import requests
4
+ mcp = FastMCP()
5
+
6
+ @mcp.tool()
7
+ def list_repositories():
8
+ '''Returns all repositories of authenticated GitHUB user'''
9
+
10
+ responce = requests.get(
11
+ f"{BASE_URL}/user/repos",
12
+ headers = HEADERS
13
+ )
14
+ if responce.status_code !=200:
15
+ return f"Error : {responce.status_code}"
16
+ repos = []
17
+
18
+ for repo in responce.json():
19
+
20
+ repos.append({
21
+ "name": repo["name"],
22
+ "url": repo["html_url"],
23
+ "visibility": "Private" if repo["private"] else "Public"
24
+ })
25
+
26
+ return repos
27
+
28
+
29
+ @mcp.tool()
30
+ def list_issues(owner:str, repo:str):
31
+ '''Returns all the issues of the user repository'''
32
+
33
+ responce =requests.get(
34
+ f"{BASE_URL}/repos/{owner}/{repo}/issues",
35
+ headers = HEADERS
36
+ )
37
+ if responce.status_code != 200:
38
+ return f"Error:{responce.status_code}"
39
+
40
+ issues =[]
41
+ for issue in responce.json():
42
+ if "pull_request" in issue:
43
+ continue
44
+
45
+ issues.append({
46
+ "id" :issue["id"],
47
+ "state":issue["state"],
48
+ "title":issue["title"],
49
+ "body":issue["body"],
50
+ "url":issue["html_url"]
51
+ })
52
+
53
+ return issues
54
+
55
+ @mcp.tool()
56
+ def create_issue(owner:str, repo:str, title:str, body:str):
57
+ "This function Creates an issue with title and body in the repository of the owner"
58
+
59
+ issue={"title":title,"body":body}
60
+ responce = requests.post(
61
+ f"{BASE_URL}/repos/{owner}/{repo}/issues",
62
+ json=issue,
63
+ headers=HEADERS
64
+ )
65
+ if responce.status_code != 201:
66
+ return {
67
+ "status": responce.status_code,
68
+ "error": responce.json()
69
+ }
70
+ return {
71
+ "message": "Issue created successfully",
72
+ "issue_url": responce.json()["html_url"]
73
+ }
74
+
75
+ @mcp.tool()
76
+ def close_issue(owner:str,repo:str,issue_number:int):
77
+ '''This function will close the issue using the issue number'''
78
+ update={"state":"closed"}
79
+ responce = requests.patch(
80
+ f"{BASE_URL}/repos/{owner}/{repo}/issues/{issue_number}",
81
+ json=update,
82
+ headers=HEADERS
83
+ )
84
+ if responce.status_code != 200:
85
+ return {
86
+ "status": responce.status_code,
87
+ "error": responce.json()
88
+ }
89
+ return {
90
+ "message": "Issue closed successfully",
91
+ "issue_url": responce.json()["html_url"]
92
+ }
93
+
94
+ @mcp.tool()
95
+ def reopen_issue(owner:str,repo:str,issue_number:int):
96
+ '''This function will reopen the issue using the issue number'''
97
+
98
+
99
+ update={"state":"open"}
100
+ responce = requests.patch(
101
+ f"{BASE_URL}/repos/{owner}/{repo}/issues/{issue_number}",
102
+ json=update,
103
+ headers=HEADERS
104
+ )
105
+ if responce.status_code != 200:
106
+ return {
107
+ "status": responce.status_code,
108
+ "error": responce.json()
109
+ }
110
+ return {
111
+ "message": "Issue reopened successfully",
112
+ "issue_url": responce.json()["html_url"]
113
+ }
114
+
115
+ @mcp.tool()
116
+ def comment_on_issue(owner:str,repo:str,issue_number:int,comment:str):
117
+ '''This function will create a comment on the issue using the issue number'''
118
+
119
+
120
+ comment={"body":comment}
121
+ responce = requests.post(
122
+ f"{BASE_URL}/repos/{owner}/{repo}/issues/{issue_number}/comments",
123
+ json=comment,
124
+ headers=HEADERS
125
+ )
126
+ if responce.status_code != 201:
127
+ return {
128
+ "status": responce.status_code,
129
+ "error": responce.json()
130
+ }
131
+ return {
132
+ "message": "Comment added successfully",
133
+ "issue_url": responce.json()["html_url"]
134
+ }
135
+
136
+
137
+ @mcp.tool()
138
+ def get_repository_details(owner:str,repo:str):
139
+ '''Returns the details of repository with repository name'''
140
+
141
+ responce = requests.get(
142
+ f"{BASE_URL}/repos/{owner}/{repo}",
143
+ headers = HEADERS
144
+ )
145
+ if responce.status_code !=200:
146
+ return {
147
+ "status": responce.status_code,
148
+ "error": responce.json()
149
+ }
150
+ repo_data = responce.json()
151
+
152
+
153
+
154
+
155
+ return{
156
+ "name": repo_data["name"],
157
+ "full_name": repo_data["full_name"],
158
+ "description": repo_data["description"],
159
+ "url": repo_data["html_url"],
160
+ "visibility": "Private" if repo_data["private"] else "Public",
161
+ "default_branch": repo_data["default_branch"],
162
+ "language": repo_data["language"],
163
+ "stars": repo_data["stargazers_count"],
164
+ "forks": repo_data["forks_count"],
165
+ "open_issues": repo_data["open_issues_count"],
166
+ "created_at": repo_data["created_at"],
167
+ "updated_at": repo_data["updated_at"],
168
+ "clone_url": repo_data["clone_url"]
169
+ }
170
+
171
+ @mcp.tool()
172
+ def create_repository(name:str,description:str,private:bool,auto_init:bool):
173
+ '''Use this tool to create a repository'''
174
+
175
+ responce = requests.post(
176
+ f"{BASE_URL}/user/repos",
177
+ json={"name":name,"description":description,"private":private,"auto_init":auto_init},
178
+ headers = HEADERS
179
+ )
180
+ if responce.status_code!=201:
181
+ return {
182
+ "status": responce.status_code,
183
+ "error": responce.json()
184
+ }
185
+ else:
186
+ return{
187
+ "message":"Repository Created Successfully",
188
+ "issue_url":responce.json()['html_url'],
189
+ "clone_url": responce.json()["clone_url"]
190
+ }
191
+ @mcp.tool()
192
+ def list_branches(owner: str, repo: str):
193
+ """Returns all branches of a repository."""
194
+
195
+ response = requests.get(
196
+ f"{BASE_URL}/repos/{owner}/{repo}/branches",
197
+ headers=HEADERS
198
+ )
199
+
200
+ if response.status_code != 200:
201
+ return {
202
+ "status": response.status_code,
203
+ "error": response.json()
204
+ }
205
+
206
+ branches = []
207
+
208
+ for branch in response.json():
209
+ branches.append({
210
+ "name": branch["name"],
211
+ "protected": branch["protected"]
212
+ })
213
+
214
+ return branches
215
+
216
+ @mcp.tool()
217
+ def create_branch(owner: str, repo: str, branch_name: str):
218
+ """Creates a new branch."""
219
+
220
+ repo_response = requests.get(
221
+ f"{BASE_URL}/repos/{owner}/{repo}",
222
+ headers=HEADERS
223
+ )
224
+
225
+ if repo_response.status_code != 200:
226
+ return {
227
+ "status": repo_response.status_code,
228
+ "error": repo_response.json()
229
+ }
230
+
231
+ default_branch = repo_response.json()["default_branch"]
232
+
233
+ sha_response = requests.get(
234
+ f"{BASE_URL}/repos/{owner}/{repo}/git/ref/heads/{default_branch}",
235
+ headers=HEADERS
236
+ )
237
+
238
+ if sha_response.status_code != 200:
239
+ return {
240
+ "status": sha_response.status_code,
241
+ "error": sha_response.json()
242
+ }
243
+
244
+ sha = sha_response.json()["object"]["sha"]
245
+
246
+ create_response = requests.post(
247
+ f"{BASE_URL}/repos/{owner}/{repo}/git/refs",
248
+ json={
249
+ "ref": f"refs/heads/{branch_name}",
250
+ "sha": sha
251
+ },
252
+ headers=HEADERS
253
+ )
254
+
255
+ if create_response.status_code != 201:
256
+ return {
257
+ "status": create_response.status_code,
258
+ "error": create_response.json()
259
+ }
260
+
261
+ return {
262
+ "message": "Branch created successfully",
263
+ "branch": branch_name
264
+ }
265
+
266
+ @mcp.tool()
267
+ def list_pull_requests(owner: str, repo: str):
268
+ """Returns all pull requests."""
269
+
270
+ response = requests.get(
271
+ f"{BASE_URL}/repos/{owner}/{repo}/pulls",
272
+ headers=HEADERS
273
+ )
274
+
275
+ if response.status_code != 200:
276
+ return {
277
+ "status": response.status_code,
278
+ "error": response.json()
279
+ }
280
+
281
+ prs = []
282
+
283
+ for pr in response.json():
284
+ prs.append({
285
+ "number": pr["number"],
286
+ "title": pr["title"],
287
+ "state": pr["state"],
288
+ "url": pr["html_url"]
289
+ })
290
+
291
+ return prs
292
+
293
+ @mcp.tool()
294
+ def create_pull_request(
295
+ owner: str,
296
+ repo: str,
297
+ title: str,
298
+ body: str,
299
+ head: str,
300
+ base: str
301
+ ):
302
+ """Creates a pull request."""
303
+
304
+ response = requests.post(
305
+ f"{BASE_URL}/repos/{owner}/{repo}/pulls",
306
+ json={
307
+ "title": title,
308
+ "body": body,
309
+ "head": head,
310
+ "base": base
311
+ },
312
+ headers=HEADERS
313
+ )
314
+
315
+ if response.status_code != 201:
316
+ return {
317
+ "status": response.status_code,
318
+ "error": response.json()
319
+ }
320
+
321
+ return {
322
+ "message": "Pull request created successfully",
323
+ "pr_url": response.json()["html_url"]
324
+ }
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: raja_github_mcp
3
+ Version: 0.1.0
4
+ Summary: An MCP server for GitHub repository, issue, branch, and pull request management.
5
+ Author: Anna Vamsi Krishna Raja
6
+ Keywords: mcp,model-context-protocol,github,ai-agent,fastmcp
7
+ Requires-Python: >=3.13
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: fastmcp>=3.4.2
10
+ Requires-Dist: requests
11
+ Requires-Dist: python-dotenv
@@ -0,0 +1,10 @@
1
+ github_mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ github_mcp/github_client.py,sha256=C5Mhz4956As_txwrYf-w2fAcW3u5LM3ghz5ggQJnHj4,226
3
+ github_mcp/main.py,sha256=vfXFP-aInBuaudQk0YpkJlrnSxIa1lAKLISt3HsaCoM,212
4
+ github_mcp/test.py,sha256=daEdpEyAJIa8b2VkCqSKcw8PaExcB6Qro80XNes_sHA,2
5
+ github_mcp/tools.py,sha256=JyEaZUWGnbB0WrNxPYVV6pjW9mlpMQaPa_X8NqYSifo,8458
6
+ raja_github_mcp-0.1.0.dist-info/METADATA,sha256=Bk665Qnd8_UHvJSMmoGXMH2npPsFlS1qKDh7xqFbptY,389
7
+ raja_github_mcp-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
8
+ raja_github_mcp-0.1.0.dist-info/entry_points.txt,sha256=xxTejNUu9JW0uO-s7RB6woQ1b7lnLW0YjzcvQNeVyzc,52
9
+ raja_github_mcp-0.1.0.dist-info/top_level.txt,sha256=Oz7KcY8SwRmG0rRos2vB8LycqcG5vapSkveK8aqQi0Q,11
10
+ raja_github_mcp-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ github-mcp = github_mcp.main:main
@@ -0,0 +1 @@
1
+ github_mcp