fetchJSON performs a GET request to the given URL with the standard MCP OAuth2 discovery headers and decodes the JSON response into dest. It returns nil on success or an error if the request fails or the server returns a non-200 status.
(ctx context.Context, httpClient *http.Client, rawURL string, dest any)
| 1368 | // response into dest. It returns nil on success or an error |
| 1369 | // if the request fails or the server returns a non-200 status. |
| 1370 | func fetchJSON(ctx context.Context, httpClient *http.Client, rawURL string, dest any) error { |
| 1371 | req, err := http.NewRequestWithContext( |
| 1372 | ctx, http.MethodGet, rawURL, nil, |
| 1373 | ) |
| 1374 | if err != nil { |
| 1375 | return xerrors.Errorf("create request for %s: %w", rawURL, err) |
| 1376 | } |
| 1377 | req.Header.Set("Accept", "application/json") |
| 1378 | req.Header.Set("MCP-Protocol-Version", mcp.LATEST_PROTOCOL_VERSION) |
| 1379 | |
| 1380 | resp, err := httpClient.Do(req) |
| 1381 | if err != nil { |
| 1382 | return xerrors.Errorf("GET %s: %w", rawURL, err) |
| 1383 | } |
| 1384 | defer resp.Body.Close() |
| 1385 | |
| 1386 | if resp.StatusCode != http.StatusOK { |
| 1387 | return xerrors.Errorf( |
| 1388 | "GET %s returned HTTP %d", rawURL, resp.StatusCode, |
| 1389 | ) |
| 1390 | } |
| 1391 | |
| 1392 | body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) |
| 1393 | if err != nil { |
| 1394 | return xerrors.Errorf( |
| 1395 | "read response from %s: %w", rawURL, err, |
| 1396 | ) |
| 1397 | } |
| 1398 | |
| 1399 | if err := json.Unmarshal(body, dest); err != nil { |
| 1400 | return xerrors.Errorf( |
| 1401 | "decode JSON from %s: %w", rawURL, err, |
| 1402 | ) |
| 1403 | } |
| 1404 | |
| 1405 | return nil |
| 1406 | } |
| 1407 | |
| 1408 | // discoverProtectedResource discovers the Protected Resource |
| 1409 | // Metadata for the given MCP server per RFC 9728 §3.1. It |