Fetching Connection Tokens
This section covers how to fetch connection tokens for your users and tenants. This is typically done within an MCP server, but can also be done directly by your agent as well, depending on your architecture.
To retrieve a token for a Connection, you can use either one of our SDKs or our REST API.
To see how you make token requests within your MCP server, see the Authentication for Token Fetching section below.
Authentication for Token Fetching
You can authenticate requests to fetch connection tokens using either:
- MCP Server access token: Formatted as
Bearer <PROJECT_ID>:<ACCESS_TOKEN>(recommended) - Management Key: Formatted as
Bearer <PROJECT_ID>:<MANAGEMENT_KEY>
Your MCP Server access token must include the outbound.token.fetch scope to be able to fetch connection tokens. This scope must be originally requested by the OAuth client and consented to by the user.
When using an MCP Server access token, Descope enforces your custom access control policies on the token request. This allows you to control which MCP clients/agents can retrieve connection tokens based on roles, permissions, or other conditions defined in your policies.
Management keys, on the other hand, provide full administrative access to all connection tokens across all users and tenants, bypassing access control policies.
Token Fetching Methods
These are all of the methods you can use to fetch connection tokens.
Fetch Latest User Token
This method is recommended when you don't know the exact scopes or want the most recent valid token for the user, regardless of scopes.
Request Parameters
appId(required): The ID of the connection.userId(required): The user ID for whom to fetch the token.tenantId(optional): The tenant ID of the user, if a user has multiple tokens associated with different tenants.options(optional): Additional options for token fetching.withRefreshToken: Defaults to false. Set this to true to include the refresh token in the response.forceRefresh: Defaults to false. The API will return a refreshed token regardless of this value, but this will force our service to refresh the token on the client's behalf.
Fetch Token with Specific Scopes
Use this method when you need a token with specific scopes. Important: You must provide the exact scopes that were used when the token was created. Otherwise, you'll receive a 404 Token not found error.
Request Parameters
appId(required): The ID of the connection.userId(required): The user ID for whom to fetch the token.tenantId(optional): The tenant ID of the user, if a user has multiple tokens associated with different tenants.scopes(required): An array of exact scopes that match the original token.options(optional): Additional options for token fetching.withRefreshToken: Defaults to false. Set this to true to include the refresh token in the response.forceRefresh: Defaults to false. The API will return a refreshed token regardless of this value, but this will force our service to refresh the token on the client's behalf.
Fetching Tenant-Level Tokens
In addition to user-specific tokens, you can also fetch tenant-level tokens for connections. These are useful when you need to access APIs on behalf of a tenant rather than a specific user.
Descope provides the same two methods for tenant-level connection tokens as user-level tokens. Depending on whether you know the exact scopes of the token you need, you can use the following methods:
Fetch Latest Tenant Token
This method is recommended when you don't know the exact scopes or want the most recent valid token for the tenant, regardless of scopes.
Request Parameters
appId(required): The ID of the connection.tenantId(required): The tenant ID if you're fetching a tenant-level token.options(optional): Additional options for token fetching.withRefreshToken: Defaults to false. Set this to true to include the refresh token in the response.forceRefresh: Defaults to false. The API will return a refreshed token regardless of this value, but this will force our service to refresh the token on the client's behalf.
Fetch Tenant Token with Specific Scopes
Use this method when you need a tenant token with specific scopes. Important: You must provide the exact scopes that were used when the token was created. Otherwise, you'll receive a 404 Token not found error.
Request Parameters
appId(required): The ID of the connection.tenantId(required): The tenant ID if you're fetching a tenant-level token.scopes(required): An array of exact scopes that match the original token.options(optional): Additional options for token fetching.withRefreshToken: Defaults to false. Set this to true to include the refresh token in the response.forceRefresh: Defaults to false. The API will return a refreshed token regardless of this value, but this will force our service to refresh the token on the client's behalf.
Connection Token Response
The refresh_token will not be returned unless withRefreshToken is set to true in the request.
The response will include the user/tenant token details, similar to the example below:
Using Tokens within your MCP Tools
Once you have the access token from a connection, you can use it to make authenticated requests to the third-party provider's API within your MCP tools.
Example: Google Contacts MCP Tool
The following example shows how an MCP tool would fetch a user's contacts using the Google Contacts API with a token obtained from a connection. This assumes you've already validated the MCP client's access token and extracted the user ID.
Key Points
-
Token Fetching: The MCP tool fetches the connection token using the user ID from the validated MCP access token. This ensures that access control policies are enforced.
-
Policy Enforcement: When using an MCP Server access token (instead of a Management Key), Descope evaluates your access control policies before returning the connection token. This means only authorized users / clients can retrieve tokens for specific connections.
-
Token Usage: The connection token is then used to authenticate requests to the third-party API (Google Contacts in this example).
-
Error Handling: Always handle API errors appropriately and return meaningful responses to the MCP client.
For more detailed examples and AI agent implementations, see our Examples Guide.
Error Handling
When working with connection tokens, you may encounter different types of errors. Here's what each error code means and how to handle them:
Common Error Codes
| Status Code | Meaning | Common Causes |
|---|---|---|
| 401 | Unauthorized | Invalid management key or project ID |
| 403 | Forbidden | Insufficient permissions or invalid tenant access |
| 404 | Token not found | User never connected to the connection, token was cleared, or wrong scopes provided |
| 500 | Server error | Invalid HTTP method (not POST) or malformed JSON payload |
Error Handling Example
Viewing and Managing Tokens in the Console
After connecting users to a connection, you can view and manage their tokens directly in the Descope Console under the Token Management tab for your connection.
![]()
For each user or tenant-level token, you can:
- View the access token (and refresh token, if applicable)
- Manually refresh the access token
- Delete the token
Note
You can delete your pre-existing tokens programtically as well with these functions.
This provides a convenient way to audit, troubleshoot, or revoke access for specific users or tenants without writing any code.