88 type ToolResult ,
99 GeminiChat ,
1010} from '@google/gemini-cli-core' ;
11- // isInitializeRequest 在这种模式下不再需要
1211import {
1312 type CallToolResult ,
13+ isInitializeRequest ,
1414} from '@modelcontextprotocol/sdk/types.js' ;
1515import {
1616 type PartUnion ,
@@ -34,8 +34,8 @@ export class GcliMcpBridge {
3434 private readonly cliVersion : string ;
3535 private readonly mcpServer : McpServer ;
3636 private readonly debugMode : boolean ;
37- // 将 transport 提升为类的成员
38- private transport : StreamableHTTPServerTransport | undefined ;
37+ // **修改 1: 创建一个 Map 来存储每个会话的 transport 实例**
38+ private readonly transports : Record < string , StreamableHTTPServerTransport > = { } ;
3939
4040 constructor ( config : Config , cliVersion : string , debugMode = false ) {
4141 this . config = config ;
@@ -56,29 +56,75 @@ export class GcliMcpBridge {
5656 if ( this . debugMode ) {
5757 app . use ( requestLogger ( this . debugMode ) ) ;
5858 }
59-
60- // 1. 在 start 方法中只创建一次 transport
61- this . transport = new StreamableHTTPServerTransport ( {
62- // sessionIdGenerator 仍然是需要的,SDK 会用它来处理会话
63- sessionIdGenerator : ( ) => randomUUID ( ) ,
64- } ) ;
65-
66- // 2. 在 start 方法中只连接一次
67- await this . mcpServer . connect ( this . transport ) ;
68-
69- console . log ( `${ LOG_PREFIX } McpServer connected to the transport.` ) ;
7059
71- // 3. 修改路由处理器,始终使用同一个 transport 实例
60+ // **修改 2: 更新路由处理器以管理多个 transport**
7261 app . all ( '/mcp' , async ( req : Request , res : Response ) => {
73- if ( ! this . transport ) {
74- console . error ( `${ LOG_PREFIX } Transport is not initialized.` ) ;
75- res . status ( 500 ) . json ( { error : 'Server transport not available' } ) ;
76- return ;
62+ const sessionId = req . headers [ 'mcp-session-id' ] as string | undefined ;
63+ let transport : StreamableHTTPServerTransport | undefined = sessionId ? this . transports [ sessionId ] : undefined ;
64+
65+ if ( ! transport ) {
66+ // 如果没有找到 transport,并且这是一个新的 initialize 请求,则创建一个新的
67+ if ( isInitializeRequest ( req . body ) ) {
68+ if ( this . debugMode ) {
69+ console . log (
70+ `${ LOG_PREFIX } Creating new transport for initialize request` ,
71+ ) ;
72+ }
73+
74+ transport = new StreamableHTTPServerTransport ( {
75+ sessionIdGenerator : ( ) => randomUUID ( ) ,
76+ onsessioninitialized : newSessionId => {
77+ if ( this . debugMode ) {
78+ console . log (
79+ `${ LOG_PREFIX } Session initialized: ${ newSessionId } ` ,
80+ ) ;
81+ }
82+ // 将新的 transport 实例存储在 Map 中
83+ if ( transport ) {
84+ this . transports [ newSessionId ] = transport ;
85+ }
86+ } ,
87+ } ) ;
88+
89+ // 当连接关闭时,从 Map 中移除 transport
90+ transport . onclose = ( ) => {
91+ const sid = transport ! . sessionId ;
92+ if ( sid && this . transports [ sid ] ) {
93+ if ( this . debugMode ) {
94+ console . log (
95+ `${ LOG_PREFIX } Session ${ sid } closed, removing transport.` ,
96+ ) ;
97+ }
98+ delete this . transports [ sid ] ;
99+ }
100+ } ;
101+
102+ // 将新的 transport 连接到我们唯一的 McpServer 实例
103+ await this . mcpServer . connect ( transport ) ;
104+ } else {
105+ // 如果请求没有 session ID 但又不是 initialize 请求,则为错误请求
106+ console . error (
107+ `${ LOG_PREFIX } Bad Request: Missing session ID for non-initialize request.` ,
108+ ) ;
109+ res . status ( 400 ) . json ( {
110+ jsonrpc : '2.0' ,
111+ error : {
112+ code : - 32000 ,
113+ message : 'Bad Request: Mcp-Session-Id header is required' ,
114+ } ,
115+ id : null ,
116+ } ) ;
117+ return ;
118+ }
119+ } else if ( this . debugMode ) {
120+ console . log (
121+ `${ LOG_PREFIX } Reusing transport for session: ${ sessionId } ` ,
122+ ) ;
77123 }
78-
124+
125+ // 使用找到的或新创建的 transport 处理请求
79126 try {
80- // handleRequest 方法能够处理并发请求
81- await this . transport . handleRequest ( req , res , req . body ) ;
127+ await transport . handleRequest ( req , res , req . body ) ;
82128 } catch ( e ) {
83129 console . error ( `${ LOG_PREFIX } Error handling request:` , e ) ;
84130 if ( ! res . headersSent ) {
0 commit comments