When Copilot CLI reports MCP server 'github-mcp-server' requires authentication inside Docker Sandboxes, adding another token to another JSON file is rarely the best first move.
Three pieces are easy to confuse:
- Docker Sandboxes supplies a GitHub credential through its host-side secret system.
- Copilot CLI includes its own GitHub MCP server.
- A repository can replace that built-in server with a project-level MCP definition.
Check them in that order.
Table of Contents
Give the existing sandbox its own GitHub secret
Docker’s global service secrets apply when a sandbox is created. If the sandbox already existed when the GitHub secret was added or changed, bind the secret directly to that sandbox:
sbx secret set github --sandbox <sandbox-name> --command 'gh auth token'
The command runs on the host. Docker stores the resolver rather than requiring the token to be pasted into a repository or shell command.
For a new sandbox, set the global secret before creation:
sbx secret set github --command 'gh auth token'
The selected GitHub account must have Copilot access. A global secret added after a sandbox starts will not repair that existing sandbox; either use the sandbox-scoped form or recreate it.
When /login works only until you exit
This is usually a different boundary from the GitHub MCP server.
Copilot CLI normally saves its OAuth login in the operating system’s credential vault. A headless Linux or WSL sandbox may not have a usable keyring. In that case Copilot asks whether it may store the token as plain text. Choosing No cancels the sign-in without saving account state, so the next Copilot process asks you to log in again.
The safer route is to fix the Docker-managed credential rather than copy an OAuth token into the sandbox. If the host token returned by gh auth token lets gh work but Copilot still asks for login, bind a Copilot-supported token to the existing sandbox interactively:
sbx secret set github --sandbox <sandbox-name>
For a personal fine-grained token, GitHub requires the Copilot Requests account permission. Add only the repository permissions needed by the GitHub MCP tools. Copilot CLI does not accept classic personal access tokens. Enter the token at the prompt; do not place it in a shell command, repository file, or screenshot.
The fallback is to run /login again and accept Copilot’s plain-text option. When no vault is available, Copilot uses ~/.copilot/config.json; the same persistent sandbox can reuse it after the process exits. This is less isolated than Docker’s host-side secret store, so use it only in a trusted sandbox and never commit or copy that file.
Test the built-in server before adding another one
Copilot CLI already ships with github-mcp-server. From an active Copilot session, inspect it with:
/mcp show github-mcp-server
Now check the project root for .mcp.json and .github/mcp.json. Copilot CLI loads those files inside the sandbox, and a project-level definition named github-mcp-server takes precedence over the built-in definition.
That override may be intentional, but it changes the authentication path. Rename or temporarily remove the override for the first test. Do not expect the host’s ~/.copilot/mcp-config.json to appear inside the sandbox: Docker Sandboxes exposes project-level configuration from the mounted workspace, not the host’s user-level Copilot configuration.
Enable write tools without replacing the server
The built-in GitHub MCP server starts with a read-only tool selection. To expose its broader tool set for one Copilot run, add GitHub’s supported flag after the Docker Sandboxes argument separator:
sbx run docker.io/sbx/copilot-kit:latest <project> -- --enable-all-github-mcp-tools
Docker Sandboxes v0.42 requires the full kit image name shown above. Releases with the copilot shorthand can use the same trailing flag with their usual sbx run copilot ... command.
Enabling tools does not grant permissions that the GitHub credential lacks. Prefer a fine-grained token with only the repositories and operations the agent actually needs.
Use one small diagnostic split
If authentication still fails, open a shell in the running sandbox and check the GitHub CLI without printing its token:
sbx exec -it <sandbox-name> bash
gh auth status
The result narrows the problem:
| Observation | Likely boundary to inspect |
|---|---|
gh auth status also fails |
Docker sandbox secret scope or the host resolver account |
gh works but the built-in MCP server fails |
Copilot kit or MCP credential wiring |
| A differently named MCP server works | A same-name project override is shadowing the built-in server |
| Read operations work but writes fail | Enabled tool selection or GitHub token permissions |
Avoid printing environment variables, dumping configuration files that may contain headers, or committing a bearer token to .mcp.json. The useful evidence is which boundary succeeds, not the credential value.
For a different remote MCP server, the same habit applies: identify the client, transport, credential source, and exact authority before widening access. This executed MCP boundary sample shows the resulting evidence packet. A metadata-only fit check comes before repository access or payment.
