Skip to content
Open
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
3 changes: 3 additions & 0 deletions cmd/github-mcp-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ var (
ListenHost: viper.GetString("listen-host"),
BaseURL: viper.GetString("base-url"),
ResourcePath: viper.GetString("base-path"),
AuthorizationServer: viper.GetString("authorization-server"),
ExportTranslations: viper.GetBool("export-translations"),
EnableCommandLogging: viper.GetBool("enable-command-logging"),
LogFilePath: viper.GetString("log-file"),
Expand Down Expand Up @@ -235,6 +236,7 @@ func init() {
httpCmd.Flags().String("listen-host", "", "Host the HTTP server binds to (e.g. 127.0.0.1). Empty binds to all interfaces.")
httpCmd.Flags().String("base-url", "", "Base URL where this server is publicly accessible (for OAuth resource metadata)")
httpCmd.Flags().String("base-path", "", "Externally visible base path for the HTTP server (for OAuth resource metadata)")
httpCmd.Flags().String("authorization-server", "", "Override the authorization server URL in OAuth resource metadata. Useful when deploying behind an OAuth proxy (e.g. for GHES). Env: GITHUB_AUTHORIZATION_SERVER")
httpCmd.Flags().Bool("scope-challenge", false, "Enable OAuth scope challenge responses")
httpCmd.Flags().Bool("trust-proxy-headers", false, "Honor X-Forwarded-Host and X-Forwarded-Proto when constructing OAuth resource metadata URLs. Only enable when the server is deployed behind a trusted proxy that sets these headers. Ignored when --base-url is set.")

Expand All @@ -260,6 +262,7 @@ func init() {
_ = viper.BindPFlag("listen-host", httpCmd.Flags().Lookup("listen-host"))
_ = viper.BindPFlag("base-url", httpCmd.Flags().Lookup("base-url"))
_ = viper.BindPFlag("base-path", httpCmd.Flags().Lookup("base-path"))
_ = viper.BindPFlag("authorization-server", httpCmd.Flags().Lookup("authorization-server"))
_ = viper.BindPFlag("scope-challenge", httpCmd.Flags().Lookup("scope-challenge"))
_ = viper.BindPFlag("trust-proxy-headers", httpCmd.Flags().Lookup("trust-proxy-headers"))
// Add subcommands
Expand Down
25 changes: 25 additions & 0 deletions docs/streamable-http.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,31 @@ github-mcp-server http --trust-proxy-headers

Equivalent environment variable: `GITHUB_TRUST_PROXY_HEADERS=1`. Only enable this when the upstream proxy is trusted to set or strip these headers; otherwise prefer `--base-url`. When `--base-url` is set, it always takes precedence and `--trust-proxy-headers` has no effect.

### With an OAuth Proxy (GHES / non-standard authorization server)

When deploying against GitHub Enterprise Server, GHES does not natively support the OAuth extensions required by MCP (RFC 8414 metadata discovery, RFC 7591 Dynamic Client Registration, PKCE). In this case you can run a separate OAuth proxy that implements the MCP OAuth spec and forwards authentication to GHES. Use `--authorization-server` to advertise the proxy's URL in the protected resource metadata instead of the one derived from `--gh-host`:

```bash
github-mcp-server http \
--gh-host https://github.example.com \
--base-url https://mcp.example.com \
--authorization-server https://mcp.example.com/oauth-proxy
```

The `authorization_servers` field in the protected resource metadata will then point at your proxy:

```json
{
"resource": "https://mcp.example.com",
"authorization_servers": [
"https://mcp.example.com/oauth-proxy"
],
...
}
```

Equivalent environment variable: `GITHUB_AUTHORIZATION_SERVER=https://mcp.example.com/oauth-proxy`.

## Client Configuration

### Using OAuth Authentication
Expand Down
14 changes: 11 additions & 3 deletions pkg/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ type ServerConfig struct {
// This is used to restore the original path when a proxy strips a base path before forwarding.
ResourcePath string

// AuthorizationServer overrides the authorization server URL advertised in the
// OAuth Protected Resource Metadata (/.well-known/oauth-protected-resource).
// When set, this URL is used instead of the one derived from the GitHub host.
// Useful when deploying behind an OAuth proxy (e.g. for GHES, which does not
// natively support RFC 8414 / RFC 7591 / PKCE).
AuthorizationServer string

// TrustProxyHeaders indicates whether X-Forwarded-Host and X-Forwarded-Proto
// should be honored when constructing OAuth resource metadata URLs. Only
// enable this when the server is deployed behind a trusted proxy that sets
Expand Down Expand Up @@ -163,9 +170,10 @@ func RunHTTPServer(cfg ServerConfig) error {

// Register OAuth protected resource metadata endpoints
oauthCfg := &oauth.Config{
BaseURL: cfg.BaseURL,
ResourcePath: cfg.ResourcePath,
TrustProxyHeaders: cfg.TrustProxyHeaders,
BaseURL: cfg.BaseURL,
ResourcePath: cfg.ResourcePath,
TrustProxyHeaders: cfg.TrustProxyHeaders,
AuthorizationServer: cfg.AuthorizationServer,
}

serverOptions := []HandlerOption{}
Expand Down