88 type ToolResult ,
99 GeminiChat ,
1010} from '@google/gemini-cli-core' ;
11+ // isInitializeRequest 在这种模式下不再需要
1112import {
1213 type CallToolResult ,
13- isInitializeRequest ,
1414} from '@modelcontextprotocol/sdk/types.js' ;
1515import {
1616 type PartUnion ,
@@ -22,7 +22,6 @@ import { randomUUID } from 'node:crypto';
2222
2323const LOG_PREFIX = '[MCP SERVER]' ;
2424
25- // Simplified request logger - only log on debug mode
2625const requestLogger = ( debugMode : boolean ) => ( req : Request , res : Response , next : NextFunction ) => {
2726 if ( debugMode ) {
2827 console . log ( `${ LOG_PREFIX } ${ req . method } ${ req . url } ` ) ;
@@ -35,6 +34,8 @@ export class GcliMcpBridge {
3534 private readonly cliVersion : string ;
3635 private readonly mcpServer : McpServer ;
3736 private readonly debugMode : boolean ;
37+ // 将 transport 提升为类的成员
38+ private transport : StreamableHTTPServerTransport | undefined ;
3839
3940 constructor ( config : Config , cliVersion : string , debugMode = false ) {
4041 this . config = config ;
@@ -52,72 +53,32 @@ export class GcliMcpBridge {
5253 public async start ( app : Application ) {
5354 await this . registerAllGcliTools ( ) ;
5455
55- // Only use request logger in debug mode
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+ } ) ;
5965
60- const transports : Record < string , StreamableHTTPServerTransport > = { } ;
66+ // 2. 在 start 方法中只连接一次
67+ await this . mcpServer . connect ( this . transport ) ;
68+
69+ console . log ( `${ LOG_PREFIX } McpServer connected to the transport.` ) ;
6170
71+ // 3. 修改路由处理器,始终使用同一个 transport 实例
6272 app . all ( '/mcp' , async ( req : Request , res : Response ) => {
63- const sessionId = req . headers [ 'mcp-session-id' ] as string | undefined ;
64- let transport = sessionId ? transports [ sessionId ] : undefined ;
65-
66- if ( ! transport ) {
67- if ( isInitializeRequest ( req . body ) ) {
68- if ( this . debugMode ) {
69- console . log (
70- `${ LOG_PREFIX } Creating new transport for initialize request` ,
71- ) ;
72- }
73- transport = new StreamableHTTPServerTransport ( {
74- sessionIdGenerator : ( ) => randomUUID ( ) ,
75- onsessioninitialized : newSessionId => {
76- if ( this . debugMode ) {
77- console . log (
78- `${ LOG_PREFIX } Session initialized: ${ newSessionId } ` ,
79- ) ;
80- }
81- transports [ newSessionId ] = transport ! ;
82- } ,
83- } ) ;
84-
85- transport . onclose = ( ) => {
86- const sid = transport ! . sessionId ;
87- if ( sid && transports [ sid ] ) {
88- if ( this . debugMode ) {
89- console . log (
90- `${ LOG_PREFIX } Session ${ sid } closed` ,
91- ) ;
92- }
93- delete transports [ sid ] ;
94- }
95- } ;
96-
97- // Connect the new transport to the *existing* McpServer
98- await this . mcpServer . connect ( transport ) ;
99- } else {
100- console . error (
101- `${ LOG_PREFIX } Bad Request: Missing or invalid session ID` ,
102- ) ;
103- res . status ( 400 ) . json ( {
104- jsonrpc : '2.0' ,
105- error : {
106- code : - 32000 ,
107- message : 'Bad Request: Missing or invalid session ID.' ,
108- } ,
109- id : null ,
110- } ) ;
111- return ;
112- }
113- } else if ( this . debugMode ) {
114- console . log (
115- `${ LOG_PREFIX } Reusing transport for session: ${ sessionId } ` ,
116- ) ;
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 ;
11777 }
118-
78+
11979 try {
120- await transport . handleRequest ( req , res , req . body ) ;
80+ // handleRequest 方法能够处理并发请求
81+ await this . transport . handleRequest ( req , res , req . body ) ;
12182 } catch ( e ) {
12283 console . error ( `${ LOG_PREFIX } Error handling request:` , e ) ;
12384 if ( ! res . headersSent ) {
0 commit comments