docs: lead local/stdio install with OAuth login (#2776)

* docs: lead local/stdio install with OAuth login

Surface OAuth 2.1 login as a first-class option above the Personal Access
Token in the README install section and in every local-capable installation
guide, each in that client's own config syntax, linking to the dedicated
docs/oauth-login.md guide.

The github.com OAuth example needs no token; in Docker it publishes a fixed
callback port to loopback (-p 127.0.0.1:8085:8085). The PAT block is retained
below it and noted as taking precedence over OAuth.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(oauth): correct PKCE/client-secret explanation

The previous "How it works" text claimed PKCE removes the need for a client
secret. In practice GitHub requires the client secret at the token endpoint for
both OAuth Apps and GitHub Apps, and the implementation sends it alongside the
PKCE verifier (Manager.oauth2Config populates ClientSecret; flow.go exchanges
with VerifierOption). The secret is baked into the distributed binary and is not
truly confidential; PKCE is what actually secures the flow. Reword to reflect
this accurately.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: don't frame OAuth login as github.com-only

The intro line said "On github.com you can skip the token entirely", which
implied OAuth login only works on github.com. OAuth works on GitHub Enterprise
too — you just supply your own app credentials there. Reword to lead with OAuth
as the mechanism and scope the zero-config claim correctly: on github.com the
official image already includes the app credentials, so the user provides none.
Enterprise / bring-your-own-app is covered by the linked OAuth guide.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Sam Morrow
2026-06-26 14:45:06 +02:00
committed by GitHub
parent 8ce77e3c16
commit fab5fc5ff2
15 changed files with 470 additions and 9 deletions
+31 -2
View File
@@ -280,9 +280,38 @@ More about using MCP server tools in VS Code's [agent mode documentation](https:
Install in GitHub Copilot on other IDEs (JetBrains, Visual Studio, Eclipse, etc.)
Add the following JSON block to your IDE's MCP settings.
Add one of the following JSON blocks to your IDE's MCP settings.
> The examples below authenticate with a Personal Access Token. To log in with OAuth instead (no token to create or store), see **[Local Server OAuth Login](docs/oauth-login.md)** — in Docker it needs a fixed callback port, as the one-click buttons above show.
**Log in with OAuth (no token to create or store).** On github.com the official image already includes the app credentials, so you provide none yourself: it runs a browser-based login on first use and keeps the resulting token **in memory only**. In Docker this needs a fixed callback port published to loopback so the container's login callback is reachable:
```json
{
"mcp": {
"servers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
}
```
See **[Local Server OAuth Login](docs/oauth-login.md)** for the native-binary flow (no fixed port needed), the headless/device-code fallback, GitHub Enterprise Server / `ghe.com`, and bringing your own OAuth or GitHub App.
**Or authenticate with a Personal Access Token.** Set `GITHUB_PERSONAL_ACCESS_TOKEN` instead (it takes precedence over OAuth):
```json
{
@@ -75,6 +75,35 @@ Close and reopen Antigravity for the changes to take effect.
If you prefer running the server locally with Docker:
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"mcpServers": {
@@ -63,6 +63,16 @@ claude mcp add-json github "{`"type`":`"http`",`"url`":`"https://api.githubcopil
### Local Server Setup (Docker required)
### With Docker
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback. Run the following command in the terminal (not in Claude Code CLI):
```bash
claude mcp add github -e GITHUB_OAUTH_CALLBACK_PORT=8085 -- docker run -i --rm -p 127.0.0.1:8085:8085 -e GITHUB_OAUTH_CALLBACK_PORT ghcr.io/github/github-mcp-server
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
1. Run the following command in the terminal (not in Claude Code CLI):
```bash
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_GITHUB_PAT -- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
@@ -136,6 +146,35 @@ claude mcp add github --transport http https://api.githubcopilot.com/mcp/ -H "Au
Add this codeblock to your `claude_desktop_config.json`:
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"mcpServers": {
@@ -212,6 +251,35 @@ Or open the file in a text editor and add the `mcpServers` block manually:
> **macOS note**: Xcode runs with a minimal `PATH` that typically excludes `/usr/local/bin` (Intel) and `/opt/homebrew/bin` (Apple Silicon). Use the full path to `docker` to ensure it can be found. Run `which docker` in Terminal to find the correct path on your system.
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "/usr/local/bin/docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"mcpServers": {
+26 -1
View File
@@ -29,7 +29,32 @@ Replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://githu
## Local Server (Docker)
1. Click the Cline icon in your editor's sidebar (or open the command palette and search for "Cline"), then click the **MCP Servers** icon (server stack icon at the top of the Cline panel), and click **"Configure MCP Servers"** to open `cline_mcp_settings.json`.
2. Add the configuration below, replacing `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens).
2. Add one of the configurations below. The OAuth option needs no token; for the PAT option, replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens).
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
+21 -1
View File
@@ -45,7 +45,27 @@ echo -e ".env" >> .gitignore
## Local Docker Configuration
Use this if you prefer a local, self-hosted instance instead of the remote HTTP server, please refer to the [OpenAI documentation for configuration](https://developers.openai.com/codex/mcp).
Use this if you prefer a local, self-hosted instance instead of the remote HTTP server. See the [OpenAI documentation for configuration](https://developers.openai.com/codex/mcp) for the authoritative schema.
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```toml
[mcp_servers.github]
command = "docker"
args = ["run", "-i", "--rm", "-p", "127.0.0.1:8085:8085", "-e", "GITHUB_OAUTH_CALLBACK_PORT", "ghcr.io/github/github-mcp-server"]
env = { GITHUB_OAUTH_CALLBACK_PORT = "8085" }
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```toml
[mcp_servers.github]
command = "docker"
args = ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"]
env = { GITHUB_PERSONAL_ACCESS_TOKEN = "ghp_your_token_here" }
```
## Verification
@@ -95,6 +95,35 @@ For additional options like toolsets and read-only mode, see the [remote server
With Docker running, you can run the GitHub MCP server in a container:
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"mcpServers": {
@@ -51,6 +51,35 @@ The local GitHub MCP server runs via Docker and requires Docker Desktop to be in
### Docker Configuration
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"mcpServers": {
+33 -1
View File
@@ -59,7 +59,37 @@ You can also connect to the hosted MCP server directly. After securely storing y
### Method 3: Local Docker
With docker running, you can run the GitHub MCP server in a container:
With docker running, you can run the GitHub MCP server in a container.
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
// ~/.gemini/settings.json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
// ~/.gemini/settings.json
@@ -104,6 +134,8 @@ Then, replacing `/path/to/binary` with the actual path to your binary, configure
}
```
To log in with OAuth instead of a PAT (no token to create or store), omit `GITHUB_PERSONAL_ACCESS_TOKEN` — the native binary uses a random loopback callback port, so no extra configuration is needed. See **[Local Server OAuth Login](../oauth-login.md)**.
## Verification
To verify that the GitHub MCP server has been configured, start Gemini CLI in your terminal with `gemini`, then:
@@ -61,6 +61,33 @@ Set `GITHUB_PERSONAL_ACCESS_TOKEN` in your shell environment before starting Ope
The local GitHub MCP server runs via Docker and requires Docker Desktop (or another Docker runtime) to be installed and running.
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"github": {
"type": "local",
"command": [
"docker", "run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"enabled": true,
"environment": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"$schema": "https://opencode.ai/config.json",
@@ -40,7 +40,27 @@ For users who prefer to run the GitHub MCP server locally. Requires Docker insta
#### Configuration
1. Create an `.mcp.json` file in your solution or %USERPROFILE% directory.
2. Add this configuration:
2. Add this configuration. Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"servers": {
"github": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm", "-p", "127.0.0.1:8085:8085", "-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"inputs": [
@@ -109,6 +129,29 @@ The remote GitHub MCP server is hosted by GitHub and provides automatic updates
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
#### Configuration
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"servers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"servers": {
@@ -165,6 +208,29 @@ The remote GitHub MCP server is hosted by GitHub and provides automatic updates
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
#### Configuration
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"servers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"servers": {
@@ -222,6 +288,29 @@ The remote GitHub MCP server is hosted by GitHub and provides automatic updates
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
#### Configuration
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"servers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"servers": {
@@ -33,6 +33,31 @@ To customize toolsets, add server-side headers like `X-MCP-Toolsets` or `X-MCP-R
## Local Server (Docker)
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (replace `YOUR_GITHUB_PAT`; it takes precedence over OAuth):
```json
{
"mcpServers": {
@@ -30,6 +30,35 @@ Windsurf supports Streamable HTTP servers with a `serverUrl` field:
### Docker Installation (Required)
**Important**: The npm package `@modelcontextprotocol/server-github` is no longer supported as of April 2025. Use the official Docker image `ghcr.io/github/github-mcp-server` instead.
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"127.0.0.1:8085:8085",
"-e",
"GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"mcpServers": {
@@ -29,6 +29,8 @@ Xcode runs with a minimal `PATH` that typically excludes common binary locations
| Homebrew (Intel Mac) | `/usr/local/bin/` |
| Homebrew (Apple Silicon) | `/opt/homebrew/bin/` |
> **Logging in with OAuth?** You can run the local server with no PAT — it opens a browser login on first use and keeps the token in memory only. With Docker this needs a fixed callback port published to loopback (`-p 127.0.0.1:8085:8085 -e GITHUB_OAUTH_CALLBACK_PORT` with `GITHUB_OAUTH_CALLBACK_PORT=8085`); a native binary uses a random loopback port and needs no extra configuration. See **[Local Server OAuth Login](../oauth-login.md)**.
## Troubleshooting
| Issue | Possible Cause | Fix |
+25
View File
@@ -41,6 +41,31 @@ Replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://githu
The local GitHub MCP server runs via Docker and requires Docker Desktop (or another Docker runtime) to be installed and running.
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
```json
{
"context_servers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-p", "127.0.0.1:8085:8085",
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
}
}
}
}
```
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
```json
{
"context_servers": {
+6 -3
View File
@@ -32,9 +32,12 @@ pass `--oauth-client-id` (see [Bring your own app](#bring-your-own-app)).
The server prefers the **authorization code flow with PKCE**: it starts a
loopback callback server on your machine, opens GitHub's authorization page, and
exchanges the returned code for a token. PKCE means the client secret is not
required to complete the exchange, which is why a public, distributed client can
ship without a confidential secret.
exchanges the returned code for a token. GitHub requires a client secret at the
token endpoint (for both OAuth Apps and GitHub Apps), so the exchange sends it
together with the PKCE verifier. Because this is a public, distributed client,
that secret is baked into the binary and is **not truly confidential** — PKCE is
what secures the flow: it binds the authorization code to this one login attempt,
so a code intercepted on the loopback redirect can't be redeemed anywhere else.
To present the authorization URL, the server uses the most secure channel your
MCP client offers, in order: