/** * OAuth 2.0 Provider Adapter * * Implements MCP SDK OAuthServerProvider interface to integrate with external * OAuth 2.0 authorization servers (e.g., GitLab, GitHub, etc.) * * Architecture: * - This server acts as an OAuth client to the external provider (Proxy/Gateway) * - Implements "Callback Mode": * 1. Client -> MCP (Authorize) -> MCP redirects to Provider (with MCP callback URL) * 2. Provider -> MCP (Callback) -> MCP exchanges code for tokens * 3. MCP redirects to Client (with Internal Code) * 4. Client -> MCP (Token) -> MCP returns stored tokens */ import { Request, Response } from 'express'; import type { OAuthServerProvider, AuthorizationParams } from '@modelcontextprotocol/sdk/server/auth/provider.js'; import type { OAuthClientInformationFull, OAuthTokens, OAuthTokenRevocationRequest } from '@modelcontextprotocol/sdk/shared/auth.js'; import type { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js'; import type { OAuthConfig } from '../types/profile.js'; import type { Logger } from '../core/logger.js'; import { InMemoryClientsStore } from './client-store/in-memory-clients-store.js'; export { InMemoryClientsStore }; export type { InMemoryClientsStoreOptions } from './client-store/types.js'; /** * OAuth Provider Adapter for external OAuth servers */ export declare class ExternalOAuthProvider implements OAuthServerProvider { private config; private logger; private _clientsStore; private ssrfValidator; private authorizationCodes; private accessTokens; private stateStore; private endpointsInitialized; private initializationPromise; constructor(config: OAuthConfig, logger: Logger); /** * Lazy initialization of OAuth endpoints (async) * Public method to allow HttpTransport to ensure initialization before client validation */ ensureEndpointsInitialized(): Promise; get clientsStore(): InMemoryClientsStore; get authorizationEndpoint(): string | undefined; get redirectUri(): string | undefined; get scopes(): string[]; /** * Fetch OAuth Authorization Server Metadata (RFC 8414) */ private fetchOAuthMetadata; /** * Resolve environment variable references in OAuth config */ private resolveEnvVars; /** * Derive OAuth endpoints from issuer if needed */ private deriveEndpointsFromIssuer; /** * Check if redirect URI host AND scheme are allowed * Prevents open redirect vulnerabilities (CWE-601) and XSS (javascript: scheme) */ private isAllowedRedirectHost; /** * Match hostname against allowlist entry * * Supports: * - Exact hostnames * - Wildcard subdomains (*.example.com) * - IPv4 exact matches * - IPv4 CIDR ranges (e.g., 10.0.0.0/8) * - IPv6 exact matches * - IPv6 CIDR ranges (e.g., 2001:db8::/32) */ private matchRedirectHost; /** * Check if IP address is within CIDR range * * Example: '192.168.1.50' matches '192.168.1.0/24' * '2001:db8::1' matches '2001:db8::/32' */ private matchCIDR; /** * Convert IPv4 address to 32-bit integer */ private ipv4ToInt; /** * Convert IPv6 address to 128-bit BigInt */ private ipv6ToBigInt; private ipv6Mask; private stripIpv6Brackets; /** * Begin authorization flow * Stores state and redirects to External Provider with MCP Callback URI */ authorize(client: OAuthClientInformationFull, params: AuthorizationParams, res: Response): Promise; /** * Handle callback from External Provider * Exchanges code for tokens and redirects to Client with Internal Code */ handleCallback(req: Request, res: Response): Promise; /** * Get code challenge for authorization code (Internal) */ challengeForAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string): Promise; /** * Exchange authorization code for access token (Internal) */ exchangeAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string, codeVerifier?: string, redirectUri?: string, resource?: URL): Promise; /** * Exchange authorization code with external OAuth provider */ private exchangeCodeWithProvider; exchangeRefreshToken(client: OAuthClientInformationFull, refreshToken: string, scopes?: string[], resource?: URL): Promise; verifyAccessToken(token: string): Promise; private introspectToken; revokeToken(client: OAuthClientInformationFull, request: OAuthTokenRevocationRequest): Promise; private revokeTokenWithProvider; /** * Cleanup expired states, codes, and tokens * Called periodically by HttpTransport */ cleanup(): void; } //# sourceMappingURL=oauth-provider.d.ts.map