33package oauth
44
55import (
6- "context"
76 "fmt"
87 "net/http"
98 "strings"
@@ -18,9 +17,6 @@ import (
1817const (
1918 // OAuthProtectedResourcePrefix is the well-known path prefix for OAuth protected resource metadata.
2019 OAuthProtectedResourcePrefix = "/.well-known/oauth-protected-resource"
21-
22- // DefaultAuthorizationServer is GitHub's OAuth authorization server.
23- DefaultAuthorizationServer = "https://github.com/login/oauth"
2420)
2521
2622// SupportedScopes lists all OAuth scopes that may be required by MCP tools.
@@ -45,13 +41,8 @@ type Config struct {
4541 // This is used to construct the OAuth resource URL.
4642 BaseURL string
4743
48- // APIHost is the GitHub API host resolver that provides OAuth URL.
49- // If set, this takes precedence over AuthorizationServer.
50- APIHost utils.APIHostResolver
51-
5244 // AuthorizationServer is the OAuth authorization server URL.
5345 // Defaults to GitHub's OAuth server if not specified.
54- // This field is ignored if APIHost is set.
5546 AuthorizationServer string
5647
5748 // ResourcePath is the externally visible base path for the MCP server (e.g., "/mcp").
@@ -62,29 +53,27 @@ type Config struct {
6253
6354// AuthHandler handles OAuth-related HTTP endpoints.
6455type AuthHandler struct {
65- cfg * Config
56+ cfg * Config
57+ apiHost utils.APIHostResolver
6658}
6759
6860// NewAuthHandler creates a new OAuth auth handler.
69- func NewAuthHandler (cfg * Config ) (* AuthHandler , error ) {
61+ func NewAuthHandler (cfg * Config , apiHost utils. APIHostResolver ) (* AuthHandler , error ) {
7062 if cfg == nil {
7163 cfg = & Config {}
7264 }
7365
74- // Resolve authorization server from APIHost if provided
75- if cfg . APIHost != nil {
76- oauthURL , err := cfg . APIHost . OAuthURL ( context . Background () )
66+ if apiHost == nil {
67+ var err error
68+ apiHost , err = utils . NewAPIHost ( "https://api.github.com" )
7769 if err != nil {
78- return nil , fmt .Errorf ("failed to get OAuth URL from API host: %w" , err )
70+ return nil , fmt .Errorf ("failed to create default API host: %w" , err )
7971 }
80- cfg .AuthorizationServer = oauthURL .String ()
81- } else if cfg .AuthorizationServer == "" {
82- // Default authorization server to GitHub if not provided
83- cfg .AuthorizationServer = DefaultAuthorizationServer
8472 }
8573
8674 return & AuthHandler {
87- cfg : cfg ,
75+ cfg : cfg ,
76+ apiHost : apiHost ,
8877 }, nil
8978}
9079
@@ -109,15 +98,28 @@ func (h *AuthHandler) RegisterRoutes(r chi.Router) {
10998
11099func (h * AuthHandler ) metadataHandler () http.Handler {
111100 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
101+ ctx := r .Context ()
112102 resourcePath := resolveResourcePath (
113103 strings .TrimPrefix (r .URL .Path , OAuthProtectedResourcePrefix ),
114104 h .cfg .ResourcePath ,
115105 )
116106 resourceURL := h .buildResourceURL (r , resourcePath )
117107
108+ var authorizationServerURL string
109+ if h .cfg .AuthorizationServer != "" {
110+ authorizationServerURL = h .cfg .AuthorizationServer
111+ } else {
112+ authURL , err := h .apiHost .AuthorizationServerURL (ctx )
113+ if err != nil {
114+ http .Error (w , fmt .Sprintf ("failed to resolve authorization server URL: %v" , err ), http .StatusInternalServerError )
115+ return
116+ }
117+ authorizationServerURL = authURL .String ()
118+ }
119+
118120 metadata := & oauthex.ProtectedResourceMetadata {
119121 Resource : resourceURL ,
120- AuthorizationServers : []string {h . cfg . AuthorizationServer },
122+ AuthorizationServers : []string {authorizationServerURL },
121123 ResourceName : "GitHub MCP Server" ,
122124 ScopesSupported : SupportedScopes ,
123125 BearerMethodsSupported : []string {"header" },
0 commit comments