discoverProtectedResource discovers the Protected Resource Metadata for the given MCP server per RFC 9728 §3.1. It tries the path-aware well-known URL first, then falls back to the root-level URL. Path-aware: GET {origin}/.well-known/oauth-protected-resource{path} Root: GET {origin}/.well-kno
( ctx context.Context, httpClient *http.Client, origin, path string, )
| 1413 | // Path-aware: GET {origin}/.well-known/oauth-protected-resource{path} |
| 1414 | // Root: GET {origin}/.well-known/oauth-protected-resource |
| 1415 | func discoverProtectedResource( |
| 1416 | ctx context.Context, httpClient *http.Client, origin, path string, |
| 1417 | ) (*protectedResourceMetadata, error) { |
| 1418 | var urls []string |
| 1419 | |
| 1420 | // Per RFC 9728 §3.1, when the resource URL contains a |
| 1421 | // path component, the well-known URI is constructed by |
| 1422 | // inserting the well-known prefix before the path. |
| 1423 | if path != "" && path != "/" { |
| 1424 | urls = append( |
| 1425 | urls, |
| 1426 | origin+"/.well-known/oauth-protected-resource"+path, |
| 1427 | ) |
| 1428 | } |
| 1429 | // Always try the root-level URL as a fallback. |
| 1430 | urls = append( |
| 1431 | urls, origin+"/.well-known/oauth-protected-resource", |
| 1432 | ) |
| 1433 | |
| 1434 | var lastErr error |
| 1435 | for _, u := range urls { |
| 1436 | var meta protectedResourceMetadata |
| 1437 | if err := fetchJSON(ctx, httpClient, u, &meta); err != nil { |
| 1438 | lastErr = err |
| 1439 | continue |
| 1440 | } |
| 1441 | if len(meta.AuthorizationServers) == 0 { |
| 1442 | lastErr = xerrors.Errorf( |
| 1443 | "protected resource metadata at %s "+ |
| 1444 | "has no authorization_servers", u, |
| 1445 | ) |
| 1446 | continue |
| 1447 | } |
| 1448 | return &meta, nil |
| 1449 | } |
| 1450 | |
| 1451 | return nil, xerrors.Errorf( |
| 1452 | "discover protected resource metadata: %w", lastErr, |
| 1453 | ) |
| 1454 | } |
| 1455 | |
| 1456 | // discoverAuthServerMetadata discovers the Authorization Server |
| 1457 | // Metadata per RFC 8414 §3.1. When the authorization server |
no test coverage detected