11import { ApiClient , VerifyAccessTokenError } from "@auth0/auth0-api-js" ;
2- import { InvalidTokenError } from "@modelcontextprotocol/sdk/server/auth/errors.js" ;
2+ import {
3+ InsufficientScopeError ,
4+ InvalidTokenError ,
5+ } from "@modelcontextprotocol/sdk/server/auth/errors.js" ;
36import { headers } from "xmcp/headers" ;
47import { AUTH0_AUDIENCE , AUTH0_DOMAIN } from "./config" ;
58import { Auth } from "./types" ;
9+ import { ToolExtraArguments } from "xmcp" ;
10+
11+ const auth0Mcp = createAuth0Mcp ( ) ;
12+ export default auth0Mcp ;
613
714export function createAuth0Mcp ( ) {
815 const verify = createVerifier ( ) ;
916 const requireScopes = createScopeValidator ( verify ) ;
1017
1118 return {
19+ /**
20+ * Wraps an MCP tool handler to enforce required OAuth scopes.
21+ *
22+ * @example
23+ * ```typescript
24+ * // Require specific scopes
25+ * export default auth0Mcp.requireScopes(["tool:greet"], async (params, { authInfo }) => {
26+ * // Tool logic here
27+ * });
28+ *
29+ * // Authentication only (no scope validation)
30+ * export default auth0Mcp.requireScopes([], async (params, { authInfo }) => {
31+ * // Tool logic here - just needs authenticated user
32+ * });
33+ */
1234 requireScopes,
1335 } ;
1436}
@@ -102,19 +124,22 @@ function hasAllScopes(
102124function createScopeValidator ( verifyToken : ( token : string ) => Promise < Auth > ) {
103125 return function requireScopes < TParams , TReturn > (
104126 requiredScopes : readonly string [ ] ,
105- toolFunction : ( params : TParams ) => Promise < TReturn >
106- ) : ( params : TParams ) => Promise < TReturn > {
107- return async ( params : TParams ) => {
127+ toolFunction : (
128+ params : TParams ,
129+ context : { authInfo : Auth }
130+ ) => Promise < TReturn >
131+ ) : ( params : TParams , context : ToolExtraArguments ) => Promise < TReturn > {
132+ return async ( params : TParams , _context ) => {
108133 const header = headers ( ) ;
109134 const authHeader = header . authorization ;
110135
111136 if ( ! authHeader ) {
112- throw new Error ( "Missing authoirization header" ) ;
137+ throw new InvalidTokenError ( "Missing authorization header" ) ;
113138 }
114139
115140 const [ type , token ] = authHeader . split ( " " ) ;
116141 if ( type ?. toLocaleLowerCase ( ) !== "bearer" || ! token ) {
117- throw new Error ( "Invalid authorization header" ) ;
142+ throw new InvalidTokenError ( "Invalid authorization header" ) ;
118143 }
119144
120145 const decoded = await verifyToken ( token ) ;
@@ -124,10 +149,12 @@ function createScopeValidator(verifyToken: (token: string) => Promise<Auth>) {
124149 const missing = requiredScopes . filter (
125150 ( scope ) => ! userScopes . includes ( scope )
126151 ) ;
127- throw new Error ( `Missing required scopes: ${ missing . join ( ", " ) } .` ) ;
152+ throw new InsufficientScopeError (
153+ `Missing required scopes: ${ missing . join ( ", " ) } .`
154+ ) ;
128155 }
129156
130- return toolFunction ( params ) ;
157+ return toolFunction ( params , { authInfo : decoded } ) ;
131158 } ;
132159 } ;
133160}
0 commit comments