ghcli-mcp-connector
by FerhatDundar
README.md
<div align="center">
# π ghcli-mcp-connector
**Talk to the GitHub CLI (`gh`) from an MCP-speaking agent.**
[](https://github.com/FerhatDundar/ghcli-mcp-connector/actions/workflows/ci.yml)
[](https://github.com/FerhatDundar/ghcli-mcp-connector/actions/workflows/codeql.yml)
[](https://github.com/FerhatDundar/ghcli-mcp-connector/releases/latest)
[](https://registry.modelcontextprotocol.io/?q=ghcli-mcp-connector)
[](https://go.dev/)
[](LICENSE)
[](https://modelcontextprotocol.io/)
[](https://www.conventionalcommits.org/)
[](CONTRIBUTING.md)
</div>
---
A single static Go binary that speaks the [Model Context Protocol](https://modelcontextprotocol.io/)
and lets an agent run GitHub CLI commands: any `gh <command> <subcommand>`
invocation β `repo`, `issue`, `pr`, `release`, `gist`, `workflow`, `run`,
`secret`, `variable`, `project`, `ruleset`, `codespace`, `extension`, `api`,
and more β with a read-only-by-default safety gate on anything that
changes state on GitHub.
No Python, no `uv`, no runtime dependency to install β just a binary and
an `.mcp.json`. It shells out to the `gh` binary already installed and
authenticated on the host (`gh auth login`, stored in the OS keychain, or
`GH_TOKEN`/`GITHUB_TOKEN`) instead of reimplementing a GitHub API client,
so it gets the full breadth of the CLI for free rather than a hand-curated
subset of endpoints.
> **Note:** this is a sibling of [github-mcp-connector](https://github.com/FerhatDundar/github-mcp-connector),
> not a replacement. That one talks to the GitHub REST API directly via
> `google/go-github` with a curated set of 18 tools. This one shells out to
> the `gh` CLI itself β same trade-off as `aws-mcp-connector` vs. a
> hand-written AWS SDK client: broader coverage (gh extensions, gh's own
> filters/formatting, workflow/run/codespace/project/ruleset management)
> through a single `ghcli_exec` escape hatch, instead of a curated surface.
## β¨ Why this exists
> An agent that only has a narrow, hand-picked set of GitHub tools hits a
> wall the moment you need something outside that set. This connector
> instead wraps the `gh` CLI itself, so an agent can run `gh pr list`,
> `gh issue create`, `gh workflow run`, `gh api repos/owner/repo/issues` β
> anything the CLI can do β without waiting on a new tool to be written
> for it. State-changing commands are blocked by default and require both
> a server-level opt-in and a per-call `confirm=true`, so exploring/
> reading is safe out of the box.
## π§° Tools
| Tool | What it does | Write? |
|---|---|:---:|
| `ghcli_exec` | Run any `gh <command> <subcommand> ...` command. Read-only by default β commands that change GitHub state need `GHCLI_MCP_ALLOW_WRITE=true` on the server *and* `confirm=true` on the call. | β
(gated) |
| `ghcli_help` | Show `gh <command> [subcommand] --help` text β always safe, use it to check exact syntax before calling `ghcli_exec`. | |
| `ghcli_whoami` | Show the GitHub identity (login, name, profile URL) the configured auth resolves to. | |
Every tool accepts an optional `response_format`: `markdown` (default,
readable for a chat UI) or `json` (for programmatic use).
This server has no working-directory git repo, so repo-scoped commands
need an explicit `-R`/`--repo owner/repo` rather than relying on gh's
cwd-based repo detection.
## π Quickstart
**Fastest path:** grab a prebuilt bundle from the [latest release](https://github.com/FerhatDundar/ghcli-mcp-connector/releases/latest) β
download `ghcli-mcp-connector-plugin-<version>-<os>-<arch>.zip`, unzip it,
and point Cowork/Claude at the `plugin/` folder inside (see step 4 of
[SETUP.md](SETUP.md)). No Go toolchain required.
**From source:**
```bash
# 1. Build
cd go-server
go mod tidy
go build -o ghcli-connector-server .
cp ghcli-connector-server ../plugin/servers/go/
# 2. Set up auth β needs the gh CLI itself installed and logged in
# (gh auth login) β see SETUP.md
gh auth status # should succeed before running the server
# 3. Run
./go-server/ghcli-connector-server # serves MCP over stdio
```
Or `make build` β see the [Makefile](Makefile) for every shortcut
(`test`, `vet`, `fmt`, `lint`, `tidy`).
Full walkthrough β including wiring this up as a Claude/Cowork plugin β is
in **[SETUP.md](SETUP.md)**.
## π Configuration
Everything is environment variables, passed through by the plugin's
`.mcp.json`:
| Variable | Purpose | Default |
|---|---|---|
| `GH_TOKEN` / `GITHUB_TOKEN` | gh CLI's own token env vars. Leave unset to use whatever `gh auth login` already configured. | unset (keychain auth) |
| `GH_HOST` | Target a GitHub Enterprise hostname instead of github.com. | unset (github.com) |
| `GHCLI_MCP_ALLOW_WRITE` | `"true"` to permit state-changing commands at all (still needs `confirm=true` per call). | `false` (read-only) |
| `GHCLI_MCP_ALLOWED_REPOS` | Comma-separated allowlist of `owner/repo` values, e.g. `"me/proj,me/other"`. Only enforced when a call passes an explicit `-R`/`--repo` flag. | unset (unrestricted) |
| `GHCLI_MCP_CLI_PATH` | Path to the `gh` binary. | `gh` resolved via `PATH` |
## π§ͺ Quality bar
This isn't a toy script β it's got the same checks you'd expect from a
production Go service:
- β
**Unit tests** for every input-validation path (`go test ./...`)
- β
**`go vet`** + **`gofmt`** clean
- β
**[golangci-lint](https://golangci-lint.run/)** (govet, staticcheck, errcheck, gosec, and more)
- β
**[govulncheck](https://go.dev/blog/vuln)** β no known vulnerabilities in the dependency graph
- β
**[CodeQL](https://codeql.github.com/)** static security analysis on every push
- β
**End-to-end verified** against real GitHub during development β not mocks
- β
**[Dependabot](.github/dependabot.yml)** keeps Go modules and Actions current
All of it runs in [CI](.github/workflows/ci.yml) on every push and PR.
## π·οΈ Releases & versioning
Versions follow [semver](https://semver.org/) and are cut automatically by
[release-please](https://github.com/googleapis/release-please) from
[Conventional Commits](https://www.conventionalcommits.org/) on `main`:
- `fix: ...` β patch (`v0.1.0` β `v0.1.1`)
- `feat: ...` β minor (`v0.1.1` β `v0.2.0`)
- `feat!: ...` / `BREAKING CHANGE:` footer β major (`v0.2.0` β `v1.0.0`)
Every merged PR updates a standing **"chore(main): release vX.Y.Z"** PR
with an auto-generated [CHANGELOG.md](CHANGELOG.md). Merging that PR:
1. tags the release and publishes it on GitHub
2. builds and attaches zipped, ready-to-install plugin bundles for
linux/darwin/windows Γ amd64/arm64
3. regenerates `server.json` from those exact assets (fresh version +
SHA-256 hashes) and publishes it to the
[official MCP Registry](https://registry.modelcontextprotocol.io/) via
`mcp-publisher`, authenticated with GitHub OIDC β no stored secrets
See [.github/workflows/release-please.yml](.github/workflows/release-please.yml)
and [.github/workflows/publish-mcp-registry.yml](.github/workflows/publish-mcp-registry.yml)
(also runnable by hand for an existing tag via `workflow_dispatch`).
## π Layout
```
ghcli-mcp-connector/
βββ README.md β you are here
βββ SETUP.md β step-by-step setup guide
βββ CONTRIBUTING.md β how to contribute
βββ CODE_OF_CONDUCT.md
βββ SECURITY.md β vulnerability reporting
βββ CODEOWNERS
βββ LICENSE β MIT
βββ Makefile β build / test / lint shortcuts
βββ .golangci.yml β lint rules
βββ release-please-config.json β semver/changelog automation config
βββ .release-please-manifest.json
βββ server.json β MCP Registry manifest (regenerated fresh per release by CI)
βββ scripts/
β βββ render-server-json.sh β rebuilds server.json from a release's zip assets
βββ .github/
β βββ workflows/
β β βββ ci.yml β build, vet, test, lint, govulncheck
β β βββ codeql.yml β security scanning
β β βββ pr-title.yml β Conventional Commits PR title check
β β βββ release-please.yml β version PRs, tagging, GitHub releases
β β βββ publish-mcp-registry.yml β publishes server.json to the MCP Registry
β β βββ rebuild-release-assets.yml β manual re-attach fallback
β βββ ISSUE_TEMPLATE/
β βββ PULL_REQUEST_TEMPLATE.md
β βββ dependabot.yml
βββ go-server/ β the MCP server source
β βββ main.go
β βββ main_test.go
β βββ go.mod / go.sum
β βββ README.md
βββ plugin/ β installable Cowork/Claude plugin
βββ .claude-plugin/plugin.json
βββ .mcp.json β holds credentials locally β never commit real ones
βββ skills/ghcli-mcp/SKILL.md β teaches Claude when/how to use the tools
βββ servers/go/ β compiled binary goes here
```
## π€ Contributing
PRs and issues are very welcome β see **[CONTRIBUTING.md](CONTRIBUTING.md)**
for the full guide (setup, coding conventions, how to add a new tool) and
the **[Code of Conduct](CODE_OF_CONDUCT.md)**.
`main` is protected: every change, including the maintainer's, lands via
pull request with CI green. PR titles must follow
[Conventional Commits](https://www.conventionalcommits.org/) β that's what
drives the automatic versioning above.
Found a security issue? Please follow **[SECURITY.md](SECURITY.md)**
instead of opening a public issue.
## π License
[MIT](LICENSE) Β© FerhatDundar
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues