11import { InvalidTokenError , InsufficientScopeError , ServerError } from '@modelcontextprotocol/sdk/server/auth/errors' ;
22import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types' ;
33
4+ // Extend the Request type to include auth info
5+ declare global {
6+ interface Request {
7+ auth ?: AuthInfo ;
8+ }
9+ }
410export interface McpAuthOptions {
511 /**
612 * Optional, scopes that the token must have.
@@ -33,7 +39,15 @@ export function withMcpAuth(
3339 throw new InvalidTokenError ( "Invalid Authorization header format, expected 'Bearer TOKEN'" ) ;
3440 }
3541
36- const authInfo = await verifyToken ( req , token ) ;
42+ let authInfo : AuthInfo ;
43+ try {
44+ authInfo = await verifyToken ( req , token ) ;
45+ } catch ( error ) {
46+ // Handle any error from verifyToken as a 401
47+ throw new InvalidTokenError (
48+ error instanceof Error ? error . message : "Failed to verify token"
49+ ) ;
50+ }
3751
3852 // Check if token has the required scopes (if any)
3953 if ( options . requiredScopes ?. length ) {
@@ -52,12 +66,13 @@ export function withMcpAuth(
5266 }
5367
5468 // Set auth info on the request object after successful verification
55- ( req as any ) . auth = authInfo ;
69+ req . auth = authInfo ;
5670
5771 return handler ( req ) ;
5872 } catch ( error ) {
5973 const origin = new URL ( req . url ) . origin ;
6074 const resourceMetadataUrl = options . resourceMetadataPath || `${ origin } /.well-known/oauth-protected-resource` ;
75+
6176 if ( error instanceof InvalidTokenError ) {
6277 return new Response ( JSON . stringify ( error . toResponseObject ( ) ) , {
6378 status : 401 ,
0 commit comments