exchangeMcpAuthorizationCode function

Future<McpOAuthTokenGrant> exchangeMcpAuthorizationCode(
  1. McpAuthorizationCode authorizationCode, {
  2. required McpOAuthClientAuthentication clientAuthentication,
  3. HttpClient? httpClient,
  4. Map<String, String> headers = const <String, String>{},
  5. Duration timeout = _defaultTokenTimeout,
  6. int maxResponseBytes = _defaultTokenResponseBytes,
  7. void onRequestOpened(
    1. HttpClientRequest request
    )?,
})

Redeems a validated MCP authorization code at its discovered token endpoint.

onRequestOpened observes the request before it is sent so an owning client can bind it to a larger lifecycle.

Implementation

Future<McpOAuthTokenGrant> exchangeMcpAuthorizationCode(
  McpAuthorizationCode authorizationCode, {
  required McpOAuthClientAuthentication clientAuthentication,
  HttpClient? httpClient,
  Map<String, String> headers = const <String, String>{},
  Duration timeout = _defaultTokenTimeout,
  int maxResponseBytes = _defaultTokenResponseBytes,
  void Function(HttpClientRequest request)? onRequestOpened,
}) async {
  final requestState = authorizationCode.request;
  final authorizationServer = requestState.authorizationServer;
  final endpoint = authorizationServer.tokenEndpoint;
  _validateExchangeInputs(
    authorizationCode,
    clientAuthentication,
    headers,
    timeout,
    maxResponseBytes,
  );

  final response = await _postOAuthForm(
    endpoint: endpoint,
    form: <String, String>{
      'grant_type': _authorizationCodeGrant,
      'code': authorizationCode.code,
      'redirect_uri': requestState.redirectUri.toString(),
      if (clientAuthentication.method != _clientSecretBasic)
        'client_id': clientAuthentication.clientId,
      'code_verifier': requestState.pkce.verifier,
      'resource': requestState.resource.toString(),
      if (clientAuthentication.method == _clientSecretPost)
        'client_secret': clientAuthentication._clientSecret!,
    },
    clientAuthentication: clientAuthentication,
    httpClient: httpClient,
    headers: headers,
    timeout: timeout,
    maxResponseBytes: maxResponseBytes,
    endpointLabel: 'OAuth token endpoint',
    onRequestOpened: onRequestOpened,
  );
  return _parseTokenGrantResponse(
    statusCode: response.statusCode,
    mimeType: response.mimeType,
    body: _decodeOAuthResponse(response, endpoint, 'OAuth token endpoint'),
    endpoint: endpoint,
    resource: requestState.resource,
    clientId: clientAuthentication.clientId,
    authorizationServer: authorizationServer,
    effectiveScopes: requestState.scopes,
  );
}