@@ -6,6 +6,7 @@ import type { Request, Response } from "express";
66import express from "express" ;
77import { createServer as createHttpServer , Server as HttpServer } from "http" ;
88import { createServer as createNetServer } from "net" ;
9+ import { randomUUID } from "crypto" ;
910import * as z from "zod/v4" ;
1011import type { ServerConfig } from "./test-fixtures.js" ;
1112
@@ -187,22 +188,24 @@ export class TestServerHttp {
187188 }
188189
189190 /**
190- * Start the server with the specified transport
191+ * Start the server with the specified transport.
192+ * When requestedPort is omitted, uses port 0 so the OS assigns a unique port (avoids EADDRINUSE when tests run in parallel).
191193 */
192194 async start (
193195 transport : "http" | "sse" ,
194196 requestedPort ?: number ,
195197 ) : Promise < number > {
196- const port = requestedPort
197- ? await findAvailablePort ( requestedPort )
198- : await findAvailablePort ( transport === "http" ? 3001 : 3000 ) ;
199-
200- this . url = `http://localhost:${ port } ` ;
198+ const port =
199+ requestedPort !== undefined ? await findAvailablePort ( requestedPort ) : 0 ;
201200
202201 if ( transport === "http" ) {
203- return this . startHttp ( port ) ;
202+ const actualPort = await this . startHttp ( port ) ;
203+ this . url = `http://localhost:${ actualPort } ` ;
204+ return actualPort ;
204205 } else {
205- return this . startSse ( port ) ;
206+ const actualPort = await this . startSse ( port ) ;
207+ this . url = `http://localhost:${ actualPort } ` ;
208+ return actualPort ;
206209 }
207210 }
208211
@@ -213,8 +216,10 @@ export class TestServerHttp {
213216 // Create HTTP server
214217 this . httpServer = createHttpServer ( app ) ;
215218
216- // Create StreamableHTTP transport
217- this . transport = new StreamableHTTPServerTransport ( { } ) ;
219+ // Create StreamableHTTP transport (stateful so it can handle multiple requests per session)
220+ this . transport = new StreamableHTTPServerTransport ( {
221+ sessionIdGenerator : ( ) => randomUUID ( ) ,
222+ } ) ;
218223
219224 // Set up Express route to handle MCP requests
220225 app . post ( "/mcp" , async ( req : Request , res : Response ) => {
@@ -292,10 +297,12 @@ export class TestServerHttp {
292297 // Connect transport to server
293298 await this . mcpServer . connect ( this . transport ) ;
294299
295- // Start listening
300+ // Start listening (port 0 = OS assigns a unique port)
296301 return new Promise ( ( resolve , reject ) => {
297302 this . httpServer ! . listen ( port , ( ) => {
298- resolve ( port ) ;
303+ const assignedPort = ( this . httpServer ! . address ( ) as { port : number } )
304+ ?. port ;
305+ resolve ( assignedPort ?? port ) ;
299306 } ) ;
300307 this . httpServer ! . on ( "error" , reject ) ;
301308 } ) ;
@@ -371,10 +378,12 @@ export class TestServerHttp {
371378 // Note: SSE transport is created per request, so we don't store a single instance
372379 this . transport = undefined ;
373380
374- // Start listening
381+ // Start listening (port 0 = OS assigns a unique port)
375382 return new Promise ( ( resolve , reject ) => {
376383 this . httpServer ! . listen ( port , ( ) => {
377- resolve ( port ) ;
384+ const assignedPort = ( this . httpServer ! . address ( ) as { port : number } )
385+ ?. port ;
386+ resolve ( assignedPort ?? port ) ;
378387 } ) ;
379388 this . httpServer ! . on ( "error" , reject ) ;
380389 } ) ;
0 commit comments