mcp-github-agent 0.1.0__tar.gz
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.
- mcp_github_agent-0.1.0/PKG-INFO +153 -0
- mcp_github_agent-0.1.0/README.md +127 -0
- mcp_github_agent-0.1.0/mcp_github_agent.egg-info/PKG-INFO +153 -0
- mcp_github_agent-0.1.0/mcp_github_agent.egg-info/SOURCES.txt +30 -0
- mcp_github_agent-0.1.0/mcp_github_agent.egg-info/dependency_links.txt +1 -0
- mcp_github_agent-0.1.0/mcp_github_agent.egg-info/entry_points.txt +2 -0
- mcp_github_agent-0.1.0/mcp_github_agent.egg-info/requires.txt +3 -0
- mcp_github_agent-0.1.0/mcp_github_agent.egg-info/top_level.txt +4 -0
- mcp_github_agent-0.1.0/pyproject.toml +43 -0
- mcp_github_agent-0.1.0/setup.cfg +4 -0
- mcp_github_agent-0.1.0/src/__init__.py +0 -0
- mcp_github_agent-0.1.0/src/analyzers/base.py +21 -0
- mcp_github_agent-0.1.0/src/analyzers/ruff.py +49 -0
- mcp_github_agent-0.1.0/src/audit.py +120 -0
- mcp_github_agent-0.1.0/src/config.py +36 -0
- mcp_github_agent-0.1.0/src/diff_parser.py +36 -0
- mcp_github_agent-0.1.0/src/github_client.py +111 -0
- mcp_github_agent-0.1.0/src/main.py +29 -0
- mcp_github_agent-0.1.0/src/policy.py +125 -0
- mcp_github_agent-0.1.0/src/review.py +107 -0
- mcp_github_agent-0.1.0/src/review_engine.py +83 -0
- mcp_github_agent-0.1.0/src/tools.py +291 -0
- mcp_github_agent-0.1.0/tests/__init__.py +0 -0
- mcp_github_agent-0.1.0/tests/test_audit.py +181 -0
- mcp_github_agent-0.1.0/tests/test_config.py +41 -0
- mcp_github_agent-0.1.0/tests/test_diff_parser.py +74 -0
- mcp_github_agent-0.1.0/tests/test_github_client.py +173 -0
- mcp_github_agent-0.1.0/tests/test_main.py +48 -0
- mcp_github_agent-0.1.0/tests/test_policy.py +133 -0
- mcp_github_agent-0.1.0/tests/test_review_engine.py +162 -0
- mcp_github_agent-0.1.0/tests/test_ruff_analyzer.py +78 -0
- mcp_github_agent-0.1.0/tests/test_tools.py +326 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-github-agent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server giving AI agents controlled GitHub access with policy guard and audit trail
|
|
5
|
+
Author-email: Morgan Fu <maogenfu0121@163.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/FMorgan-111/github-mcp-server
|
|
8
|
+
Project-URL: Repository, https://github.com/FMorgan-111/github-mcp-server
|
|
9
|
+
Project-URL: Issues, https://github.com/FMorgan-111/github-mcp-server/issues
|
|
10
|
+
Keywords: mcp,github,ai-agent,claude-code,codex,policy,audit
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: fastmcp
|
|
24
|
+
Requires-Dist: httpx
|
|
25
|
+
Requires-Dist: python-dotenv
|
|
26
|
+
|
|
27
|
+
# GitHub MCP Agent Server
|
|
28
|
+
|
|
29
|
+
[](https://github.com/FMorgan-111/github-mcp-server/actions/workflows/ci.yml)
|
|
30
|
+
[](https://www.python.org/downloads/release/python-3100/)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
|
|
33
|
+
> MCP server giving AI agents controlled GitHub access with policy guard and audit trail.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
┌───────────────┐ MCP stdio ┌───────────────────┐
|
|
41
|
+
│ AI Agent │ ◄──────────────────────► │ GitHub MCP Server │
|
|
42
|
+
│ (Claude, Codex│ JSON-RPC 2.0 │ │
|
|
43
|
+
│ or any MCP │ ┌─┴───────────────┐ │
|
|
44
|
+
│ client) │ │ Policy Guard │ │
|
|
45
|
+
└───────────────┘ ├─────────────────┤ │
|
|
46
|
+
│ Audit Log │ │
|
|
47
|
+
└─────────────────┘ │
|
|
48
|
+
┌──────────────────────────────────────────────┐ │
|
|
49
|
+
│ github_client.py │ │
|
|
50
|
+
│ (httpx) │ │
|
|
51
|
+
│ GitHub API │ │
|
|
52
|
+
└──────────────────────────────────────────────┘ │
|
|
53
|
+
┌──────────────────────────────────────────────┐ │
|
|
54
|
+
│ Review Engine (ruff + regex) │ │
|
|
55
|
+
└──────────────────────────────────────────────┘ │
|
|
56
|
+
└───┘
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Features & Tools
|
|
62
|
+
|
|
63
|
+
| Tool | Description | Example Input | Example Output |
|
|
64
|
+
|-------------------|--------------------------------------------|-------------------------------------------------------------------------------|---------------------------------------------|
|
|
65
|
+
| `search_code` | Search GitHub repo code by query | `search_code("def main", "owner/repo")` | List of matching files with paths & URLs |
|
|
66
|
+
| `list_issues` | List open or closed issues | `list_issues("owner/repo", state="open")` | Formatted list of issues |
|
|
67
|
+
| `create_issue` | Create a new issue (policy-guarded) | `create_issue("owner/repo", "Bug: timeout", "Steps to reproduce...")` | Confirmation with issue URL |
|
|
68
|
+
| `get_pr_diff` | Fetch raw diff of a pull request | `get_pr_diff("owner/repo", pr_number=7)` | Unified diff as text |
|
|
69
|
+
| `create_pr` | Create a pull request between branches | `create_pr("owner/repo", "Add feature", "Details...", head="feat", base="main")` | Confirmation with PR URL |
|
|
70
|
+
| `review_pr_diff` | Run local automated code review rules | `review_pr_diff("owner/repo", pr_number=7)` | List of warnings and errors found |
|
|
71
|
+
| `comment_pr_review`| Post review findings as PR comments | `comment_pr_review("owner/repo", pr_number=7)` | Number of comments posted |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Security Model
|
|
76
|
+
|
|
77
|
+
- **Repository Allowlist:** Only repositories explicitly allowed by policy can be accessed.
|
|
78
|
+
- **Branch Protection:** PRs to protected branches are subject to branch protection rules before merging.
|
|
79
|
+
- **Dry-Run Mode:** Execute operations without side effects for safe testing and auditing.
|
|
80
|
+
- **Audit Logging:** All actions logged in JSONL format with precise timestamps to maintain traceability.
|
|
81
|
+
- **Policy Configuration:** Start from `policy.example.json` to configure repository allowlists and protected branches.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## FAQ
|
|
86
|
+
|
|
87
|
+
**Why not call the GitHub API directly?**
|
|
88
|
+
Direct API calls lack centralized policy enforcement, audit logging, and uniform tooling support for AI agents. This MCP server adds a controlled, auditable layer for safer automation.
|
|
89
|
+
|
|
90
|
+
**What MCP clients work with this?**
|
|
91
|
+
Agents like Claude Code, OpenAI Codex, and any client supporting the MCP JSON-RPC 2.0 transport can connect to this server.
|
|
92
|
+
|
|
93
|
+
**How is this different from the official GitHub MCP server?**
|
|
94
|
+
This project's key differentiator is policy enforcement. Repository allowlists prevent agents from touching unauthorized repos, branch protection blocks accidental PRs to sensitive branches, dry-run mode supports safe validation, and write actions are audit-logged with timestamps.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
### Prerequisites
|
|
101
|
+
|
|
102
|
+
- Python 3.10+
|
|
103
|
+
- GitHub personal access token with `repo` scope
|
|
104
|
+
|
|
105
|
+
### Install
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pip install fastmcp httpx python-dotenv
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Configure and Run
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git clone https://github.com/FMorgan-111/github-mcp-server.git
|
|
115
|
+
cd github-mcp-server
|
|
116
|
+
cp .env.example .env && nano .env
|
|
117
|
+
python3 -m src.main
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Connect with Claude Code
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
claude mcp add github-agent -- python3 /path/to/github-mcp-server/src/main.py
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Development
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pip install -e . --break-system-packages
|
|
132
|
+
python3 -m pytest tests/ -v
|
|
133
|
+
python3 -m src.main
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
23 tests, all passing.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Deployment with Docker
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
docker build -t github-mcp-server .
|
|
144
|
+
docker run -e GITHUB_TOKEN=ghp_your_token_here -i github-mcp-server
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The `-e GITHUB_TOKEN=...` flag passes the token into the container because the local `.env` file is not copied into the image.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# GitHub MCP Agent Server
|
|
2
|
+
|
|
3
|
+
[](https://github.com/FMorgan-111/github-mcp-server/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.python.org/downloads/release/python-3100/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
> MCP server giving AI agents controlled GitHub access with policy guard and audit trail.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌───────────────┐ MCP stdio ┌───────────────────┐
|
|
15
|
+
│ AI Agent │ ◄──────────────────────► │ GitHub MCP Server │
|
|
16
|
+
│ (Claude, Codex│ JSON-RPC 2.0 │ │
|
|
17
|
+
│ or any MCP │ ┌─┴───────────────┐ │
|
|
18
|
+
│ client) │ │ Policy Guard │ │
|
|
19
|
+
└───────────────┘ ├─────────────────┤ │
|
|
20
|
+
│ Audit Log │ │
|
|
21
|
+
└─────────────────┘ │
|
|
22
|
+
┌──────────────────────────────────────────────┐ │
|
|
23
|
+
│ github_client.py │ │
|
|
24
|
+
│ (httpx) │ │
|
|
25
|
+
│ GitHub API │ │
|
|
26
|
+
└──────────────────────────────────────────────┘ │
|
|
27
|
+
┌──────────────────────────────────────────────┐ │
|
|
28
|
+
│ Review Engine (ruff + regex) │ │
|
|
29
|
+
└──────────────────────────────────────────────┘ │
|
|
30
|
+
└───┘
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Features & Tools
|
|
36
|
+
|
|
37
|
+
| Tool | Description | Example Input | Example Output |
|
|
38
|
+
|-------------------|--------------------------------------------|-------------------------------------------------------------------------------|---------------------------------------------|
|
|
39
|
+
| `search_code` | Search GitHub repo code by query | `search_code("def main", "owner/repo")` | List of matching files with paths & URLs |
|
|
40
|
+
| `list_issues` | List open or closed issues | `list_issues("owner/repo", state="open")` | Formatted list of issues |
|
|
41
|
+
| `create_issue` | Create a new issue (policy-guarded) | `create_issue("owner/repo", "Bug: timeout", "Steps to reproduce...")` | Confirmation with issue URL |
|
|
42
|
+
| `get_pr_diff` | Fetch raw diff of a pull request | `get_pr_diff("owner/repo", pr_number=7)` | Unified diff as text |
|
|
43
|
+
| `create_pr` | Create a pull request between branches | `create_pr("owner/repo", "Add feature", "Details...", head="feat", base="main")` | Confirmation with PR URL |
|
|
44
|
+
| `review_pr_diff` | Run local automated code review rules | `review_pr_diff("owner/repo", pr_number=7)` | List of warnings and errors found |
|
|
45
|
+
| `comment_pr_review`| Post review findings as PR comments | `comment_pr_review("owner/repo", pr_number=7)` | Number of comments posted |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Security Model
|
|
50
|
+
|
|
51
|
+
- **Repository Allowlist:** Only repositories explicitly allowed by policy can be accessed.
|
|
52
|
+
- **Branch Protection:** PRs to protected branches are subject to branch protection rules before merging.
|
|
53
|
+
- **Dry-Run Mode:** Execute operations without side effects for safe testing and auditing.
|
|
54
|
+
- **Audit Logging:** All actions logged in JSONL format with precise timestamps to maintain traceability.
|
|
55
|
+
- **Policy Configuration:** Start from `policy.example.json` to configure repository allowlists and protected branches.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## FAQ
|
|
60
|
+
|
|
61
|
+
**Why not call the GitHub API directly?**
|
|
62
|
+
Direct API calls lack centralized policy enforcement, audit logging, and uniform tooling support for AI agents. This MCP server adds a controlled, auditable layer for safer automation.
|
|
63
|
+
|
|
64
|
+
**What MCP clients work with this?**
|
|
65
|
+
Agents like Claude Code, OpenAI Codex, and any client supporting the MCP JSON-RPC 2.0 transport can connect to this server.
|
|
66
|
+
|
|
67
|
+
**How is this different from the official GitHub MCP server?**
|
|
68
|
+
This project's key differentiator is policy enforcement. Repository allowlists prevent agents from touching unauthorized repos, branch protection blocks accidental PRs to sensitive branches, dry-run mode supports safe validation, and write actions are audit-logged with timestamps.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Quick Start
|
|
73
|
+
|
|
74
|
+
### Prerequisites
|
|
75
|
+
|
|
76
|
+
- Python 3.10+
|
|
77
|
+
- GitHub personal access token with `repo` scope
|
|
78
|
+
|
|
79
|
+
### Install
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install fastmcp httpx python-dotenv
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Configure and Run
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/FMorgan-111/github-mcp-server.git
|
|
89
|
+
cd github-mcp-server
|
|
90
|
+
cp .env.example .env && nano .env
|
|
91
|
+
python3 -m src.main
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Connect with Claude Code
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
claude mcp add github-agent -- python3 /path/to/github-mcp-server/src/main.py
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Development
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pip install -e . --break-system-packages
|
|
106
|
+
python3 -m pytest tests/ -v
|
|
107
|
+
python3 -m src.main
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
23 tests, all passing.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Deployment with Docker
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
docker build -t github-mcp-server .
|
|
118
|
+
docker run -e GITHUB_TOKEN=ghp_your_token_here -i github-mcp-server
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The `-e GITHUB_TOKEN=...` flag passes the token into the container because the local `.env` file is not copied into the image.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-github-agent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server giving AI agents controlled GitHub access with policy guard and audit trail
|
|
5
|
+
Author-email: Morgan Fu <maogenfu0121@163.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/FMorgan-111/github-mcp-server
|
|
8
|
+
Project-URL: Repository, https://github.com/FMorgan-111/github-mcp-server
|
|
9
|
+
Project-URL: Issues, https://github.com/FMorgan-111/github-mcp-server/issues
|
|
10
|
+
Keywords: mcp,github,ai-agent,claude-code,codex,policy,audit
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: fastmcp
|
|
24
|
+
Requires-Dist: httpx
|
|
25
|
+
Requires-Dist: python-dotenv
|
|
26
|
+
|
|
27
|
+
# GitHub MCP Agent Server
|
|
28
|
+
|
|
29
|
+
[](https://github.com/FMorgan-111/github-mcp-server/actions/workflows/ci.yml)
|
|
30
|
+
[](https://www.python.org/downloads/release/python-3100/)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
|
|
33
|
+
> MCP server giving AI agents controlled GitHub access with policy guard and audit trail.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
┌───────────────┐ MCP stdio ┌───────────────────┐
|
|
41
|
+
│ AI Agent │ ◄──────────────────────► │ GitHub MCP Server │
|
|
42
|
+
│ (Claude, Codex│ JSON-RPC 2.0 │ │
|
|
43
|
+
│ or any MCP │ ┌─┴───────────────┐ │
|
|
44
|
+
│ client) │ │ Policy Guard │ │
|
|
45
|
+
└───────────────┘ ├─────────────────┤ │
|
|
46
|
+
│ Audit Log │ │
|
|
47
|
+
└─────────────────┘ │
|
|
48
|
+
┌──────────────────────────────────────────────┐ │
|
|
49
|
+
│ github_client.py │ │
|
|
50
|
+
│ (httpx) │ │
|
|
51
|
+
│ GitHub API │ │
|
|
52
|
+
└──────────────────────────────────────────────┘ │
|
|
53
|
+
┌──────────────────────────────────────────────┐ │
|
|
54
|
+
│ Review Engine (ruff + regex) │ │
|
|
55
|
+
└──────────────────────────────────────────────┘ │
|
|
56
|
+
└───┘
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Features & Tools
|
|
62
|
+
|
|
63
|
+
| Tool | Description | Example Input | Example Output |
|
|
64
|
+
|-------------------|--------------------------------------------|-------------------------------------------------------------------------------|---------------------------------------------|
|
|
65
|
+
| `search_code` | Search GitHub repo code by query | `search_code("def main", "owner/repo")` | List of matching files with paths & URLs |
|
|
66
|
+
| `list_issues` | List open or closed issues | `list_issues("owner/repo", state="open")` | Formatted list of issues |
|
|
67
|
+
| `create_issue` | Create a new issue (policy-guarded) | `create_issue("owner/repo", "Bug: timeout", "Steps to reproduce...")` | Confirmation with issue URL |
|
|
68
|
+
| `get_pr_diff` | Fetch raw diff of a pull request | `get_pr_diff("owner/repo", pr_number=7)` | Unified diff as text |
|
|
69
|
+
| `create_pr` | Create a pull request between branches | `create_pr("owner/repo", "Add feature", "Details...", head="feat", base="main")` | Confirmation with PR URL |
|
|
70
|
+
| `review_pr_diff` | Run local automated code review rules | `review_pr_diff("owner/repo", pr_number=7)` | List of warnings and errors found |
|
|
71
|
+
| `comment_pr_review`| Post review findings as PR comments | `comment_pr_review("owner/repo", pr_number=7)` | Number of comments posted |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Security Model
|
|
76
|
+
|
|
77
|
+
- **Repository Allowlist:** Only repositories explicitly allowed by policy can be accessed.
|
|
78
|
+
- **Branch Protection:** PRs to protected branches are subject to branch protection rules before merging.
|
|
79
|
+
- **Dry-Run Mode:** Execute operations without side effects for safe testing and auditing.
|
|
80
|
+
- **Audit Logging:** All actions logged in JSONL format with precise timestamps to maintain traceability.
|
|
81
|
+
- **Policy Configuration:** Start from `policy.example.json` to configure repository allowlists and protected branches.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## FAQ
|
|
86
|
+
|
|
87
|
+
**Why not call the GitHub API directly?**
|
|
88
|
+
Direct API calls lack centralized policy enforcement, audit logging, and uniform tooling support for AI agents. This MCP server adds a controlled, auditable layer for safer automation.
|
|
89
|
+
|
|
90
|
+
**What MCP clients work with this?**
|
|
91
|
+
Agents like Claude Code, OpenAI Codex, and any client supporting the MCP JSON-RPC 2.0 transport can connect to this server.
|
|
92
|
+
|
|
93
|
+
**How is this different from the official GitHub MCP server?**
|
|
94
|
+
This project's key differentiator is policy enforcement. Repository allowlists prevent agents from touching unauthorized repos, branch protection blocks accidental PRs to sensitive branches, dry-run mode supports safe validation, and write actions are audit-logged with timestamps.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
### Prerequisites
|
|
101
|
+
|
|
102
|
+
- Python 3.10+
|
|
103
|
+
- GitHub personal access token with `repo` scope
|
|
104
|
+
|
|
105
|
+
### Install
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pip install fastmcp httpx python-dotenv
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Configure and Run
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git clone https://github.com/FMorgan-111/github-mcp-server.git
|
|
115
|
+
cd github-mcp-server
|
|
116
|
+
cp .env.example .env && nano .env
|
|
117
|
+
python3 -m src.main
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Connect with Claude Code
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
claude mcp add github-agent -- python3 /path/to/github-mcp-server/src/main.py
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Development
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pip install -e . --break-system-packages
|
|
132
|
+
python3 -m pytest tests/ -v
|
|
133
|
+
python3 -m src.main
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
23 tests, all passing.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Deployment with Docker
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
docker build -t github-mcp-server .
|
|
144
|
+
docker run -e GITHUB_TOKEN=ghp_your_token_here -i github-mcp-server
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The `-e GITHUB_TOKEN=...` flag passes the token into the container because the local `.env` file is not copied into the image.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
mcp_github_agent.egg-info/PKG-INFO
|
|
4
|
+
mcp_github_agent.egg-info/SOURCES.txt
|
|
5
|
+
mcp_github_agent.egg-info/dependency_links.txt
|
|
6
|
+
mcp_github_agent.egg-info/entry_points.txt
|
|
7
|
+
mcp_github_agent.egg-info/requires.txt
|
|
8
|
+
mcp_github_agent.egg-info/top_level.txt
|
|
9
|
+
src/__init__.py
|
|
10
|
+
src/audit.py
|
|
11
|
+
src/config.py
|
|
12
|
+
src/diff_parser.py
|
|
13
|
+
src/github_client.py
|
|
14
|
+
src/main.py
|
|
15
|
+
src/policy.py
|
|
16
|
+
src/review.py
|
|
17
|
+
src/review_engine.py
|
|
18
|
+
src/tools.py
|
|
19
|
+
src/analyzers/base.py
|
|
20
|
+
src/analyzers/ruff.py
|
|
21
|
+
tests/__init__.py
|
|
22
|
+
tests/test_audit.py
|
|
23
|
+
tests/test_config.py
|
|
24
|
+
tests/test_diff_parser.py
|
|
25
|
+
tests/test_github_client.py
|
|
26
|
+
tests/test_main.py
|
|
27
|
+
tests/test_policy.py
|
|
28
|
+
tests/test_review_engine.py
|
|
29
|
+
tests/test_ruff_analyzer.py
|
|
30
|
+
tests/test_tools.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mcp-github-agent"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server giving AI agents controlled GitHub access with policy guard and audit trail"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Morgan Fu", email = "maogenfu0121@163.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["mcp", "github", "ai-agent", "claude-code", "codex", "policy", "audit"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
26
|
+
"Topic :: Software Development :: Version Control :: Git",
|
|
27
|
+
]
|
|
28
|
+
dependencies = [
|
|
29
|
+
"fastmcp",
|
|
30
|
+
"httpx",
|
|
31
|
+
"python-dotenv",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://github.com/FMorgan-111/github-mcp-server"
|
|
36
|
+
Repository = "https://github.com/FMorgan-111/github-mcp-server"
|
|
37
|
+
Issues = "https://github.com/FMorgan-111/github-mcp-server/issues"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
github-mcp = "src.main:main"
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["."]
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Analyzer protocol — pluggable code analysis backends."""
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Protocol
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class Finding:
|
|
8
|
+
severity: str # "error" | "warning" | "info"
|
|
9
|
+
file: str
|
|
10
|
+
line: int
|
|
11
|
+
rule: str # e.g. "F401", "E501"
|
|
12
|
+
message: str
|
|
13
|
+
suggestion: str = ""
|
|
14
|
+
source: str = "" # "ruff", "bandit", "regex"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Analyzer(Protocol):
|
|
18
|
+
"""Any backend that takes file path → list of Findings."""
|
|
19
|
+
|
|
20
|
+
def analyze(self, file_path: str) -> list[Finding]:
|
|
21
|
+
...
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Ruff subprocess analyzer — run ruff check as JSON, return Findings."""
|
|
2
|
+
import json
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from .base import Finding
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RuffAnalyzer:
|
|
10
|
+
"""Run ruff check on a file, return structured findings."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, ruff_cmd: str = "ruff"):
|
|
13
|
+
self.cmd = ruff_cmd
|
|
14
|
+
|
|
15
|
+
def analyze(self, file_path: str) -> list[Finding]:
|
|
16
|
+
path = Path(file_path)
|
|
17
|
+
if path.suffix != ".py":
|
|
18
|
+
return []
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
result = subprocess.run(
|
|
22
|
+
[self.cmd, "check", "--output-format", "json", str(path)],
|
|
23
|
+
capture_output=True,
|
|
24
|
+
text=True,
|
|
25
|
+
timeout=30,
|
|
26
|
+
)
|
|
27
|
+
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
28
|
+
return []
|
|
29
|
+
|
|
30
|
+
if result.returncode not in (0, 1):
|
|
31
|
+
return [] # ruff crash / config error? skip
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
violations = json.loads(result.stdout or "[]")
|
|
35
|
+
except json.JSONDecodeError:
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
findings = []
|
|
39
|
+
for v in violations:
|
|
40
|
+
findings.append(Finding(
|
|
41
|
+
severity="error" if v.get("fix") else "warning",
|
|
42
|
+
file=v.get("filename", str(path)),
|
|
43
|
+
line=v.get("location", {}).get("row", 0),
|
|
44
|
+
rule=v.get("code", ""),
|
|
45
|
+
message=v.get("message", ""),
|
|
46
|
+
suggestion=v.get("fix", {}).get("message", ""),
|
|
47
|
+
source="ruff",
|
|
48
|
+
))
|
|
49
|
+
return findings
|