Skip to main content
  1. Posts/

Connecting OpenCode to GitHub MCP Server

·5 mins
Rafael Fernandez
Author
Rafael Fernandez
Mathematics, programming, and life stuff

Zero-to-working how-to (from scratch)
#

If you have never connected OpenCode to GitHub MCP before, follow this full path first.

1) Install OpenCode
#

Quick install:

curl -fsSL https://opencode.ai/install | bash

Alternative with npm:

npm install -g opencode-ai

2) Create a GitHub PAT
#

For this setup, use a fine-grained PAT.

Direct link:

3) Grant PAT permissions (recommended baseline) #

Permissions depend on what you want MCP to do, but for common repo + PR workflows start with:

  • Metadata: Read-only
  • Contents: Read and write
  • Pull requests: Read and write
  • Issues: Read and write

If you only need read access, keep them read-only where possible. If later you need more (for example actions/checks workflows), expand permissions using least privilege.

4) Store the token in a secret file
#

Create folder and file:

mkdir -p ~/.config/opencode/.secrets
chmod 700 ~/.config/opencode/.secrets
printf 'github_pat_xxxxxxxxxxxxxxxxxxxx' > ~/.config/opencode/.secrets/github-pat
chmod 600 ~/.config/opencode/.secrets/github-pat

5) Configure OpenCode with remote GitHub MCP
#

In ~/.config/opencode/opencode.json add:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "github": {
      "type": "remote",
      "url": "https://api.githubcopilot.com/mcp/",
      "enabled": true,
      "oauth": false,
      "headers": {
        "Authorization": "Bearer {file:~/.config/opencode/.secrets/github-pat}"
      }
    }
  }
}

6) Verify real connectivity
#

opencode mcp list
opencode mcp debug github --log-level DEBUG

Then run a real action in OpenCode:

List open pull requests in owner/repo using github mcp tools.

If this works, your base setup is done. The rest of this post explains why this can fail in some environments and how to avoid the common traps.

Why this post exists
#

This post comes from one very real debugging session.

OpenCode was working fine with other MCP servers, but GitHub MCP was a dead end for me: no GitHub tools were showing up, and everything looked misconfigured.

The tricky part was not the lack of docs. It was the lack of one explicit “do this exact setup” path for OpenCode + remote GitHub MCP in one place.

I kept hitting the same errors:

  • 401 Unauthorized (No access token was provided in this request)
  • Incompatible auth server: does not support dynamic client registration

If those messages look familiar, this is the walkthrough I wish I had.

Why I wanted GitHub MCP inside OpenCode
#

For me, the value of GitHub MCP is not just “more tools”. It is less cognitive switching.

connecting-opencode-to-github-mcp-server-img-2.png

When I am already working in OpenCode, being able to read issues, inspect PRs, check review comments, or query checks without jumping between terminal, browser, and different tabs is a big productivity win.

In real team workflows, this matters even more: moving from issue to PR, answering review feedback, and validating changes becomes faster because the agent has GitHub context inside the same conversation where it already understands your technical goal.

The short version
#

For this integration, the practical and reliable approach is:

  1. Use the GitHub MCP remote endpoint: https://api.githubcopilot.com/mcp/
  2. Use a GitHub PAT (fine-grained if possible)
  3. Send it via Authorization: Bearer ...
  4. Set "oauth": false for that MCP server in OpenCode

That last line is the key when you are not using pre-registered OAuth app credentials.

Working configuration
#

Open your global OpenCode config:

  • ~/.config/opencode/opencode.json

Then add (or update) this block:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "github": {
      "type": "remote",
      "url": "https://api.githubcopilot.com/mcp/",
      "enabled": true,
      "oauth": false,
      "headers": {
        "Authorization": "Bearer {file:~/.config/opencode/.secrets/github-pat}"
      }
    }
  }
}

Then create the secret file and put your token there:

  • ~/.config/opencode/.secrets/github-pat

File content:

github_pat_xxxxxxxxxxxxxxxxxxxx

This is the exact setup that unblocked me.

And one personal decision that mattered for me: I do not use global environment variables for every token or connection.

I could export GITHUB_TOKEN, SENTRY_TOKEN, X_API_KEY, and many others, but I prefer not to keep all secrets globally available in every shell session. I recommend using {file:...} pointing to a dedicated secret file per integration.

In my opinion, this is a better default because it:

  • avoids polluting your global environment with many secrets,
  • reduces cross-project variable mix-ups,
  • and keeps secret management explicit and easier to reason about.

Why this works
#

OpenCode supports automatic OAuth for remote MCP servers and may attempt dynamic client registration by default.

GitHub has clarified they do not plan to support dynamic client registration for this flow, so auto OAuth negotiation can fail depending on the client/host behavior.

When you set:

"oauth": false

you force Bearer header authentication and skip that OAuth negotiation path.

In plain engineering terms: stop waiting for automatic OAuth handshakes that do not align here, and authenticate directly with a controlled header.

Details that can save hours
#

1) Variable syntax is strict
#

In OpenCode config, use:

  • {env:MY_VAR}
  • {file:path/to/secret}

Do not use ${env:MY_VAR}.

It looks small, but it breaks auth immediately.

2) Debug output can be misleading
#

opencode mcp debug ... may still show OAuth-related warnings even when GitHub MCP tools work in the TUI. Multiple users reported this behavior in the issue thread.

Always validate with a real MCP action, not only with debug output.

3) Do not inline tokens in JSON
#

Keep PATs out of plain config whenever possible. {file:...} is cleaner and safer.

This tiny decision prevents accidental copy/paste leaks and bad commits.

For the same reason, I also prefer file-based secrets over global env vars in this setup.

Quick verification
#

Run:

opencode mcp list
opencode mcp debug github --log-level DEBUG

Then ask OpenCode to perform a real GitHub action through MCP, for example:

List open pull requests in owner/repo using github mcp tools.

If tools are available and calls execute, you are done.

That was my final check: less theory, more “does this work end-to-end right now?”

PAT vs OAuth app (security note)
#

This guide uses PAT because it is the fastest path and the one most people try first.

For mature setups, OAuth app credentials may be a better model depending on your security posture and org policy. But if your immediate goal is to make OpenCode work with GitHub MCP today, PAT + oauth: false is the practical fix.

My recommendation: validate the integration first with PAT, then harden the auth model once everything is stable.

References
#

If official docs eventually add a first-class OpenCode section, that will be great. Until then, this is the shortest path I found that works in practice.