diff --git a/cmd/github-mcp-server/main.go b/cmd/github-mcp-server/main.go index 231b0cf2c3..7e82dce39d 100644 --- a/cmd/github-mcp-server/main.go +++ b/cmd/github-mcp-server/main.go @@ -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"), @@ -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.") @@ -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 diff --git a/docs/streamable-http.md b/docs/streamable-http.md index 8f4a2bff84..1d3c6aede8 100644 --- a/docs/streamable-http.md +++ b/docs/streamable-http.md @@ -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 diff --git a/pkg/http/server.go b/pkg/http/server.go index 36d3e111bc..b70e1d064f 100644 --- a/pkg/http/server.go +++ b/pkg/http/server.go @@ -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 @@ -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{}