refreshMcpOAuthToken function
Future<McpOAuthTokenGrant>
refreshMcpOAuthToken(
- McpOAuthTokenGrant grant, {
- required McpOAuthClientAuthentication clientAuthentication,
- Iterable<
String> ? scopes, - HttpClient? httpClient,
- Map<
String, String> headers = const <String, String>{}, - Duration timeout = _defaultTokenTimeout,
- int maxResponseBytes = _defaultTokenResponseBytes,
- void onRequestOpened(
- HttpClientRequest request
Refreshes a resource-bound MCP OAuth grant without mutating grant.
onRequestOpened observes the request before it is sent so an owning client
can bind it to a larger lifecycle.
Implementation
Future<McpOAuthTokenGrant> refreshMcpOAuthToken(
McpOAuthTokenGrant grant, {
required McpOAuthClientAuthentication clientAuthentication,
Iterable<String>? scopes,
HttpClient? httpClient,
Map<String, String> headers = const <String, String>{},
Duration timeout = _defaultTokenTimeout,
int maxResponseBytes = _defaultTokenResponseBytes,
void Function(HttpClientRequest request)? onRequestOpened,
}) async {
final authorizationServer = grant.authorizationServer;
final endpoint = authorizationServer.tokenEndpoint;
final refreshToken = grant.refreshToken;
if (!_credentialValid(refreshToken)) {
throw McpOAuthTokenException(
'OAuth grant does not contain a usable refresh token.',
endpoint: endpoint,
);
}
final supportedGrants = authorizationServer.grantTypesSupported;
if (supportedGrants != null &&
!supportedGrants.contains(_refreshTokenGrant)) {
throw McpOAuthTokenException(
'Authorization server does not advertise refresh_token grants.',
endpoint: endpoint,
);
}
final requestedScopes = _validatedRefreshScopes(
scopes,
grant: grant,
endpoint: endpoint,
);
_validateOAuthEndpointInputs(
expectedClientId: grant.clientId,
authorizationServer: authorizationServer,
clientAuthentication: clientAuthentication,
supportedMethods:
authorizationServer.tokenEndpointAuthMethodsSupported ??
const <String>[_clientSecretBasic],
endpoint: endpoint,
endpointLabel: 'OAuth token endpoint',
headers: headers,
timeout: timeout,
maxResponseBytes: maxResponseBytes,
);
final response = await _postOAuthForm(
endpoint: endpoint,
form: <String, String>{
'grant_type': _refreshTokenGrant,
'refresh_token': refreshToken!,
if (clientAuthentication.method != _clientSecretBasic)
'client_id': clientAuthentication.clientId,
'resource': grant.resource.toString(),
if (scopes != null) 'scope': requestedScopes.join(' '),
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: grant.resource,
clientId: grant.clientId,
authorizationServer: authorizationServer,
effectiveScopes: requestedScopes,
retainedRefreshToken: refreshToken,
allowedResponseScopes: requestedScopes.toSet(),
);
}