1+ import { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js' ;
12import { z , ZodTypeAny } from 'zod' ;
23import { BaseTool , OutputSchema } from './BaseTool.js' ;
34
@@ -17,14 +18,19 @@ export abstract class MapboxApiBasedTool<
1718 * Mapbox tokens are JWT tokens where the payload contains the username.
1819 * @throws Error if the token is not set, invalid, or doesn't contain username
1920 */
20- static getUserNameFromToken ( ) : string {
21- if ( ! MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN ) {
22- throw new Error ( 'MAPBOX_ACCESS_TOKEN is not set' ) ;
21+ static getUserNameFromToken ( access_token ?: string ) : string {
22+ if ( ! access_token ) {
23+ if ( ! MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN ) {
24+ throw new Error (
25+ 'No access token provided. Please set MAPBOX_ACCESS_TOKEN environment variable or pass it as an argument.'
26+ ) ;
27+ }
28+ access_token = MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN ;
2329 }
2430
2531 try {
2632 // JWT format: header.payload.signature
27- const parts = MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN . split ( '.' ) ;
33+ const parts = access_token . split ( '.' ) ;
2834 if ( parts . length !== 3 ) {
2935 throw new Error ( 'MAPBOX_ACCESS_TOKEN is not in valid JWT format' ) ;
3036 }
@@ -68,19 +74,30 @@ export abstract class MapboxApiBasedTool<
6874 /**
6975 * Validates Mapbox token and runs the tool logic.
7076 */
71- async run ( rawInput : unknown ) : Promise < z . infer < typeof OutputSchema > > {
77+ async run (
78+ rawInput : unknown ,
79+ extra ?: RequestHandlerExtra < any , any >
80+ ) : Promise < z . infer < typeof OutputSchema > > {
7281 try {
73- if ( ! MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN ) {
74- throw new Error ( 'MAPBOX_ACCESS_TOKEN is not set' ) ;
82+ // First check if token is provided via authentication context
83+ // Check both standard token field and accessToken in extra for compatibility
84+ // In the streamableHttp, the authInfo is injected into extra from `req.auth`
85+ // https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/server/streamableHttp.ts#L405
86+ const authToken = extra ?. authInfo ?. token ;
87+ const accessToken = authToken || MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN ;
88+ if ( ! accessToken ) {
89+ throw new Error (
90+ 'No access token available. Please provide via Bearer auth or MAPBOX_ACCESS_TOKEN env var'
91+ ) ;
7592 }
7693
7794 // Validate that the token has the correct JWT format
78- if ( ! this . isValidJwtFormat ( MapboxApiBasedTool . MAPBOX_ACCESS_TOKEN ) ) {
95+ if ( ! this . isValidJwtFormat ( accessToken ) ) {
7996 throw new Error ( 'MAPBOX_ACCESS_TOKEN is not in valid JWT format' ) ;
8097 }
8198
8299 // Call parent run method which handles the rest
83- return await super . run ( rawInput ) ;
100+ return await super . run ( rawInput , extra ) ;
84101 } catch ( error ) {
85102 const errorMessage =
86103 error instanceof Error ? error . message : String ( error ) ;
0 commit comments