1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Core\Auth;
15:
16: /**
17: * The metadata document an authorization server publishes.
18: *
19: * @see https://datatracker.ietf.org/doc/html/rfc8414#section-2
20: * @see https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
21: */
22: final readonly class AuthorizationServerMetadata
23: {
24: /**
25: * @param non-empty-string $issuer
26: * @param null|non-empty-string $authorizationEndpoint
27: * @param null|non-empty-string $tokenEndpoint
28: * @param null|non-empty-string $registrationEndpoint
29: * @param null|list<non-empty-string> $codeChallengeMethodsSupported
30: * @param null|list<non-empty-string> $tokenEndpointAuthMethodsSupported
31: * @param null|list<non-empty-string> $tokenEndpointAuthSigningAlgValuesSupported
32: * @param null|list<non-empty-string> $grantTypesSupported
33: * @param null|list<non-empty-string> $authorizationGrantProfilesSupported
34: */
35: public function __construct(
36: public string $issuer,
37: public ?string $authorizationEndpoint = null,
38: public ?string $tokenEndpoint = null,
39: public ?string $registrationEndpoint = null,
40: public ?ScopeSet $scopesSupported = null,
41: public ?array $codeChallengeMethodsSupported = null,
42: public ?bool $authorizationResponseIssParameterSupported = null,
43: public ?bool $clientIdMetadataDocumentSupported = null,
44: public ?array $tokenEndpointAuthMethodsSupported = null,
45: public ?array $tokenEndpointAuthSigningAlgValuesSupported = null,
46: public ?array $grantTypesSupported = null,
47: public ?array $authorizationGrantProfilesSupported = null,
48: ) {
49: }
50:
51: /**
52: * @param array<string, mixed> $data
53: */
54: public static function fromArray(array $data): self
55: {
56: $reader = new MetadataReader('Authorization Server Metadata');
57: $scopes = $reader->readStringList($data, 'scopes_supported');
58:
59: return new self(
60: $reader->readRequiredString($data, 'issuer'),
61: $reader->readString($data, 'authorization_endpoint'),
62: $reader->readString($data, 'token_endpoint'),
63: $reader->readString($data, 'registration_endpoint'),
64: null === $scopes ? null : ScopeSet::fromList($scopes),
65: $reader->readStringList($data, 'code_challenge_methods_supported'),
66: $reader->readBool($data, 'authorization_response_iss_parameter_supported'),
67: $reader->readBool($data, 'client_id_metadata_document_supported'),
68: $reader->readStringList($data, 'token_endpoint_auth_methods_supported'),
69: $reader->readStringList($data, 'token_endpoint_auth_signing_alg_values_supported'),
70: $reader->readStringList($data, 'grant_types_supported'),
71: $reader->readStringList($data, 'authorization_grant_profiles_supported'),
72: );
73: }
74: }
75: