()
| 112 | } |
| 113 | |
| 114 | func (h *AuthHandler) metadataHandler() http.Handler { |
| 115 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 116 | ctx := r.Context() |
| 117 | resourcePath := resolveResourcePath( |
| 118 | strings.TrimPrefix(r.URL.Path, OAuthProtectedResourcePrefix), |
| 119 | h.cfg.ResourcePath, |
| 120 | ) |
| 121 | resourceURL := h.buildResourceURL(r, resourcePath) |
| 122 | |
| 123 | var authorizationServerURL string |
| 124 | if h.cfg.AuthorizationServer != "" { |
| 125 | authorizationServerURL = h.cfg.AuthorizationServer |
| 126 | } else { |
| 127 | authURL, err := h.apiHost.AuthorizationServerURL(ctx) |
| 128 | if err != nil { |
| 129 | http.Error(w, fmt.Sprintf("failed to resolve authorization server URL: %v", err), http.StatusInternalServerError) |
| 130 | return |
| 131 | } |
| 132 | authorizationServerURL = authURL.String() |
| 133 | } |
| 134 | |
| 135 | metadata := &oauthex.ProtectedResourceMetadata{ |
| 136 | Resource: resourceURL, |
| 137 | AuthorizationServers: []string{authorizationServerURL}, |
| 138 | ResourceName: "GitHub MCP Server", |
| 139 | ScopesSupported: SupportedScopes, |
| 140 | BearerMethodsSupported: []string{"header"}, |
| 141 | } |
| 142 | |
| 143 | auth.ProtectedResourceMetadataHandler(metadata).ServeHTTP(w, r) |
| 144 | }) |
| 145 | } |
| 146 | |
| 147 | // routesForPattern generates route variants for a given pattern. |
| 148 | // GitHub strips the /mcp prefix before forwarding, so we register both variants: |
no test coverage detected