@@ -12,13 +12,11 @@ import {
1212 EventStore ,
1313 EventId ,
1414 StreamId ,
15- AuthenticatedRequest ,
1615 SessionStore ,
1716 SessionState
1817} from './fetchStreamableHttpServerTransport.js' ;
1918import { McpServer } from '../../server/mcp.js' ;
2019import { CallToolResult , JSONRPCMessage } from '../../types.js' ;
21- import { AuthInfo } from '../../server/auth/types.js' ;
2220import { zodTestMatrix , type ZodMatrixEntry } from '../../__fixtures__/zodTestMatrix.js' ;
2321
2422async function getFreePort ( ) {
@@ -270,70 +268,6 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
270268 const baseUrl = `http://127.0.0.1:${ ( server . address ( ) as AddressInfo ) . port } ` ;
271269 const webRequest = await nodeRequestToWebRequest ( req , baseUrl ) ;
272270
273- // Handle with transport
274- const webResponse = await transport . handleRequest ( webRequest as AuthenticatedRequest ) ;
275-
276- // Convert Web Standard Response to Node.js response
277- webResponseToNodeResponse ( webResponse , res ) ;
278- } catch ( error ) {
279- console . error ( 'Error handling request:' , error ) ;
280- if ( ! res . headersSent ) res . writeHead ( 500 ) . end ( ) ;
281- }
282- } ) ;
283-
284- const baseUrl = await new Promise < URL > ( resolve => {
285- // Use specified port or 0 for random port
286- server . listen ( config . port ?? 0 , '127.0.0.1' , ( ) => {
287- const addr = server . address ( ) as AddressInfo ;
288- resolve ( new URL ( `http://127.0.0.1:${ addr . port } ` ) ) ;
289- } ) ;
290- } ) ;
291-
292- return { server, transport, mcpServer, baseUrl } ;
293- }
294-
295- /**
296- * Helper to create and start authenticated test HTTP server with MCP setup
297- */
298- async function createTestAuthServer ( config : TestServerConfig = { sessionIdGenerator : ( ) => crypto . randomUUID ( ) } ) : Promise < {
299- server : Server ;
300- transport : FetchStreamableHTTPServerTransport ;
301- mcpServer : McpServer ;
302- baseUrl : URL ;
303- } > {
304- const mcpServer = new McpServer ( { name : 'test-server' , version : '1.0.0' } , { capabilities : { logging : { } } } ) ;
305-
306- mcpServer . tool (
307- 'profile' ,
308- 'A user profile data tool' ,
309- { active : z . boolean ( ) . describe ( 'Profile status' ) } ,
310- async ( { active } , { authInfo } ) : Promise < CallToolResult > => {
311- return { content : [ { type : 'text' , text : `${ active ? 'Active' : 'Inactive' } profile from token: ${ authInfo ?. token } !` } ] } ;
312- }
313- ) ;
314-
315- const transport = new FetchStreamableHTTPServerTransport ( {
316- sessionIdGenerator : config . sessionIdGenerator ,
317- enableJsonResponse : config . enableJsonResponse ?? false ,
318- eventStore : config . eventStore ,
319- onsessioninitialized : config . onsessioninitialized ,
320- onsessionclosed : config . onsessionclosed
321- } ) ;
322-
323- await mcpServer . connect ( transport ) ;
324-
325- const server = createServer ( async ( req , res ) => {
326- try {
327- // Convert Node.js request to Web Standard Request
328- const baseUrl = `http://127.0.0.1:${ ( server . address ( ) as AddressInfo ) . port } ` ;
329- const webRequest = ( await nodeRequestToWebRequest ( req , baseUrl ) ) as AuthenticatedRequest ;
330-
331- // Add auth info from Authorization header
332- const authHeader = req . headers [ 'authorization' ] ;
333- if ( authHeader ?. startsWith ( 'Bearer ' ) ) {
334- webRequest . auth = { token : authHeader . split ( ' ' ) [ 1 ] } as AuthInfo ;
335- }
336-
337271 // Handle with transport
338272 const webResponse = await transport . handleRequest ( webRequest ) ;
339273
@@ -1058,105 +992,6 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
1058992 } ) ;
1059993 } ) ;
1060994
1061- describe ( 'FetchStreamableHTTPServerTransport with AuthInfo' , ( ) => {
1062- let server : Server ;
1063- let transport : FetchStreamableHTTPServerTransport ;
1064- let baseUrl : URL ;
1065- let sessionId : string ;
1066-
1067- beforeEach ( async ( ) => {
1068- const result = await createTestAuthServer ( ) ;
1069- server = result . server ;
1070- transport = result . transport ;
1071- baseUrl = result . baseUrl ;
1072- } ) ;
1073-
1074- afterEach ( async ( ) => {
1075- await stopTestServer ( { server, transport } ) ;
1076- } ) ;
1077-
1078- async function initializeServer ( ) : Promise < string > {
1079- const response = await sendPostRequest ( baseUrl , TEST_MESSAGES . initialize ) ;
1080-
1081- expect ( response . status ) . toBe ( 200 ) ;
1082- const newSessionId = response . headers . get ( 'mcp-session-id' ) ;
1083- expect ( newSessionId ) . toBeDefined ( ) ;
1084- return newSessionId as string ;
1085- }
1086-
1087- it ( 'should call a tool with authInfo' , async ( ) => {
1088- sessionId = await initializeServer ( ) ;
1089-
1090- const toolCallMessage : JSONRPCMessage = {
1091- jsonrpc : '2.0' ,
1092- method : 'tools/call' ,
1093- params : {
1094- name : 'profile' ,
1095- arguments : { active : true }
1096- } ,
1097- id : 'call-1'
1098- } ;
1099-
1100- const response = await sendPostRequest ( baseUrl , toolCallMessage , sessionId , { authorization : 'Bearer test-token' } ) ;
1101- expect ( response . status ) . toBe ( 200 ) ;
1102-
1103- const text = await readSSEEvent ( response ) ;
1104- const eventLines = text . split ( '\n' ) ;
1105- const dataLine = eventLines . find ( line => line . startsWith ( 'data:' ) ) ;
1106- expect ( dataLine ) . toBeDefined ( ) ;
1107-
1108- const eventData = JSON . parse ( dataLine ! . substring ( 5 ) ) ;
1109- expect ( eventData ) . toMatchObject ( {
1110- jsonrpc : '2.0' ,
1111- result : {
1112- content : [
1113- {
1114- type : 'text' ,
1115- text : 'Active profile from token: test-token!'
1116- }
1117- ]
1118- } ,
1119- id : 'call-1'
1120- } ) ;
1121- } ) ;
1122-
1123- it ( 'should calls tool without authInfo when it is optional' , async ( ) => {
1124- sessionId = await initializeServer ( ) ;
1125-
1126- const toolCallMessage : JSONRPCMessage = {
1127- jsonrpc : '2.0' ,
1128- method : 'tools/call' ,
1129- params : {
1130- name : 'profile' ,
1131- arguments : { active : false }
1132- } ,
1133- id : 'call-1'
1134- } ;
1135-
1136- const response = await sendPostRequest ( baseUrl , toolCallMessage , sessionId ) ;
1137- expect ( response . status ) . toBe ( 200 ) ;
1138-
1139- const text = await readSSEEvent ( response ) ;
1140- const eventLines = text . split ( '\n' ) ;
1141- const dataLine = eventLines . find ( line => line . startsWith ( 'data:' ) ) ;
1142- expect ( dataLine ) . toBeDefined ( ) ;
1143-
1144- const eventData = JSON . parse ( dataLine ! . substring ( 5 ) ) ;
1145- expect ( eventData ) . toMatchObject ( {
1146- jsonrpc : '2.0' ,
1147- result : {
1148- content : [
1149- {
1150- type : 'text' ,
1151- text : 'Inactive profile from token: undefined!'
1152- }
1153- ]
1154- } ,
1155- id : 'call-1'
1156- } ) ;
1157- } ) ;
1158- } ) ;
1159-
1160995 // Test JSON Response Mode
1161996 describe ( 'FetchStreamableHTTPServerTransport with JSON Response Mode' , ( ) => {
1162997 let server : Server ;
0 commit comments