Summary
With tools.github configured (any toolset, any auth mode — cross-org GitHub App or same-org), Claude Code's own init handshake reports the github MCP server as status: "failed", and zero mcp__github__* tools are ever registered as callable — even though --allowed-tools and --mcp-config both correctly reference them, and the underlying github-mcp-server container is demonstrably alive and answering protocol calls.
This reproduced in 5 out of 5 controlled runs across two orgs, four repositories, and both cross-org (GitHub App, owner: override) and same-org (no override) auth configurations — a 100% failure rate with a minimal, purpose-built diagnostic workflow.
Environment
- gh-aw version:
v0.82.7
- Claude Code CLI version:
2.1.201
- Model:
claude-opus-4-8[1m]
- MCP Gateway image:
ghcr.io/github/gh-aw-mcpg:v0.4.1
- GitHub MCP Server image:
ghcr.io/github/github-mcp-server:v1.5.0
- Runner: GitHub-hosted Actions runner
Minimal reproduction workflow
No cross-org checkout, no PR creation — just probes GitHub MCP tool availability and reports honestly (explicitly forbidden from routing around a missing tool via gh api/curl so the report reflects the tool's actual out-of-the-box behavior):
---
name: GitHub MCP Test
on:
workflow_dispatch: {}
engine:
id: claude
permissions:
contents: read
issues: read
pull-requests: read
vulnerability-alerts: read
security-events: read
tools:
github:
toolsets: [default, dependabot, security_advisories]
github-app:
client-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
repositories: ["*"]
safe-outputs:
noop: {}
strict: true
timeout-minutes: 10
network:
allowed:
- defaults
max-ai-credits: 200
max-turns: 10
---
# GitHub MCP Reliability Test
Diagnostic-only. Do not fix anything, do not create pull requests, do not modify files.
## Rules
- Do NOT run `yarn audit`/`npm audit`/any vulnerability-scanning fallback.
- Do NOT read or modify any repository files.
- Do NOT work around a missing/failed tool via `gh api`, `curl` to the MCP gateway, or raw JSON-RPC.
- Report the unmodified, out-of-the-box behavior honestly.
## Instructions
1. Report whether any `mcp__github__*` tools are present and callable in this session.
2. Try calling a GitHub MCP tool for listing Dependabot alerts (e.g. `list_dependabot_alerts`), exactly once. Record whether it was even invocable, and the exact result.
3. Try exactly one more GitHub MCP tool from a different toolset (e.g. `get_me`, `search_repositories`). Record the same.
4. Report all of the above via `noop`.
Steps to reproduce
- Add the workflow above to a repository with a GitHub App configured for
tools.github.github-app (or omit github-app entirely to use the default token — not yet tested, but worth including in triage).
gh aw compile <workflow>.md
gh workflow run "GitHub MCP Test"
- Inspect the
agent job logs.
Expected behavior
Claude Code's init message should report "github":{"status":"connected"} (or similar), and the agent's tool set should include the mcp__github__* tools implied by the configured toolsets.
Actual behavior
Every run's init message:
"mcp_servers":[{"name":"github","status":"failed"},{"name":"safeoutputs","status":"failed"}]
The agent's own tool set contains no mcp__github__* entries at all. Verbatim from one run's final report:
None present. No mcp__github__* tools were available or callable in this session. The available tool set consisted only of local/harness tools (Bash, file tools, Skill, Task, Web, Workflow, Cron) plus the safeoutputs CLI. Despite the <github-mcp-tools> context declaring a read-only GitHub MCP server, zero GitHub MCP tools were exposed to the agent this run.
Evidence the underlying server is not the problem
In the Start MCP Gateway step, the gateway's own health check and connectivity check both report success, in every run, including the ones where Claude later reports github as failed:
[info] Health response body: {"status":"healthy","specVersion":"1.14.0","gatewayVersion":"v0.4.1","servers":{"github":{"status":"running","uptime":0},"safeoutputs":{"status":"running","uptime":3}}}
...
✓ github: connected
More conclusively: the post-run Parse MCP Gateway logs for step summary step captures the gateway's internal RPC traffic, which includes a successful tools/list response from the github MCP server, with full tool schemas returned (e.g. a get_commit tool description with its complete input schema) — proof the container was alive, reachable, and correctly answering MCP protocol calls the entire time.
So the container and gateway are healthy. The break appears to be specifically in Claude Code's own MCP client failing to complete its handshake with the github server over the gateway's HTTP transport (http://<gateway>:8080/mcp/github), despite --mcp-config and --allowed-tools both correctly including it.
Note: safeoutputs reports the identical "status":"failed" at init in every run too, but recovers via a separate CLI-mount path (mcp-cli binaries on PATH) and functions normally. This suggests the init status field may not reliably reflect either server's actual state, but for github specifically — which has no equivalent CLI-mount fallback — the practical effect is that the tools are simply never usable.
Reproducibility
| Variant |
Org/repo count |
Result |
Cross-org (github-app with owner: override, cross-org checkout:) |
4 repos across 2 orgs |
5/5 — total failure |
Same-org (no owner: override, no cross-org checkout) |
1 repo |
included above |
5 out of 5 runs, zero exceptions.
Impact
We first noticed this via a security-remediation workflow that depends entirely on live list_dependabot_alerts calls. When the native tool is unavailable, an agent may (reasonably, given no other option) fall back to alternative signal sources or hand-rolled workarounds instead of failing loudly — in our case this produced a silent false negative: a run reported "no critical alerts, nothing to fix" when a real, open, critical CVE existed, because a manual workaround didn't paginate correctly. That's a separate, compounding issue, but it underscores why the native tool needs to be reliable (or fail loudly) rather than silently absent.
Summary
With
tools.githubconfigured (any toolset, any auth mode — cross-org GitHub App or same-org), Claude Code's own init handshake reports thegithubMCP server asstatus: "failed", and zeromcp__github__*tools are ever registered as callable — even though--allowed-toolsand--mcp-configboth correctly reference them, and the underlyinggithub-mcp-servercontainer is demonstrably alive and answering protocol calls.This reproduced in 5 out of 5 controlled runs across two orgs, four repositories, and both cross-org (GitHub App,
owner:override) and same-org (no override) auth configurations — a 100% failure rate with a minimal, purpose-built diagnostic workflow.Environment
v0.82.72.1.201claude-opus-4-8[1m]ghcr.io/github/gh-aw-mcpg:v0.4.1ghcr.io/github/github-mcp-server:v1.5.0Minimal reproduction workflow
No cross-org checkout, no PR creation — just probes GitHub MCP tool availability and reports honestly (explicitly forbidden from routing around a missing tool via
gh api/curlso the report reflects the tool's actual out-of-the-box behavior):Steps to reproduce
tools.github.github-app(or omitgithub-appentirely to use the default token — not yet tested, but worth including in triage).gh aw compile <workflow>.mdgh workflow run "GitHub MCP Test"agentjob logs.Expected behavior
Claude Code's init message should report
"github":{"status":"connected"}(or similar), and the agent's tool set should include themcp__github__*tools implied by the configuredtoolsets.Actual behavior
Every run's init message:
The agent's own tool set contains no
mcp__github__*entries at all. Verbatim from one run's final report:Evidence the underlying server is not the problem
In the
Start MCP Gatewaystep, the gateway's own health check and connectivity check both report success, in every run, including the ones where Claude later reportsgithubas failed:More conclusively: the post-run
Parse MCP Gateway logs for step summarystep captures the gateway's internal RPC traffic, which includes a successfultools/listresponse from thegithubMCP server, with full tool schemas returned (e.g. aget_committool description with its complete input schema) — proof the container was alive, reachable, and correctly answering MCP protocol calls the entire time.So the container and gateway are healthy. The break appears to be specifically in Claude Code's own MCP client failing to complete its handshake with the
githubserver over the gateway's HTTP transport (http://<gateway>:8080/mcp/github), despite--mcp-configand--allowed-toolsboth correctly including it.Note:
safeoutputsreports the identical"status":"failed"at init in every run too, but recovers via a separate CLI-mount path (mcp-clibinaries onPATH) and functions normally. This suggests the initstatusfield may not reliably reflect either server's actual state, but forgithubspecifically — which has no equivalent CLI-mount fallback — the practical effect is that the tools are simply never usable.Reproducibility
github-appwithowner:override, cross-orgcheckout:)owner:override, no cross-org checkout)5 out of 5 runs, zero exceptions.
Impact
We first noticed this via a security-remediation workflow that depends entirely on live
list_dependabot_alertscalls. When the native tool is unavailable, an agent may (reasonably, given no other option) fall back to alternative signal sources or hand-rolled workarounds instead of failing loudly — in our case this produced a silent false negative: a run reported "no critical alerts, nothing to fix" when a real, open, critical CVE existed, because a manual workaround didn't paginate correctly. That's a separate, compounding issue, but it underscores why the native tool needs to be reliable (or fail loudly) rather than silently absent.