@@ -13,7 +13,7 @@ const execFileAsync = promisify(execFile);
1313const CUSTOM_PREFIX = process . env . CUSTOM_PREFIX || '' ;
1414const INTERNAL_PORT = parseInt ( process . env . INTERNAL_PORT || '8080' , 10 ) ;
1515
16- // Basic timestamped logging
16+ // Timestamped logging
1717function log ( ...args ) {
1818 const ts = new Date ( ) . toISOString ( ) ;
1919 console . log ( `[${ ts } ]` , ...args ) ;
@@ -29,7 +29,7 @@ function buildPrefixed(url) {
2929const app = express ( ) ;
3030app . use ( express . json ( ) ) ;
3131
32- // CORS allowing any origin; expose Mcp-Session-Id header for browser clients
32+ // CORS: expose session header for browser-based clients
3333app . use (
3434 cors ( {
3535 origin : '*' ,
@@ -43,7 +43,7 @@ app.use(
4343const transports = new Map ( ) ;
4444
4545// Helper: read session id from header or from query (?session=...)
46- // This improves compatibility with clients that cannot attach custom headers.
46+ // Improves compatibility with clients that can’t attach custom headers.
4747function getSessionId ( req ) {
4848 const h = req . headers [ 'mcp-session-id' ] ;
4949 const fromHeader = Array . isArray ( h ) ? h [ 0 ] : h ;
@@ -71,7 +71,7 @@ function createMcpServer() {
7171 // Log the request info
7272 log ( `[tool:read_web_url] request` , { originalUrl : url , prefixedUrl : prefixed } ) ;
7373
74- // Use a sentinel marker so we can capture HTTP status without logging/returning the body
74+ // Append HTTP status at end of stdout so we can log it without logging the body
7575 const STATUS_MARKER = '<<<MCP_HTTP_STATUS:' ;
7676 const STATUS_END = '>>>' ;
7777
@@ -81,15 +81,11 @@ function createMcpServer() {
8181 [
8282 '-sL' ,
8383 '--fail' ,
84- // Follow redirects and fetch content
8584 prefixed ,
86- // Append final HTTP status code to stdout after the body
8785 '-w' ,
8886 `\n${ STATUS_MARKER } %{http_code}${ STATUS_END } `
8987 ] ,
90- {
91- maxBuffer : 25 * 1024 * 1024 // 25 MiB cap
92- }
88+ { maxBuffer : 25 * 1024 * 1024 }
9389 ) ;
9490
9591 // Split body and status using the marker
@@ -100,9 +96,7 @@ function createMcpServer() {
10096 body = stdout . slice ( 0 , idx ) ;
10197 const tail = stdout . slice ( idx + STATUS_MARKER . length ) ;
10298 const endIdx = tail . indexOf ( STATUS_END ) ;
103- if ( endIdx !== - 1 ) {
104- httpCode = tail . slice ( 0 , endIdx ) . trim ( ) ;
105- }
99+ if ( endIdx !== - 1 ) httpCode = tail . slice ( 0 , endIdx ) . trim ( ) ;
106100 }
107101
108102 // Log summary without printing the response body
@@ -114,7 +108,6 @@ function createMcpServer() {
114108
115109 return { content : [ { type : 'text' , text : body } ] } ;
116110 } catch ( err ) {
117- // Log error details but not the response body
118111 const msg =
119112 err && typeof err === 'object' && 'stderr' in err && err . stderr
120113 ? String ( err . stderr )
@@ -141,27 +134,32 @@ app.post('/mcp', async (req, res) => {
141134 const isInit = method === 'initialize' ;
142135 log ( `[mcp] POST` , { method, sessionId : sessionId || null , isInit } ) ;
143136
144- // Create a new session if:
145- // - The request is initialize, or
146- // - No session was provided (compat mode for clients that don't initialize explicitly)
137+ // Create a new session for initialize OR when no session is provided (compat mode)
147138 if ( ! transport && ( isInit || ! sessionId ) ) {
148139 log ( `[mcp] creating new session` ) ;
140+
141+ // Pre-generate an ID so we can safely set the header immediately
142+ const newSessionId = randomUUID ( ) ;
143+
149144 transport = new StreamableHTTPServerTransport ( {
150- sessionIdGenerator : ( ) => randomUUID ( )
151- // Optionally: allowedOrigins / allowedHosts for hardened deployments
145+ sessionIdGenerator : ( ) => newSessionId
152146 } ) ;
153147
154148 const server = createMcpServer ( ) ;
149+
155150 transport . onclose = ( ) => {
156151 if ( transport . sessionId ) transports . delete ( transport . sessionId ) ;
157152 server . close ( ) ;
158- log ( `[mcp] session closed` , { sessionId : transport . sessionId || null } ) ;
153+ log ( `[mcp] session closed` , { sessionId : transport . sessionId || newSessionId } ) ;
159154 } ;
160155
161156 await server . connect ( transport ) ;
162- transports . set ( transport . sessionId , transport ) ;
163- sessionId = transport . sessionId ;
164- res . setHeader ( 'Mcp-Session-Id' , sessionId ) ;
157+
158+ // Store and advertise the session
159+ transports . set ( newSessionId , transport ) ;
160+ sessionId = newSessionId ;
161+ if ( sessionId ) res . setHeader ( 'Mcp-Session-Id' , sessionId ) ;
162+
165163 log ( `[mcp] session created` , { sessionId } ) ;
166164 }
167165
@@ -175,7 +173,7 @@ app.post('/mcp', async (req, res) => {
175173 }
176174
177175 // Always expose session ID for clients to persist it
178- res . setHeader ( 'Mcp-Session-Id' , sessionId ) ;
176+ if ( sessionId ) res . setHeader ( 'Mcp-Session-Id' , sessionId ) ;
179177
180178 // Hand off to the transport
181179 await transport . handleRequest ( req , res , body ) ;
@@ -208,7 +206,7 @@ app.delete('/mcp', async (req, res) => {
208206 res . status ( 204 ) . end ( ) ;
209207} ) ;
210208
211- // Simple health endpoint
209+ // Health endpoint
212210app . get ( '/' , ( _req , res ) => {
213211 res . json ( {
214212 status : 'ok' ,
0 commit comments