registerMcpOAuthClient function
Future<McpOAuthDynamicClientRegistration>
registerMcpOAuthClient({
- required McpAuthorizationServerMetadata authorizationServer,
- required McpOAuthDynamicClientRegistrationRequest registration,
- String? initialAccessToken,
- HttpClient? httpClient,
- Map<
String, String> headers = const <String, String>{}, - Duration timeout = _defaultRegistrationTimeout,
- int maxResponseBytes = _defaultRegistrationResponseBytes,
- void onRequestOpened(
- HttpClientRequest request
Registers a public OAuth client through the advertised RFC 7591 endpoint.
onRequestOpened observes the request before it is sent so an owning client
can bind it to a larger lifecycle.
Implementation
Future<McpOAuthDynamicClientRegistration> registerMcpOAuthClient({
required McpAuthorizationServerMetadata authorizationServer,
required McpOAuthDynamicClientRegistrationRequest registration,
String? initialAccessToken,
HttpClient? httpClient,
Map<String, String> headers = const <String, String>{},
Duration timeout = _defaultRegistrationTimeout,
int maxResponseBytes = _defaultRegistrationResponseBytes,
void Function(HttpClientRequest request)? onRequestOpened,
}) async {
final endpoint = authorizationServer.registrationEndpoint;
if (endpoint == null) {
throw McpOAuthClientRegistrationException(
'Authorization server does not advertise a dynamic client '
'registration endpoint.',
endpoint: authorizationServer.issuer,
);
}
_validateRegistrationInputs(
endpoint: endpoint,
initialAccessToken: initialAccessToken,
headers: headers,
timeout: timeout,
maxResponseBytes: maxResponseBytes,
);
final encodedBody = utf8.encode(jsonEncode(registration.toJson()));
final client = httpClient ?? HttpClient();
final ownsClient = httpClient == null;
final deadline = DateTime.now().add(timeout);
HttpClientRequest? request;
try {
request = await client
.postUrl(endpoint)
.timeout(_remaining(deadline, endpoint));
try {
onRequestOpened?.call(request);
} catch (error) {
request.abort(error);
rethrow;
}
request.followRedirects = false;
request.headers.contentType = ContentType.json;
request.headers.set(HttpHeaders.acceptHeader, 'application/json');
for (final entry in headers.entries) {
request.headers.set(entry.key, entry.value);
}
if (initialAccessToken != null) {
request.headers.set(
HttpHeaders.authorizationHeader,
'Bearer $initialAccessToken',
);
}
request.contentLength = encodedBody.length;
request.add(encodedBody);
final response = await request.close().timeout(
_remaining(deadline, endpoint),
);
final body = await _readRegistrationResponse(
response,
endpoint: endpoint,
maxResponseBytes: maxResponseBytes,
).timeout(_remaining(deadline, endpoint));
final registrationResponse = _ClientRegistrationResponse(
statusCode: response.statusCode,
mimeType: response.headers.contentType?.mimeType,
body: body,
);
return _parseRegistrationResponse(
registrationResponse,
endpoint: endpoint,
authorizationServer: authorizationServer,
request: registration,
);
} on McpOAuthClientRegistrationException {
rethrow;
} on TimeoutException {
request?.abort();
throw McpOAuthClientRegistrationException(
'Dynamic client registration request timed out.',
endpoint: endpoint,
);
} on Object {
request?.abort();
throw McpOAuthClientRegistrationException(
'Dynamic client registration request failed.',
endpoint: endpoint,
);
} finally {
if (ownsClient) {
client.close(force: true);
}
}
}