mcpresso-oauth-server
Version:
Production-ready OAuth 2.1 server implementation for Model Context Protocol (MCP) with PKCE support
765 lines (755 loc) • 28.7 kB
TypeScript
import * as cors from 'cors';
import { CorsOptions } from 'cors';
import express from 'express';
interface OAuthClient {
id: string;
secret?: string;
name: string;
type: 'confidential' | 'public';
redirectUris: string[];
scopes: string[];
grantTypes: string[];
createdAt: Date;
updatedAt: Date;
}
interface OAuthUser {
id: string;
username: string;
email?: string;
scopes: string[];
createdAt: Date;
updatedAt: Date;
[key: string]: any;
}
interface UserAuthContext {
clientId: string;
scope?: string;
resource?: string;
redirectUri: string;
ipAddress: string;
userAgent?: string;
}
interface UserAuthCallbacks {
/**
* Authenticate a user by username/email and password.
* This callback is invoked when the user submits their credentials.
*
* @param credentials - The user's login credentials
* @param context - Authentication context (client, scope, etc.)
* @returns Promise<OAuthUser | null> - The authenticated user or null if invalid
*/
authenticateUser?: (credentials: {
username: string;
password: string;
}, context: UserAuthContext) => Promise<OAuthUser | null>;
/**
* Get the currently authenticated user from session/context.
* This callback is invoked during the authorization flow to determine
* if a user is already logged in.
*
* @param sessionData - Session data (cookies, tokens, etc.)
* @param context - Authentication context
* @returns Promise<OAuthUser | null> - The current user or null if not authenticated
*/
getCurrentUser?: (sessionData: any, context: UserAuthContext) => Promise<OAuthUser | null>;
/**
* Render or redirect to a custom login page.
* If not provided, a basic HTML login form will be used.
*
* @param context - Authentication context
* @param error - Optional error message to display
* @returns Promise<string | { redirect: string }> - HTML content or redirect info
*/
renderLoginPage?: (context: UserAuthContext, error?: string) => Promise<string | {
redirect: string;
}>;
/**
* Render or redirect to a custom consent/authorization page.
* If not provided, automatic consent will be granted.
*
* @param user - The authenticated user
* @param context - Authentication context
* @returns Promise<boolean | string | { redirect: string }> - Consent result or custom page
*/
renderConsentPage?: (user: OAuthUser, context: UserAuthContext) => Promise<boolean | string | {
redirect: string;
}>;
}
interface AuthorizationCode {
code: string;
clientId: string;
userId: string;
redirectUri: string;
scope: string;
resource?: string;
codeChallenge?: string;
codeChallengeMethod?: 'S256' | 'plain';
expiresAt: Date;
createdAt: Date;
}
interface AccessToken {
token: string;
clientId: string;
userId?: string;
scope: string;
expiresAt: Date;
createdAt: Date;
audience?: string;
}
interface RefreshToken {
token: string;
accessTokenId: string;
clientId: string;
userId?: string;
scope: string;
expiresAt: Date;
createdAt: Date;
audience?: string;
}
interface AuthorizationRequest {
response_type: 'code';
client_id: string;
redirect_uri: string;
scope?: string;
state?: string;
resource: string;
code_challenge: string;
code_challenge_method: 'S256' | 'plain';
}
interface TokenRequest {
grant_type: 'authorization_code' | 'refresh_token' | 'client_credentials';
client_id: string;
client_secret?: string;
code?: string;
redirect_uri?: string;
refresh_token?: string;
scope?: string;
resource: string;
code_verifier?: string;
}
type TokenType = 'Bearer';
type CodeChallengeMethod = 'S256' | 'plain';
interface TokenResponse {
access_token: string;
token_type: TokenType;
expires_in: number;
refresh_token?: string;
scope: string;
}
interface TokenIntrospectionResponse {
active: boolean;
scope?: string;
client_id?: string;
username?: string;
exp?: number;
aud?: string;
}
interface UserInfoResponse {
sub: string;
name?: string;
email?: string;
scope?: string;
}
interface ClientRegistrationRequest {
redirect_uris: string[];
client_name?: string;
client_uri?: string;
logo_uri?: string;
scope?: string;
grant_types?: string[];
response_types?: string[];
token_endpoint_auth_method?: string;
token_endpoint_auth_signing_alg?: string;
contacts?: string[];
policy_uri?: string;
terms_of_service_uri?: string;
jwks_uri?: string;
jwks?: any;
software_id?: string;
software_version?: string;
}
interface ClientRegistrationResponse {
client_id: string;
client_secret?: string;
client_id_issued_at?: number;
client_secret_expires_at?: number;
redirect_uris: string[];
client_name?: string;
client_uri?: string;
logo_uri?: string;
scope?: string;
grant_types?: string[];
response_types?: string[];
token_endpoint_auth_method?: string;
token_endpoint_auth_signing_alg?: string;
contacts?: string[];
policy_uri?: string;
terms_of_service_uri?: string;
jwks_uri?: string;
jwks?: any;
software_id?: string;
software_version?: string;
}
interface OAuthError {
error: string;
error_description?: string;
error_uri?: string;
state?: string;
}
/**
* Configuration for the MCP OAuth 2.1 Server.
*
* @property issuer - The OAuth 2.1 issuer URL (should be the public base URL of your auth server). Example: 'https://auth.example.com'.
* @property serverUrl - The public base URL of your OAuth server (used for discovery and resource indicators).
* @property authorizationEndpoint - Full URL to the /authorize endpoint. Example: 'https://auth.example.com/authorize'.
* @property tokenEndpoint - Full URL to the /token endpoint.
* @property userinfoEndpoint - Full URL to the /userinfo endpoint.
* @property jwksEndpoint - Full URL to the JWKS endpoint.
* @property introspectionEndpoint - Full URL to the /introspect endpoint.
* @property revocationEndpoint - Full URL to the /revoke endpoint.
* @property requireResourceIndicator - If true, the 'resource' parameter is required in all auth/token requests (MCP best practice). Default: true for MCP, false for dev.
* @property requirePkce - If true, PKCE is required for all authorization code flows. Default: true (MCP requirement).
* @property allowRefreshTokens - If true, refresh tokens are issued and accepted. Default: true.
* @property allowDynamicClientRegistration - If true, clients can register via the /register endpoint (RFC 7591). Default: true for dev, false for prod.
* @property accessTokenLifetime - Access token lifetime in seconds. Default: 3600 (1 hour).
* @property refreshTokenLifetime - Refresh token lifetime in seconds. Default: 2592000 (30 days).
* @property authorizationCodeLifetime - Authorization code lifetime in seconds. Default: 600 (10 minutes).
* @property supportedGrantTypes - List of supported OAuth grant types. Example: ['authorization_code', 'refresh_token', 'client_credentials'].
* @property supportedResponseTypes - List of supported OAuth response types. Example: ['code'].
* @property supportedScopes - List of supported scopes. Example: ['read', 'write', 'admin'].
* @property supportedCodeChallengeMethods - Supported PKCE code challenge methods. Example: ['S256', 'plain'].
* @property jwtSecret - Secret for signing JWTs (use a strong, random value in production!).
* @property jwtAlgorithm - JWT signing algorithm. Example: 'HS256'.
* @property http - HTTP server configuration (CORS, rate limiting, etc). See HTTPServerConfig.
*/
interface MCPOAuthConfig {
/** OAuth 2.1 issuer URL (public base URL of your auth server). */
issuer: string;
/** Public base URL of your OAuth server (used for discovery and resource indicators). */
serverUrl: string;
/** Full URL to the /authorize endpoint. */
authorizationEndpoint: string;
/** Full URL to the /token endpoint. */
tokenEndpoint: string;
/** Full URL to the /userinfo endpoint. */
userinfoEndpoint: string;
/** Full URL to the JWKS endpoint. */
jwksEndpoint: string;
/** Full URL to the /introspect endpoint. */
introspectionEndpoint: string;
/** Full URL to the /revoke endpoint. */
revocationEndpoint: string;
/** Require 'resource' parameter in all auth/token requests (MCP best practice). */
requireResourceIndicator: boolean;
/** Require PKCE for all authorization code flows (MCP requirement). */
requirePkce: boolean;
/** Issue and accept refresh tokens. */
allowRefreshTokens: boolean;
/** Allow dynamic client registration via /register (RFC 7591). */
allowDynamicClientRegistration: boolean;
/** Access token lifetime in seconds. */
accessTokenLifetime: number;
/** Refresh token lifetime in seconds. */
refreshTokenLifetime: number;
/** Authorization code lifetime in seconds. */
authorizationCodeLifetime: number;
/** Supported OAuth grant types. */
supportedGrantTypes: readonly string[];
/** Supported OAuth response types. */
supportedResponseTypes: readonly string[];
/** Supported scopes. */
supportedScopes: readonly string[];
/** Supported PKCE code challenge methods. */
supportedCodeChallengeMethods: readonly string[];
/** Secret for signing JWTs (use a strong, random value in production!). */
jwtSecret: string;
/** JWT signing algorithm. */
jwtAlgorithm: string;
/** HTTP server configuration (CORS, rate limiting, etc). */
http?: HTTPServerConfig;
/** User authentication callbacks for custom login logic. */
auth?: UserAuthCallbacks;
}
/**
* Input type for MCPOAuthServer: only issuer, serverUrl, and jwtSecret are required, all others are optional.
*/
type MCPOAuthConfigInput = Pick<MCPOAuthConfig, 'issuer' | 'serverUrl' | 'jwtSecret'> & Partial<Omit<MCPOAuthConfig, 'issuer' | 'serverUrl' | 'jwtSecret'>>;
interface HTTPServerConfig {
cors?: CorsOptions;
trustProxy?: boolean | string | string[] | number;
jsonLimit?: string;
urlencodedLimit?: string;
enableCompression?: boolean;
enableHelmet?: boolean;
enableRateLimit?: boolean;
rateLimitConfig?: {
windowMs?: number;
max?: number;
message?: string;
standardHeaders?: boolean;
legacyHeaders?: boolean;
};
}
/**
* HTTP server configuration for the MCP OAuth server.
*
* @property cors - CORS configuration (see 'cors' package for options).
* @property trustProxy - Trust proxy headers (true if behind a reverse proxy).
* @property jsonLimit - Max JSON body size (e.g. '10mb').
* @property urlencodedLimit - Max urlencoded body size (e.g. '10mb').
* @property enableCompression - Enable gzip compression. Default: true.
* @property enableHelmet - Enable helmet security headers. Default: true.
* @property enableRateLimit - Enable rate limiting. Default: true.
* @property rateLimitConfig - Rate limiting options (windowMs, max, etc).
*/
interface HTTPServerConfig {
/** CORS configuration (see 'cors' package for options). */
cors?: cors.CorsOptions;
/** Trust proxy headers (true if behind a reverse proxy). */
trustProxy?: boolean | string | string[] | number;
/** Max JSON body size (e.g. '10mb'). */
jsonLimit?: string;
/** Max urlencoded body size (e.g. '10mb'). */
urlencodedLimit?: string;
/** Enable gzip compression. Default: true. */
enableCompression?: boolean;
/** Enable helmet security headers. Default: true. */
enableHelmet?: boolean;
/** Enable rate limiting. Default: true. */
enableRateLimit?: boolean;
/** Rate limiting options (windowMs, max, etc). */
rateLimitConfig?: {
/** Time window in ms. Default: 15 minutes. */
windowMs?: number;
/** Max requests per window. Default: 100. */
max?: number;
/** Message to return when rate limited. */
message?: string;
/** Use standard rate limit headers. */
standardHeaders?: boolean;
/** Use legacy rate limit headers. */
legacyHeaders?: boolean;
};
}
interface MCPProtectedResourceMetadata {
resource: string;
authorization_servers: string[];
scopes_supported?: string[];
bearer_methods_supported?: string[];
}
interface MCPAuthorizationServerMetadata {
issuer: string;
authorization_endpoint: string;
token_endpoint: string;
userinfo_endpoint?: string;
jwks_uri: string;
revocation_endpoint?: string;
introspection_endpoint?: string;
registration_endpoint?: string;
grant_types_supported: string[];
response_types_supported: string[];
scopes_supported: string[];
token_endpoint_auth_methods_supported: string[];
code_challenge_methods_supported: string[];
resource_indicators_supported?: boolean;
}
interface MCPOAuthStorage {
createClient(client: OAuthClient): Promise<void>;
getClient(clientId: string): Promise<OAuthClient | null>;
listClients(): Promise<OAuthClient[]>;
updateClient(clientId: string, updates: Partial<OAuthClient>): Promise<void>;
deleteClient(clientId: string): Promise<void>;
createUser(user: OAuthUser): Promise<void>;
getUser(userId: string): Promise<OAuthUser | null>;
getUserByUsername(username: string): Promise<OAuthUser | null>;
listUsers(): Promise<OAuthUser[]>;
updateUser(userId: string, updates: Partial<OAuthUser>): Promise<void>;
deleteUser(userId: string): Promise<void>;
createAuthorizationCode(code: AuthorizationCode): Promise<void>;
getAuthorizationCode(code: string): Promise<AuthorizationCode | null>;
deleteAuthorizationCode(code: string): Promise<void>;
cleanupExpiredCodes(): Promise<void>;
createAccessToken(token: AccessToken): Promise<void>;
getAccessToken(token: string): Promise<AccessToken | null>;
deleteAccessToken(token: string): Promise<void>;
cleanupExpiredTokens(): Promise<void>;
createRefreshToken(token: RefreshToken): Promise<void>;
getRefreshToken(token: string): Promise<RefreshToken | null>;
deleteRefreshToken(token: string): Promise<void>;
deleteRefreshTokensByAccessToken(accessTokenId: string): Promise<void>;
cleanupExpiredRefreshTokens(): Promise<void>;
getStats(): {
clients: number;
users: number;
authorizationCodes: number;
accessTokens: number;
refreshTokens: number;
};
}
declare class MCPOAuthServer {
private config;
private storage;
constructor(config: MCPOAuthConfigInput, storage: MCPOAuthStorage);
/**
* Handles user authentication during the authorization flow.
* This method should be called before generating authorization codes.
*/
authenticateUserForAuthFlow(credentials: {
username: string;
password: string;
} | null, sessionData: any, context: UserAuthContext): Promise<OAuthUser | null>;
/**
* Renders the login page for user authentication.
*/
renderLoginPage(context: UserAuthContext, error?: string): Promise<string>;
/**
* Handles consent/authorization for authenticated users.
*/
handleUserConsent(user: OAuthUser, context: UserAuthContext): Promise<boolean>;
private generateDefaultLoginPage;
handleAuthorizationRequest(params: AuthorizationRequest, credentials?: {
username: string;
password: string;
}, sessionData?: any, requestContext?: {
ipAddress: string;
userAgent?: string;
}): Promise<{
redirectUrl: string;
} | {
loginPage: string;
} | OAuthError>;
handleTokenRequest(params: TokenRequest): Promise<TokenResponse | OAuthError>;
private handleAuthorizationCodeGrant;
private handleRefreshTokenGrant;
private handleClientCredentialsGrant;
introspectToken(token: string): Promise<TokenIntrospectionResponse>;
revokeToken(token: string, clientId: string): Promise<{
success: boolean;
}>;
getUserInfo(token: string): Promise<UserInfoResponse | OAuthError>;
registerClient(request: ClientRegistrationRequest): Promise<ClientRegistrationResponse | OAuthError>;
getProtectedResourceMetadata(): MCPProtectedResourceMetadata;
getAuthorizationServerMetadata(): MCPAuthorizationServerMetadata;
private generateCode;
private generateCodeChallenge;
private generateClientId;
private generateClientSecret;
private generateAccessToken;
private generateRefreshToken;
private validateScope;
cleanup(): Promise<void>;
getStats(): Promise<{
clients: number;
users: number;
authorizationCodes: number;
accessTokens: number;
refreshTokens: number;
}>;
listClients(): Promise<OAuthClient[]>;
listUsers(): Promise<OAuthUser[]>;
}
declare function registerOAuthEndpoints(app: express.Application, oauthServer: MCPOAuthServer, basePath?: string): void;
declare class MCPOAuthHttpServer {
private app;
private oauthServer;
private config;
constructor(oauthServer: MCPOAuthServer, config: MCPOAuthConfig);
private setupMiddleware;
private setupRoutes;
private setupErrorHandling;
getApp(): express.Application;
start(port: number): Promise<void>;
}
declare class MemoryStorage implements MCPOAuthStorage {
private clients;
private users;
private authorizationCodes;
private accessTokens;
private refreshTokens;
createClient(client: OAuthClient): Promise<void>;
getClient(clientId: string): Promise<OAuthClient | null>;
listClients(): Promise<OAuthClient[]>;
updateClient(clientId: string, updates: Partial<OAuthClient>): Promise<void>;
deleteClient(clientId: string): Promise<void>;
createUser(user: OAuthUser): Promise<void>;
getUser(userId: string): Promise<OAuthUser | null>;
getUserByUsername(username: string): Promise<OAuthUser | null>;
listUsers(): Promise<OAuthUser[]>;
updateUser(userId: string, updates: Partial<OAuthUser>): Promise<void>;
deleteUser(userId: string): Promise<void>;
createAuthorizationCode(code: AuthorizationCode): Promise<void>;
getAuthorizationCode(code: string): Promise<AuthorizationCode | null>;
deleteAuthorizationCode(code: string): Promise<void>;
cleanupExpiredCodes(): Promise<void>;
createAccessToken(token: AccessToken): Promise<void>;
getAccessToken(token: string): Promise<AccessToken | null>;
deleteAccessToken(token: string): Promise<void>;
cleanupExpiredTokens(): Promise<void>;
createRefreshToken(token: RefreshToken): Promise<void>;
getRefreshToken(token: string): Promise<RefreshToken | null>;
deleteRefreshToken(token: string): Promise<void>;
deleteRefreshTokensByAccessToken(accessTokenId: string): Promise<void>;
cleanupExpiredRefreshTokens(): Promise<void>;
getStats(): {
clients: number;
users: number;
authorizationCodes: number;
accessTokens: number;
refreshTokens: number;
};
}
/**
* PKCE (Proof Key for Code Exchange) utilities
* @see https://datatracker.ietf.org/doc/html/rfc7636
*/
/**
* Generate a random code verifier
* @param length Length of the code verifier (43-128 characters)
* @returns A random code verifier
*/
declare function generateCodeVerifier(length?: number): string;
/**
* Generate a code challenge from a code verifier
* @param codeVerifier The code verifier
* @param method The code challenge method ('S256' or 'plain')
* @returns The code challenge
*/
declare function generateCodeChallenge(codeVerifier: string, method?: CodeChallengeMethod): string;
/**
* Verify a code verifier against a code challenge
* @param codeVerifier The code verifier
* @param codeChallenge The code challenge
* @param method The code challenge method
* @returns True if the code verifier matches the challenge
*/
declare function verifyCodeChallenge(codeVerifier: string, codeChallenge: string, method: CodeChallengeMethod): boolean;
/**
* Validate code verifier format
* @param codeVerifier The code verifier to validate
* @returns True if the code verifier is valid
*/
declare function isValidCodeVerifier(codeVerifier: string): boolean;
/**
* Validate code challenge format
* @param codeChallenge The code challenge to validate
* @returns True if the code challenge is valid
*/
declare function isValidCodeChallenge(codeChallenge: string): boolean;
/**
* Generate a complete PKCE pair
* @param method The code challenge method
* @param verifierLength Length of the code verifier
* @returns Object containing code verifier and challenge
*/
declare function generatePkcePair(method?: CodeChallengeMethod, verifierLength?: number): {
codeVerifier: string;
codeChallenge: string;
};
/**
* Token utilities for OAuth 2.1
*/
/**
* Generate a random token
* @param length Length of the token
* @returns A random token
*/
declare function generateRandomToken(length?: number): string;
/**
* Generate a secure access token
* @param length Length of the token
* @returns A secure access token
*/
declare function generateAccessToken(length?: number): string;
/**
* Generate a secure refresh token
* @param length Length of the token
* @returns A secure refresh token
*/
declare function generateRefreshToken(length?: number): string;
/**
* Generate a secure authorization code
* @param length Length of the code
* @returns A secure authorization code
*/
declare function generateAuthorizationCode(length?: number): string;
/**
* Create a JWT access token
* @param payload The token payload
* @param privateKey The private key for signing
* @param algorithm The signing algorithm
* @param expiresIn Expiration time in seconds
* @returns A signed JWT token
*/
declare function createJwtToken(payload: Record<string, any>, privateKey: string, algorithm?: string, expiresIn?: number): Promise<string>;
/**
* Verify a JWT token
* @param token The JWT token to verify
* @param publicKey The public key for verification
* @param algorithm The signing algorithm
* @returns The decoded token payload
*/
declare function verifyJwtToken(token: string, publicKey: string, algorithm?: string): Promise<Record<string, any>>;
/**
* Check if a token is expired
* @param token The token to check
* @returns True if the token is expired
*/
declare function isTokenExpired(token: AccessToken | RefreshToken): boolean;
/**
* Get token expiration time in seconds from now
* @param token The token to check
* @returns Seconds until expiration, negative if expired
*/
declare function getTokenExpirationSeconds(token: AccessToken | RefreshToken): number;
/**
* Create a token response object
* @param accessToken The access token
* @param tokenType The token type
* @param expiresIn Expiration time in seconds
* @param refreshToken Optional refresh token
* @param scope Optional scope
* @returns A token response object
*/
declare function createTokenResponse(accessToken: string, tokenType: TokenType | undefined, expiresIn: number, refreshToken?: string, scope?: string): any;
/**
* Parse scope string into array
* @param scope The scope string
* @returns Array of scopes
*/
declare function parseScope(scope?: string): string[];
/**
* Join scope array into string
* @param scopes Array of scopes
* @returns Scope string
*/
declare function joinScope(scopes: string[]): string;
/**
* Validate scope against allowed scopes
* @param requestedScope The requested scope
* @param allowedScopes The allowed scopes
* @returns True if the scope is valid
*/
declare function validateScope(requestedScope: string[], allowedScopes: string[]): boolean;
/**
* Get intersection of requested and allowed scopes
* @param requestedScope The requested scope
* @param allowedScopes The allowed scopes
* @returns Intersection of scopes
*/
declare function getScopeIntersection(requestedScope: string[], allowedScopes: string[]): string[];
/**
* Production-ready OAuth 2.1 Server Package
*
* A complete OAuth 2.1 implementation with PKCE support for Model Context Protocol (MCP)
*
* @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
* @see https://modelcontextprotocol.io/specification/draft/basic/authorization
*/
declare const DEFAULT_OAUTH_CONFIG: {
issuer: string;
serverUrl: string;
authorizationEndpoint: string;
tokenEndpoint: string;
userinfoEndpoint: string;
jwksEndpoint: string;
revocationEndpoint: string;
introspectionEndpoint: string;
requireResourceIndicator: boolean;
requirePkce: boolean;
allowRefreshTokens: boolean;
allowDynamicClientRegistration: boolean;
accessTokenLifetime: number;
refreshTokenLifetime: number;
authorizationCodeLifetime: number;
supportedGrantTypes: string[];
supportedResponseTypes: string[];
supportedScopes: string[];
supportedCodeChallengeMethods: string[];
jwtSecret: string;
jwtAlgorithm: string;
http: {
cors: {
origin: boolean | string[];
credentials: boolean;
exposedHeaders: string[];
allowedHeaders: string[];
methods: string[];
};
trustProxy: boolean;
jsonLimit: string;
urlencodedLimit: string;
enableCompression: boolean;
enableHelmet: boolean;
enableRateLimit: boolean;
rateLimitConfig: {
windowMs: number;
max: number;
message: string;
standardHeaders: boolean;
legacyHeaders: boolean;
};
};
};
/**
* Create a production-ready OAuth server with proper configuration
*/
declare function createProductionOAuthServer(config?: Partial<typeof DEFAULT_OAUTH_CONFIG>): {
issuer: string;
serverUrl: string;
authorizationEndpoint: string;
tokenEndpoint: string;
userinfoEndpoint: string;
jwksEndpoint: string;
revocationEndpoint: string;
introspectionEndpoint: string;
requireResourceIndicator: boolean;
requirePkce: boolean;
allowRefreshTokens: boolean;
allowDynamicClientRegistration: boolean;
accessTokenLifetime: number;
refreshTokenLifetime: number;
authorizationCodeLifetime: number;
supportedGrantTypes: string[];
supportedResponseTypes: string[];
supportedScopes: string[];
supportedCodeChallengeMethods: string[];
jwtSecret: string;
jwtAlgorithm: string;
http: {
cors: {
origin: boolean | string[];
credentials: boolean;
exposedHeaders: string[];
allowedHeaders: string[];
methods: string[];
};
trustProxy: boolean;
jsonLimit: string;
urlencodedLimit: string;
enableCompression: boolean;
enableHelmet: boolean;
enableRateLimit: boolean;
rateLimitConfig: {
windowMs: number;
max: number;
message: string;
standardHeaders: boolean;
legacyHeaders: boolean;
};
};
};
/**
* Create a demo client for testing
*/
declare function createDemoClient(): {
id: string;
secret: string;
name: string;
type: "confidential";
redirectUris: string[];
scopes: string[];
grantTypes: string[];
createdAt: Date;
updatedAt: Date;
};
export { type AccessToken, type AuthorizationCode, type AuthorizationRequest, type ClientRegistrationRequest, type ClientRegistrationResponse, type CodeChallengeMethod, DEFAULT_OAUTH_CONFIG, type HTTPServerConfig, type MCPAuthorizationServerMetadata, type MCPOAuthConfig, type MCPOAuthConfigInput, MCPOAuthHttpServer, MCPOAuthServer, type MCPOAuthStorage, type MCPProtectedResourceMetadata, MemoryStorage, type OAuthClient, type OAuthError, type OAuthUser, type RefreshToken, type TokenIntrospectionResponse, type TokenRequest, type TokenResponse, type TokenType, type UserAuthCallbacks, type UserAuthContext, type UserInfoResponse, createDemoClient, createJwtToken, createProductionOAuthServer, createTokenResponse, generateAccessToken, generateAuthorizationCode, generateCodeChallenge, generateCodeVerifier, generatePkcePair, generateRandomToken, generateRefreshToken, getScopeIntersection, getTokenExpirationSeconds, isTokenExpired, isValidCodeChallenge, isValidCodeVerifier, joinScope, parseScope, registerOAuthEndpoints, validateScope, verifyCodeChallenge, verifyJwtToken };