Skip to content

Commit a45e73a

Browse files
refactor: 为每个会话创建独立的 McpServer 实例
Co-authored-by: aider (vertex_ai/gemini-2.5-pro) <aider@aider.chat>
1 parent 8f47476 commit a45e73a

File tree

1 file changed

+44
-33
lines changed

1 file changed

+44
-33
lines changed

packages/mcp-server/src/bridge/bridge.ts

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,77 +32,88 @@ const requestLogger = (debugMode: boolean) => (req: Request, res: Response, next
3232
export class GcliMcpBridge {
3333
private readonly config: Config;
3434
private readonly cliVersion: string;
35-
private readonly mcpServer: McpServer;
3635
private readonly debugMode: boolean;
37-
// **修改 1: 创建一个 Map 来存储每个会话的 transport 实例**
38-
private readonly transports: Record<string, StreamableHTTPServerTransport> = {};
36+
// **修改 2: 更新 transports 的类型以存储每个会话的 McpServer 和 Transport**
37+
private readonly sessions: Record<
38+
string,
39+
{ mcpServer: McpServer; transport: StreamableHTTPServerTransport }
40+
> = {};
3941

4042
constructor(config: Config, cliVersion: string, debugMode = false) {
4143
this.config = config;
4244
this.cliVersion = cliVersion;
4345
this.debugMode = debugMode;
44-
this.mcpServer = new McpServer(
46+
}
47+
48+
// **辅助方法:创建一个新的 McpServer 实例**
49+
private createNewMcpServer(): McpServer {
50+
const server = new McpServer(
4551
{
4652
name: 'gemini-cli-mcp-server',
4753
version: this.cliVersion,
4854
},
4955
{ capabilities: { tools: { listChanged: true }, logging: {} } },
5056
);
57+
// 在这里立即注册所有工具
58+
this.registerAllGcliTools(server);
59+
return server;
5160
}
5261

5362
public async start(app: Application) {
54-
await this.registerAllGcliTools();
5563

5664
if (this.debugMode) {
5765
app.use(requestLogger(this.debugMode));
5866
}
5967

60-
// **修改 2: 更新路由处理器以管理多个 transport**
6168
app.all('/mcp', async (req: Request, res: Response) => {
6269
const sessionId = req.headers['mcp-session-id'] as string | undefined;
63-
let transport: StreamableHTTPServerTransport | undefined = sessionId ? this.transports[sessionId] : undefined;
6470

65-
if (!transport) {
66-
// 如果没有找到 transport,并且这是一个新的 initialize 请求,则创建一个新的
71+
// **修改 5: 从 `sessions` map 中获取会话对象**
72+
let session = sessionId ? this.sessions[sessionId] : undefined;
73+
74+
if (!session) {
6775
if (isInitializeRequest(req.body)) {
6876
if (this.debugMode) {
6977
console.log(
70-
`${LOG_PREFIX} Creating new transport for initialize request`,
78+
`${LOG_PREFIX} Creating new session and transport for initialize request`,
7179
);
7280
}
73-
74-
transport = new StreamableHTTPServerTransport({
81+
82+
// **修改 6: 为新会话创建独立的 McpServer 和 Transport**
83+
const newMcpServer = this.createNewMcpServer();
84+
const newTransport = new StreamableHTTPServerTransport({
7585
sessionIdGenerator: () => randomUUID(),
76-
onsessioninitialized: newSessionId => {
86+
onsessioninitialized: (newSessionId) => {
7787
if (this.debugMode) {
7888
console.log(
7989
`${LOG_PREFIX} Session initialized: ${newSessionId}`,
8090
);
8191
}
82-
// 将新的 transport 实例存储在 Map 中
83-
if (transport) {
84-
this.transports[newSessionId] = transport;
85-
}
92+
// 存储新的会话对象
93+
this.sessions[newSessionId] = {
94+
mcpServer: newMcpServer,
95+
transport: newTransport,
96+
};
8697
},
8798
});
8899

89-
// 当连接关闭时,从 Map 中移除 transport
90-
transport.onclose = () => {
91-
const sid = transport!.sessionId;
92-
if (sid && this.transports[sid]) {
100+
newTransport.onclose = () => {
101+
const sid = newTransport.sessionId;
102+
if (sid && this.sessions[sid]) {
93103
if (this.debugMode) {
94104
console.log(
95-
`${LOG_PREFIX} Session ${sid} closed, removing transport.`,
105+
`${LOG_PREFIX} Session ${sid} closed, removing session object.`,
96106
);
97107
}
98-
delete this.transports[sid];
108+
delete this.sessions[sid];
99109
}
100110
};
101111

102-
// 将新的 transport 连接到我们唯一的 McpServer 实例
103-
await this.mcpServer.connect(transport);
112+
// 将新的 transport 连接到新的 McpServer 实例
113+
await newMcpServer.connect(newTransport);
114+
115+
session = { mcpServer: newMcpServer, transport: newTransport };
104116
} else {
105-
// 如果请求没有 session ID 但又不是 initialize 请求,则为错误请求
106117
console.error(
107118
`${LOG_PREFIX} Bad Request: Missing session ID for non-initialize request.`,
108119
);
@@ -118,13 +129,13 @@ export class GcliMcpBridge {
118129
}
119130
} else if (this.debugMode) {
120131
console.log(
121-
`${LOG_PREFIX} Reusing transport for session: ${sessionId}`,
132+
`${LOG_PREFIX} Reusing transport and server for session: ${sessionId}`,
122133
);
123134
}
124135

125-
// 使用找到的或新创建的 transport 处理请求
126136
try {
127-
await transport.handleRequest(req, res, req.body);
137+
// **修改 7: 使用会话特定的 transport 来处理请求**
138+
await session.transport.handleRequest(req, res, req.body);
128139
} catch (e) {
129140
console.error(`${LOG_PREFIX} Error handling request:`, e);
130141
if (!res.headersSent) {
@@ -134,18 +145,18 @@ export class GcliMcpBridge {
134145
});
135146
}
136147

137-
private async registerAllGcliTools() {
148+
private async registerAllGcliTools(mcpServer: McpServer) {
138149
const toolRegistry = await this.config.getToolRegistry();
139150
const allTools = toolRegistry.getAllTools();
140151
for (const tool of allTools) {
141-
this.registerGcliTool(tool);
152+
this.registerGcliTool(tool, mcpServer);
142153
}
143154
}
144155

145-
private registerGcliTool(tool: GcliTool) {
156+
private registerGcliTool(tool: GcliTool, mcpServer: McpServer) {
146157
const inputSchema = this.convertJsonSchemaToZod(tool.schema.parameters);
147158

148-
this.mcpServer.registerTool(
159+
mcpServer.registerTool(
149160
tool.name,
150161
{
151162
title: tool.displayName,

0 commit comments

Comments
 (0)