/** * OAuth Client Provider Implementation for MCP Client * * Provides a ready-to-use OAuthClientProvider implementation that can be used * with Mastra's MCPClient for connecting to OAuth-protected MCP servers. * * Client identity is configured, never registered at runtime: the provider is * given either pre-registered client information or a Client ID Metadata * Document URL (SEP-991), and it never performs dynamic client registration. */ import type { OAuthClientProvider, OAuthClientMetadata, OAuthClientInformation, OAuthClientInformationContext, OAuthDiscoveryState, StoredOAuthTokens } from '../shared/oauth-types.js'; /** * Storage interface for persisting OAuth data. * * Implement this interface to persist OAuth data across processes. * For simple in-memory usage, use InMemoryOAuthStorage. */ export interface OAuthStorage { /** * Store a value by key. */ set(key: string, value: string): Promise | void; /** * Retrieve a value by key. */ get(key: string): Promise | string | undefined; /** * Delete a value by key. */ delete(key: string): Promise | void; } /** * Simple in-memory OAuth storage. * * Data is lost when the process exits. For production, implement * OAuthStorage with a persistent store like Redis or a database. */ export declare class InMemoryOAuthStorage implements OAuthStorage { private data; set(key: string, value: string): void; get(key: string): string | undefined; delete(key: string): void; clear(): void; } /** * Options for creating a MCPOAuthClientProvider. * * Exactly one client identity source is required: `clientInformation` for a * client pre-registered with the authorization server, or `clientMetadataUrl` * for a Client ID Metadata Document the authorization server fetches. */ export interface MCPClientMetadata extends OAuthClientMetadata { /** * The `client_id` published in a Client ID Metadata Document. When present it * must equal `clientMetadataUrl`; the provider never sends it to the * authorization server itself. */ client_id?: string; } export interface MCPOAuthClientProviderOptions { /** * The redirect URL for the OAuth callback. * This should be a URL your application controls that can handle * the authorization code callback. * * @example 'http://localhost:3000/oauth/callback' */ redirectUrl: string | URL; /** * OAuth client metadata (name, redirect URIs, grant types, scope). * * Used for scope selection and as the description of this client; it is * never posted to a registration endpoint. With `clientMetadataUrl` it must * mirror the hosted document: `client_name` and at least one redirect URI. */ clientMetadata: MCPClientMetadata; /** * Client information for a client pre-registered with the authorization server. */ clientInformation?: OAuthClientInformation; /** * HTTPS URL of this client's Client ID Metadata Document (SEP-991). * * The URL is used as the `client_id`; the authorization server fetches the * document to learn the client's metadata. Must be an HTTPS URL with a * non-root pathname. */ clientMetadataUrl?: string; /** * Storage for persisting OAuth data (tokens, discovery state and the PKCE * verifier). Defaults to InMemoryOAuthStorage if not provided. * * Tokens are keyed by the authorization server's validated `issuer`, and * mutation ordering is coordinated only within one provider instance, so * give each provider its own storage namespace. */ storage?: OAuthStorage; /** * Callback invoked when the user needs to be redirected to authorize. * * For CLI applications, you might open the URL in a browser. * For web applications, you might redirect the response. * * @param url - The authorization URL to redirect to */ onRedirectToAuthorization?: (url: URL) => void | Promise; /** * Generate a random state parameter for OAuth requests. * Defaults to using crypto.randomUUID. */ stateGenerator?: () => string | Promise; } /** * Mastra's OAuth Client Provider implementation. * * This provider handles the OAuth 2.1 authorization-code flow for connecting to * OAuth-protected MCP servers, including: * - Pre-registered or URL-based (Client ID Metadata Document) client identity * - PKCE (Proof Key for Code Exchange) * - Token storage and refresh * * @example * ```typescript * import { MCPClient, MCPOAuthClientProvider } from '@mastra/mcp'; * * const oauthProvider = new MCPOAuthClientProvider({ * redirectUrl: 'http://localhost:3000/oauth/callback', * clientMetadataUrl: 'https://my-app.example.com/oauth/client-metadata.json', * clientMetadata: { * redirect_uris: ['http://localhost:3000/oauth/callback'], * client_name: 'My MCP Client', * grant_types: ['authorization_code', 'refresh_token'], * response_types: ['code'], * }, * onRedirectToAuthorization: (url) => { * console.log(`Please visit: ${url}`); * }, * }); * * const client = new MCPClient({ * servers: { * 'protected-server': { * url: new URL('https://mcp.example.com/mcp'), * authProvider: oauthProvider, * }, * }, * }); * ``` */ export declare class MCPOAuthClientProvider implements OAuthClientProvider { private _redirectUrl; private readonly _clientMetadata; private readonly _clientMetadataUrl?; private readonly _clientInfo?; private readonly storage; private readonly onRedirect?; private readonly generateState; private _sessionState?; private _sessionRedirectUrl?; private credentialMutation; constructor(options: MCPOAuthClientProviderOptions); /** * The URL to redirect the user agent to after authorization. */ get redirectUrl(): string | URL; /** * Metadata about this OAuth client. */ get clientMetadata(): OAuthClientMetadata; /** * URL of this client's Client ID Metadata Document, when identity is URL-based. */ get clientMetadataUrl(): string | undefined; /** * Returns a OAuth2 state parameter. * * While an authorization session is active (see beginAuthorizationSession), * the pinned session state is returned so a callback server can validate * the redirect against a known value. */ state(): Promise; /** * Pins the OAuth state parameter for the next authorization request. * * Hosts driving an interactive authorization flow (e.g. MCPClient.authenticate) * call this before triggering the flow so the loopback callback server knows * which state value to expect. Call endAuthorizationSession once the flow settles. * * @returns The pinned state value, generated with the configured stateGenerator */ beginAuthorizationSession(): Promise; /** * Clears the pinned authorization state (see beginAuthorizationSession) and * restores the configured redirect URL if applyResolvedRedirectUrl rebased * it to a fallback port during the session, so the next flow starts from * the preferred port again. */ endAuthorizationSession(): void; /** * Points the provider at the callback URL that is actually bound. * * Loopback callback servers may bind a fallback port when the preferred one * is in use. Call this before triggering authorization so the authorization * request's redirect_uri matches the listening server. The bound URL must be * one of the redirect URIs the client is registered with (or lists in its * metadata document). * * @param redirectUrl - The callback URL that is actually bound */ applyResolvedRedirectUrl(redirectUrl: string | URL): void; /** * The client's identity: pre-registered information, or the metadata * document URL used as `client_id`. */ clientInformation(): OAuthClientInformation; private tokensKey; /** * Serializes storage mutations so concurrent writes and invalidations settle * in call order: a write started before `invalidateCredentials` cannot land * after it completes. */ private enqueueCredentialMutation; private readStored; private readIssuerIndex; private rememberIssuer; /** * Loads existing OAuth tokens. * * With an issuer context, only tokens minted by that authorization server are * returned; without one, the most recently saved token set is returned for * the transport's bearer-token read. */ tokens(ctx?: OAuthClientInformationContext): Promise; /** * Stores new OAuth tokens after successful authorization, bound to the * authorization server's issuer when known. */ saveTokens(tokens: StoredOAuthTokens, ctx?: OAuthClientInformationContext): Promise; /** * Persists authorization-server discovery state so the callback leg can * verify the code is exchanged with the server that issued the redirect. */ saveDiscoveryState(state: OAuthDiscoveryState): Promise; /** * Loads persisted authorization-server discovery state. */ discoveryState(): Promise; /** * Invoked to redirect the user agent to the authorization URL. */ redirectToAuthorization(authorizationUrl: URL): Promise; /** * Saves a PKCE code verifier before redirecting to authorization. */ saveCodeVerifier(codeVerifier: string): Promise; /** * Loads the PKCE code verifier for validating authorization result. */ codeVerifier(): Promise; /** * Invalidate stored credentials when the server indicates they're no longer valid. * Client identity is configuration, so the `client` scope has nothing to discard. */ invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery'): Promise; /** * Clear all stored OAuth data. * Useful for logging out or resetting state. */ clear(): Promise; /** * Check if the provider has tokens with an access token. */ hasValidTokens(): Promise; } /** * Creates a simple OAuth provider with pre-configured tokens. * * This is useful for testing scenarios where you already have a valid token. * For production, use the full MCPOAuthClientProvider with proper OAuth flow. * * @param accessToken - A valid access token * @param options - Additional configuration options * @returns An OAuthClientProvider that returns the pre-configured token * * @example * ```typescript * const provider = createSimpleTokenProvider('my-access-token', { * redirectUrl: 'http://localhost:3000/callback', * clientMetadata: { * redirect_uris: ['http://localhost:3000/callback'], * client_name: 'Test Client', * }, * clientInformation: { client_id: 'test-client' }, * }); * ``` */ export declare function createSimpleTokenProvider(accessToken: string, options: { redirectUrl: string | URL; clientMetadata: OAuthClientMetadata; /** Client identity used if the token must be refreshed. */ clientInformation: OAuthClientInformation; tokenType?: string; refreshToken?: string; expiresIn?: number; scope?: string; }): OAuthClientProvider; //# sourceMappingURL=oauth-provider.d.ts.map