11import { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types" ;
2- import { createMcpHandler , experimental_withMcpAuth as withMcpAuth } from "@vercel/mcp-adapter" ;
2+ import {
3+ createMcpHandler ,
4+ experimental_withMcpAuth as withMcpAuth ,
5+ } from "mcp-handler" ;
36import { z } from "zod" ;
47
58// Define the handler with proper parameter validation
69const handler = createMcpHandler (
7- server => {
10+ ( server ) => {
811 server . tool (
9- ' echo' ,
10- ' Echo a message back with authentication info' ,
12+ " echo" ,
13+ " Echo a message back with authentication info" ,
1114 {
12- message : z . string ( ) . describe ( ' The message to echo back' )
15+ message : z . string ( ) . describe ( " The message to echo back" ) ,
1316 } ,
1417 async ( { message } , extra ) => {
1518 return {
1619 content : [
1720 {
18- type : 'text' ,
19- text : `Echo: ${ message } ${ extra . authInfo ?. token ? ` (from ${ extra . authInfo . clientId } )` : '' } ` ,
21+ type : "text" ,
22+ text : `Echo: ${ message } ${
23+ extra . authInfo ?. token
24+ ? ` (from ${ extra . authInfo . clientId } )`
25+ : ""
26+ } `,
2027 } ,
2128 ] ,
2229 } ;
@@ -27,17 +34,17 @@ const handler = createMcpHandler(
2734 {
2835 capabilities : {
2936 auth : {
30- type : ' bearer' ,
37+ type : " bearer" ,
3138 required : true ,
3239 } ,
3340 } ,
3441 } ,
3542 // Route configuration
3643 {
37- streamableHttpEndpoint : ' /mcp' ,
38- sseEndpoint : ' /sse' ,
39- sseMessageEndpoint : ' /message' ,
40- basePath : ' /api/mcp' ,
44+ streamableHttpEndpoint : " /mcp" ,
45+ sseEndpoint : " /sse" ,
46+ sseMessageEndpoint : " /message" ,
47+ basePath : " /api/mcp" ,
4148 redisUrl : process . env . REDIS_URL ,
4249 }
4350) ;
@@ -46,38 +53,37 @@ const handler = createMcpHandler(
4653 * Verify the bearer token and return auth information
4754 * In a real implementation, this would validate against your auth service
4855 */
49- const verifyToken = async ( req : Request , bearerToken ?: string ) : Promise < AuthInfo | undefined > => {
50- if ( ! bearerToken ) return undefined ;
51-
52- // TODO: Replace with actual token verification logic
53- // This is just an example implementation
54- const isValid = bearerToken . startsWith ( '__TEST_VALUE__' ) ;
55-
56- if ( ! isValid ) return undefined ;
57-
58- return {
59- token : bearerToken ,
60- scopes : [ 'read:messages' , 'write:messages' ] ,
61- clientId : 'example-client' ,
62- extra : {
63- userId : 'user-123' ,
64- // Add any additional user/client information here
65- permissions : [ 'user' ] ,
66- timestamp : new Date ( ) . toISOString ( )
67- }
68- } ;
69- }
56+ const verifyToken = async (
57+ req : Request ,
58+ bearerToken ?: string
59+ ) : Promise < AuthInfo | undefined > => {
60+ if ( ! bearerToken ) return undefined ;
61+
62+ // TODO: Replace with actual token verification logic
63+ // This is just an example implementation
64+ const isValid = bearerToken . startsWith ( "__TEST_VALUE__" ) ;
65+
66+ if ( ! isValid ) return undefined ;
67+
68+ return {
69+ token : bearerToken ,
70+ scopes : [ "read:messages" , "write:messages" ] ,
71+ clientId : "example-client" ,
72+ extra : {
73+ userId : "user-123" ,
74+ // Add any additional user/client information here
75+ permissions : [ "user" ] ,
76+ timestamp : new Date ( ) . toISOString ( ) ,
77+ } ,
78+ } ;
79+ } ;
7080
7181// Create the auth handler with required scopes
72- const authHandler = withMcpAuth (
73- handler ,
74- verifyToken ,
75- {
76- required : true ,
77- requiredScopes : [ 'read:messages' ] ,
78- resourceMetadataPath : '/.well-known/oauth-protected-resource'
79- }
80- ) ;
82+ const authHandler = withMcpAuth ( handler , verifyToken , {
83+ required : true ,
84+ requiredScopes : [ "read:messages" ] ,
85+ resourceMetadataPath : "/.well-known/oauth-protected-resource" ,
86+ } ) ;
8187
8288// Export the handler for both GET and POST methods
8389export { authHandler as GET , authHandler as POST } ;
0 commit comments