Wraps the GitHub CLI (gh) as MCP tools using
mcp-cli, and authenticates gh via a
browser using gh-web-auth — no PAT or
gh auth login device-code copy/paste required.
- gh — official GitHub CLI, installed from GitHub's apt repo.
- gh-web-auth — built from source, runs a small web server (default
0.0.0.0:8080) that performs the GitHub OAuth device flow and writes the resulting token to~/.config/gh/hosts.yml— the exact file/format theghCLI itself reads. - mcp-cli — built from source, started with
ghas the wrapped CLI andmcp-cli-config/gh-config.jsonas its tool definitions, so it exposes typed MCP tools likegh_issue_create,gh_pr_merge,gh_repo_clone,gh_api, etc. instead of one raw passthrough tool. entrypoint.shstartsgh-web-authin the background, then execsmcp-cliin the foreground so it's PID 1 and receives signals.
docker build -t gh-cli-mcp .docker run -it --rm -p 8080:8080 gh-cli-mcpThen open http://localhost:8080 and click Login with GitHub to
complete the device-flow auth. Once authenticated, gh (and every tool
mcp-cli exposes) can talk to the GitHub API.
To persist the token across container restarts, mount a volume over the gh config directory:
docker run -it --rm -p 8080:8080 \
-v gh-cli-mcp-config:/root/.config/gh \
gh-cli-mcpmcp-cli-config/gh-config.json was generated directly from gh --help /
gh <command> <subcommand> --help output of the actual gh CLI v2.96.0
binary (downloaded from cli/cli's GitHub releases and run locally) —
every flag, alias, and positional argument was transcribed from that binary's
own cobra flag registrations, not guessed or reconstructed from memory. It
exposes 137 MCP tools across 27 command groups:
repo: view, list, clone, create, fork, delete, edit, rename, archive, sync, set-defaultissue: list, view, create, edit, close, reopen, comment, delete, pin, unpin, transfer, lock, unlockpr: list, view, create, edit, close, reopen, merge, checkout, diff, review, comment, ready, lock, unlock, checksrelease: list, view, create, edit, delete, download, upload, delete-assetworkflow: list, view, run, enable, disablerun: list, view, watch, cancel, rerun, download, deletegist: list, view, create, edit, delete, clone, renamelabel: list, create, edit, delete, cloneauth: status, login, logout, refresh, token, setup-git, switchsearch: repos, issues, prs, code, commitssecret/variable: list, set, deletessh-key/gpg-key: list, add, deletecache: list, deleteruleset: list, view, checkconfig: get, set, list, clear-cacheextension: list, install, upgrade, remove, create, browseproject: list, view, create, delete, field-list, item-listcodespace: list, view, create, delete, ssh, stop, code, edit, portsdiscussion(preview): list, viewattestation: verify, download, trusted-rootorg list,browse,status,alias: list, set, deleteapi(the generic authenticated-request escape hatch)
Not included: purely meta/interactive commands with no scriptable flags of
their own (gh help, gh completion, gh preview) and CLI-preview
features still gated behind separate opt-in (gh copilot, gh skill,
gh agent-task) — add them the same way if you need them, using
gh <command> --help as the source of truth.
Notes on the mapping to mcp-cli's schema (string / number / boolean
parameter types only, no native arrays):
- gh flags that accept repeated/comma-separated values (e.g.
--label,--topic,--assignee) are modeled as a singlestringparameter — pass a comma-separated list, exactly asghitself accepts. - gh commands that take multiple positional arguments (e.g.
issue edit <numbers>...,gist create <filename>...) are modeled as onestringpositional — pass a space-separated list for the ones that support it. - The
-R/--repo [HOST/]OWNER/REPOflag inherited by most repo-scoped commands is included as arepoparameter on every tool that has it.
Edit mcp-cli-config/gh-config.json to add/remove gh subcommands as MCP
tools — each entry maps a name/subcommand to typed parameters (flags or
positional args), following the format documented in the
mcp-cli README.
Rebuild the image after editing.