Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 53 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Built for developers who want to connect their AI tools to GitHub context and ca

The remote GitHub MCP Server is hosted by GitHub and provides the easiest method for getting up and running. If your MCP host does not support remote MCP servers, don't worry! You can use the [local version of the GitHub MCP Server](https://github.com/github/github-mcp-server?tab=readme-ov-file#local-github-mcp-server) instead.

> **Note:** The remote server does not support OAuth device flow authentication. For OAuth authentication, use the [local GitHub MCP Server](#local-github-mcp-server) with the [OAuth authentication guide](/docs/oauth-authentication.md).

### Prerequisites

1. A compatible MCP host with remote server support (VS Code 1.101+, Claude Desktop, Cursor, Windsurf, etc.)
Expand Down Expand Up @@ -130,10 +132,57 @@ GitHub Enterprise Server does not support remote server hosting. Please refer to

### Prerequisites

1. To run the server in a container, you will need to have [Docker](https://www.docker.com/) installed.
2. Once Docker is installed, you will also need to ensure Docker is running. The image is public; if you get errors on pull, you may have an expired token and need to `docker logout ghcr.io`.
3. Lastly you will need to [Create a GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new).
The MCP server can use many of the GitHub APIs, so enable the permissions that you feel comfortable granting your AI tools (to learn more about access tokens, please check out the [documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)).
**For OAuth Device Flow Authentication (Recommended):**
1. Docker installed and running (or build from source)
2. A web browser to complete authentication
3. Network access to GitHub.com (or your GitHub Enterprise instance)

**For Personal Access Token (PAT) Authentication:**
1. Docker installed and running (or build from source)
2. [Create a GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate permissions

> **💡 Tip**: New users should try [OAuth device flow authentication](/docs/oauth-authentication.md) first - it requires no pre-configuration! Simply start the server without a token and authenticate through your browser. See the [authentication guide](/docs/oauth-authentication.md) for detailed instructions.

### Authentication Methods

The local GitHub MCP Server supports two authentication methods:

#### 1. OAuth Device Flow (Recommended for Interactive Use)

No pre-configuration needed! Start the server without a token:

```json
{
"github": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/github/github-mcp-server", "stdio"]
}
}
```

The server will guide you through browser-based authentication when you first use it. [Learn more in the OAuth authentication guide](/docs/oauth-authentication.md).

#### 2. Personal Access Token (For Automation & Offline Use)

Create a [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) and configure it:

```json
{
"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"
}
}
}
```

See the [OAuth vs PAT comparison](/docs/oauth-authentication.md#comparison-with-pat-authentication) to choose the best method for your use case.

### Personal Access Token Configuration

If you choose to use a Personal Access Token, the MCP server can use many of the GitHub APIs, so enable the permissions that you feel comfortable granting your AI tools (to learn more about access tokens, please check out the [documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)).

<details><summary><b>Handling PATs Securely</b></summary>

Expand Down
11 changes: 11 additions & 0 deletions cmd/github-mcp-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ var (
}
}

// Parse OAuth scopes (similar to toolsets)
var oauthScopes []string
if viper.IsSet("oauth-scopes") {
if err := viper.UnmarshalKey("oauth-scopes", &oauthScopes); err != nil {
return fmt.Errorf("failed to unmarshal oauth-scopes: %w", err)
}
}

ttl := viper.GetDuration("repo-access-cache-ttl")
stdioServerConfig := ghmcp.StdioServerConfig{
Version: version,
Expand All @@ -83,6 +91,7 @@ var (
RepoAccessCacheTTL: &ttl,
OAuthClientID: viper.GetString("oauth-client-id"),
OAuthClientSecret: viper.GetString("oauth-client-secret"),
OAuthScopes: oauthScopes,
}
return ghmcp.RunStdioServer(stdioServerConfig)
},
Expand Down Expand Up @@ -110,6 +119,7 @@ func init() {
rootCmd.PersistentFlags().Duration("repo-access-cache-ttl", 5*time.Minute, "Override the repo access cache TTL (e.g. 1m, 0s to disable)")
rootCmd.PersistentFlags().String("oauth-client-id", "", "OAuth App client ID for device flow authentication (optional, uses default if not provided)")
rootCmd.PersistentFlags().String("oauth-client-secret", "", "OAuth App client secret for device flow authentication (optional, for confidential clients)")
rootCmd.PersistentFlags().StringSlice("oauth-scopes", nil, "Comma-separated list of OAuth scopes to request during device flow authentication (optional, uses default if not provided)")

// Bind flag to viper
_ = viper.BindPFlag("toolsets", rootCmd.PersistentFlags().Lookup("toolsets"))
Expand All @@ -126,6 +136,7 @@ func init() {
_ = viper.BindPFlag("repo-access-cache-ttl", rootCmd.PersistentFlags().Lookup("repo-access-cache-ttl"))
_ = viper.BindPFlag("oauth-client-id", rootCmd.PersistentFlags().Lookup("oauth-client-id"))
_ = viper.BindPFlag("oauth-client-secret", rootCmd.PersistentFlags().Lookup("oauth-client-secret"))
_ = viper.BindPFlag("oauth-scopes", rootCmd.PersistentFlags().Lookup("oauth-scopes"))

// Add subcommands
rootCmd.AddCommand(stdioCmd)
Expand Down
Loading