gpt-github-max-mcp
by alikhande70
README.md
# gpt-github-max-mcp
<p align="center">
<img src="docs/assets/banner.svg" alt="GPT GitHub Max MCP — maximum practical GitHub control for ChatGPT and MCP clients" width="100%">
</p>
<p align="center">
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"></a>
<a href="https://github.com/alikhande70/gpt-github-max-mcp/actions/workflows/ci.yml"><img src="https://github.com/alikhande70/gpt-github-max-mcp/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-compatible-5A32FB.svg" alt="MCP compatible"></a>
<a href="https://docs.github.com/en/rest"><img src="https://img.shields.io/badge/GitHub%20API-REST%20%2B%20GraphQL-181717.svg" alt="GitHub REST + GraphQL"></a>
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT License"></a>
</p>
An MCP (Model Context Protocol) server that gives ChatGPT — or any MCP
client — **maximum practical control over GitHub** through the official
GitHub REST and GraphQL APIs.
It exposes 22 tools covering repository browsing, file reads/writes,
branches, commits (including multi-file atomic commits via the Git Data
API), issues, pull requests, releases, Actions workflow/repository
dispatch, Actions variables & secrets, and raw REST/GraphQL escape
hatches.
## ⚠️ Warning: this server is as powerful as your token
**This server has no independent safety layer.** It does not add approval
gates, branch protection rules, dry-run modes, or any restriction beyond
what GitHub itself enforces. Every tool call is made directly against the
GitHub API using `GITHUB_TOKEN`:
- If your token can push to `main`, merge PRs, delete files, dispatch
workflows, or read/write secrets — so can this server, without asking
for confirmation first.
- If GitHub denies a request (permissions, rate limits, branch
protection, required reviews, etc.), that denial is returned to the
caller as a clear error. GitHub — not this server — is the source of
truth for what is and isn't allowed.
- Scope `GITHUB_TOKEN` deliberately (see [Suggested token permissions](#suggested-github-fine-grained-token-permissions)
below) and treat it like any other credential with production access.
If you want guardrails (required approvals, protected branches, no direct
pushes to `main`, etc.), configure them on the GitHub side — via branch
protection rules, required reviews, or a token scoped to only what you
want to allow. Do not expect this server to add them for you.
## How it works
<p align="center">
<img src="docs/assets/overview.svg" alt="Architecture overview: a ChatGPT or MCP client talks to the gpt-github-max-mcp FastMCP server over HTTP, scoped entirely by GITHUB_TOKEN, which maps 22 tools onto the GitHub REST and GraphQL API across repositories, branches, commits, pull requests, and Actions" width="100%">
</p>
A client speaks the MCP protocol to this server; the server is a thin,
1:1 bridge onto GitHub's own REST and GraphQL APIs, scoped entirely by
whatever `GITHUB_TOKEN` it's given. Nothing in between adds its own
notion of what's allowed — that's still GitHub's call.
## Quick start
```bash
git clone <this-repo> && cd gpt-github-max-mcp
pip install -e .
cp .env.example .env # then set GITHUB_TOKEN
gpt-github-max-mcp # serves http://127.0.0.1:8000/mcp
```
Then put an HTTPS tunnel in front of it (e.g.
`cloudflared tunnel --url http://127.0.0.1:8000`) and add the resulting
`.../mcp` URL as a connector in ChatGPT. Full walkthrough, including
troubleshooting: **[docs/CONNECT_CHATGPT.md](./docs/CONNECT_CHATGPT.md)**.
The sections below cover each of these steps in detail.
## Requirements
- Python 3.11+
- A GitHub personal access token (fine-grained or classic)
## Installation
```bash
git clone <this-repo>
cd gpt-github-max-mcp
python3 -m venv .venv && source .venv/bin/activate # optional but recommended
pip install -e .
```
This installs the `gpt-github-max-mcp` console command.
## Configuration (`.env`)
Copy the example file and fill in your token:
```bash
cp .env.example .env
```
```dotenv
GITHUB_TOKEN=github_pat_xxxxxxxxxxxxxxxxx
GITHUB_API_BASE=https://api.github.com
GITHUB_GRAPHQL_URL=https://api.github.com/graphql
MCP_HOST=127.0.0.1
MCP_PORT=8000
# Host/Origin allow-lists for the HTTP DNS-rebinding guard. "*" allows any
# Host/Origin header - normally required when exposing through a tunnel.
MCP_ALLOWED_HOSTS=*
MCP_ALLOWED_ORIGINS=*
```
- `GITHUB_API_BASE` / `GITHUB_GRAPHQL_URL` only need to change for GitHub
Enterprise Server.
- `MCP_ALLOWED_HOSTS` / `MCP_ALLOWED_ORIGINS` control FastMCP's built-in
HTTP Host/Origin header guard (a basic network-layer protection, not a
GitHub permission check). Leave as `*` for tunnel use, or restrict to
your tunnel's hostname for tighter local hygiene.
## Running locally
```bash
gpt-github-max-mcp
```
This starts an HTTP MCP server at:
```
http://127.0.0.1:8000/mcp
```
You can point any MCP-compatible client at that URL directly for local
use (e.g. Claude Desktop, Claude Code, local test scripts).
## Exposing it to ChatGPT
ChatGPT connects to MCP servers over HTTPS, so you need to put an HTTPS
endpoint in front of your local server — via Cloudflare Tunnel, ngrok, or a
VPS behind a real reverse proxy. See
**[docs/CONNECT_CHATGPT.md](./docs/CONNECT_CHATGPT.md)** for the full
walkthrough, including adding the connector in ChatGPT and troubleshooting.
In all cases, restrict `MCP_ALLOWED_HOSTS`/`MCP_ALLOWED_ORIGINS` to the
public hostname you're using once you've confirmed it works, rather than
leaving them at `*` indefinitely on a long-running public endpoint.
## Suggested GitHub fine-grained token permissions
Grant only what you intend to use. For full functionality across every
tool in this server:
| Permission | Access level |
|--------------------|-----------------|
| Contents | Read and write |
| Pull requests | Read and write |
| Issues | Read and write |
| Actions | Read and write |
| Workflows | Read and write |
| Secrets | Read and write |
| Variables | Read and write |
| Metadata | Read-only |
| Administration | Read and write (only if you need repo admin operations) |
| Deployments | Read and write (only if you need deployment operations) |
Fine-grained tokens can also be scoped to specific repositories/orgs —
prefer that over an all-repository token when possible. For a full
per-tool permission mapping, classic-scope equivalents, and what each
GitHub error status means, see
**[docs/TOKEN_PERMISSIONS.md](./docs/TOKEN_PERMISSIONS.md)**.
## Optional extras (both off by default)
These are operator conveniences, not safety features — neither changes
what GitHub itself allows the token to do.
### Audit log
Set `AUDIT_LOG=true` (and optionally `AUDIT_LOG_PATH=/path/to/file`, else
it logs to stdout) to record every tool call — name, redacted arguments,
and outcome — for local visibility into what the token was used for.
Secret-bearing fields (e.g. `secret_value`) are always redacted; long
string values are truncated.
### Tool allowlist
Set `MCP_TOOL_ALLOWLIST` to a comma-separated list of tool names (e.g.
`whoami,list_repositories,read_file`) to expose only that subset of tools
to MCP clients. Leave unset to expose all 22 tools (the default).
## Testing
```bash
pip install -e ".[dev]"
pytest
```
The test suite mocks all GitHub HTTP calls (via `httpx.MockTransport`) —
no network access or real token required. For an end-to-end check against
a live server (starts `gpt-github-max-mcp`, connects a real MCP client,
verifies the tool list, and calls `whoami`):
```bash
python scripts/smoke_test.py
```
## Example prompt for ChatGPT
> Use github-max MCP. Run `whoami`, list my repositories, then for
> OWNER/REPO create branch `ai/readme-mvp` from `main`, write a
> professional README.md, commit it, and open a pull request. Do not
> merge.
## Tool documentation
See [TOOLS.md](./TOOLS.md) for the full list of tools, their parameters,
the GitHub API endpoint each one calls, and the permission each requires.
## Further reading
- [docs/CONNECT_CHATGPT.md](./docs/CONNECT_CHATGPT.md) — exposing the
server over HTTPS and wiring it up in ChatGPT
- [docs/TOKEN_PERMISSIONS.md](./docs/TOKEN_PERMISSIONS.md) — per-tool
permission mapping and error-status cheat sheet
- [CHANGELOG.md](./CHANGELOG.md) — release history
## Project structure
```
gpt-github-max-mcp/
├── README.md
├── TOOLS.md
├── CHANGELOG.md
├── LICENSE
├── .env.example
├── .gitignore
├── requirements.txt
├── pyproject.toml
├── docs/
│ ├── CONNECT_CHATGPT.md
│ ├── TOKEN_PERMISSIONS.md
│ └── assets/
│ ├── banner.svg
│ └── overview.svg
├── scripts/
│ └── smoke_test.py # end-to-end check against a live server
├── tests/ # pytest suite (httpx.MockTransport, no network)
├── .github/workflows/
│ └── ci.yml
└── src/
└── gpt_github_max_mcp/
├── __init__.py
├── server.py # FastMCP app + all 22 tool definitions
├── github_client.py # httpx-based GitHub REST/GraphQL client
└── schemas.py # shared Pydantic input models
```
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing