UNPKG

mcpresso

Version:

TypeScript package for Model Context Protocol (MCP) utilities and tools

297 lines 9.43 kB
import type { Request, Response, NextFunction } from 'express'; /** * JWT payload from the OAuth token */ export interface JWTPayload { /** Subject (user ID) */ sub: string; /** Issuer */ iss: string; /** Audience */ aud: string | string[]; /** Expiration time */ exp: number; /** Issued at */ iat: number; /** Client ID */ client_id?: string; /** Scope */ scope?: string; /** Custom claims */ [key: string]: any; } /** * Full user profile that will be passed to handlers */ export interface UserProfile { /** User ID (from JWT sub claim) */ id: string; /** Username */ username?: string; /** Email address */ email?: string; /** User scopes/permissions */ scopes?: string[]; /** Custom user properties */ [key: string]: any; } /** * Function to lookup user profile from JWT payload */ export type UserLookupFunction = (jwtPayload: JWTPayload) => Promise<UserProfile | null>; /** * Configuration for MCP OAuth 2.1 authentication. * * Four usage modes: * 1. External OAuth: Provide `issuer` and `userLookup` * 2. Integrated OAuth: Provide `oauth` server instance * 3. Bearer Token: Provide `bearerToken` configuration * 4. No auth: Don't provide this config at all */ export interface MCPAuthConfig { /** * The issuer URL of the OAuth authorization server. * Only required for external OAuth servers. * For integrated OAuth, this is inherited from the oauth server. * * @example "https://auth.example.com" * @example "http://localhost:4001" */ issuer?: string; /** * Optional: The canonical URL of this MCP server, used as the required 'audience'. * If not provided, will be inferred from the request. * * @example "https://api.example.com" * @example "http://localhost:4000" */ serverUrl?: string; /** * Optional: User lookup function to fetch full user profiles. * When provided, this function will be called with the JWT payload * to fetch the complete user profile, which will then be passed * to all resource handlers as the second parameter. * * @example * ```ts * { * userLookup: async (jwtPayload) => { * const user = await db.users.findById(jwtPayload.sub); * return user ? { * id: user.id, * username: user.username, * email: user.email, * scopes: user.permissions, * profile: user.profile * } : null; * } * } * ``` */ userLookup?: UserLookupFunction; /** * Optional: Integrated OAuth server. * When provided, OAuth endpoints are enabled on the same port, * and issuer/serverUrl/jwtSecret are inherited from the oauth server. */ oauth?: any; /** * Optional: Bearer token authentication configuration. * When provided, simple token-based authentication is used. * * @example * ```ts * { * bearerToken: { * headerName: "Authorization", // Optional, defaults to "Authorization" * token: "your-secret-token-here" * } * } * ``` */ bearerToken?: { /** * Optional: Custom header name for the bearer token. * Defaults to "Authorization" if not provided. * * @example "Authorization" * @example "X-API-Key" */ headerName?: string; /** * The bearer token value that clients must provide. * This should be a secure, randomly generated token. * * @example "sk-1234567890abcdef" * @example "your-secret-token-here" */ token: string; /** * Optional: User profile to associate with authenticated requests. * If not provided, a default profile with id "bearer-user" will be used. * * @example * ```ts * { * id: "bearer-user", * username: "api-client", * email: "api@example.com", * scopes: ["read", "write"] * } * ``` */ userProfile?: UserProfile; }; /** * Optional: Shared secret for HS256 JWTs. * Only needed for external OAuth servers. * For integrated OAuth, this is inherited from the oauth server. */ jwtSecret?: string; /** * Optional: JWT algorithm (default HS256 if jwtSecret is provided). */ jwtAlgorithm?: string; /** * Optional: Whether to require resource indicators (MCP requirement). * Resource indicators help ensure tokens are only used for their intended audience. * * @default true */ requireResourceIndicator?: boolean; /** * Optional: Whether to validate audience claims in JWT tokens. * When enabled, tokens must have an 'aud' claim matching this server's URL. * * @default true */ validateAudience?: boolean; /** * Optional: Custom JWKS endpoint path (relative to issuer). * If not provided, will use `/.well-known/jwks.json` * * @example "/.well-known/jwks.json" * @example "/custom/jwks" */ jwksEndpoint?: string; /** * Optional: Custom metadata endpoint path (relative to serverUrl). * If not provided, will use `/.well-known/oauth-protected-resource` * * @example "/.well-known/oauth-protected-resource" * @example "/custom/metadata" */ metadataEndpoint?: string; /** * Optional: JWT verification options. * Allows fine-tuning of JWT validation behavior. */ jwtOptions?: { /** * Optional: Custom issuer validation. * If not provided, uses the 'issuer' field from this config. * * @example "https://auth.example.com" */ issuer?: string; /** * Optional: Custom audience validation. * If not provided, uses the 'serverUrl' field from this config. * * @example "https://api.example.com" */ audience?: string | string[]; /** * Optional: Clock tolerance for JWT validation in seconds. * Useful for servers with slight time differences. * * @default 0 * @example 30 */ clockTolerance?: number; /** * Optional: Maximum token age in seconds. * Tokens older than this will be rejected regardless of expiration. * * @example 3600 // 1 hour */ maxTokenAge?: number; }; /** * Optional: Error handling configuration. * Controls how authentication errors are reported. */ errorHandling?: { /** * Optional: Whether to include detailed error messages in responses. * In production, you may want to disable this for security. * * @default true */ includeDetails?: boolean; /** * Optional: Custom error messages for different error types. */ messages?: { missingToken?: string; invalidToken?: string; expiredToken?: string; audienceMismatch?: string; signatureFailure?: string; }; }; /** * Optional: Logging configuration. * Controls authentication-related logging. */ logging?: { /** * Optional: Whether to log successful authentications. * * @default false */ logSuccess?: boolean; /** * Optional: Whether to log authentication failures. * * @default true */ logFailures?: boolean; /** * Optional: Whether to log token validation details. * * @default false */ logValidation?: boolean; }; } /** * Creates an Express middleware for validating MCP access tokens. * This middleware implements the MCP authorization specification: * https://modelcontextprotocol.io/specification/draft/basic/authorization * * @param authConfig The MCP authentication configuration. * @param serverUrl The canonical URL of this MCP server, used as the required 'audience'. * @returns An Express middleware function. */ export declare function createMCPAuthMiddleware(authConfig: MCPAuthConfig, serverUrl?: string): (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>; /** * Creates the MCP Protected Resource Metadata endpoint. * This implements RFC 9728 as required by the MCP specification. * * @param authConfig The MCP authentication configuration. * @param serverUrl The canonical URL of this MCP server. * @returns An Express route handler for the metadata endpoint. */ export declare function createMCPProtectedResourceMetadataHandler(authConfig: MCPAuthConfig, serverUrl?: string): (req: Request, res: Response) => Response<any, Record<string, any>> | undefined; export interface AuthConfig { /** * @deprecated Use MCPAuthConfig instead */ issuer: string; } /** * @deprecated Use createMCPAuthMiddleware instead */ export declare function createAuthMiddleware(authConfig: AuthConfig, serverUrl: string): (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>; //# sourceMappingURL=auth.d.ts.map