Skip to content

Commit e8d5e09

Browse files
authored
Merge pull request #428 from cliffhall/allow-multiple-client-connections
Allow multiple instances of the Inspector to connect to the same MCP server
2 parents 029d2de + a7aa726 commit e8d5e09

File tree

1 file changed

+28
-30
lines changed

1 file changed

+28
-30
lines changed

server/src/index.ts

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ app.use((req, res, next) => {
4848
next();
4949
});
5050

51-
const webAppTransports: Map<string, Transport> = new Map<string, Transport>(); // Transports by sessionId
51+
const webAppTransports: Map<string, Transport> = new Map<string, Transport>(); // Web app transports by web app sessionId
52+
const serverTransports: Map<string, Transport> = new Map<string, Transport>(); // Server Transports by web app sessionId
5253

5354
const createTransport = async (req: express.Request): Promise<Transport> => {
5455
const query = req.query;
@@ -137,8 +138,6 @@ const createTransport = async (req: express.Request): Promise<Transport> => {
137138
}
138139
};
139140

140-
let backingServerTransport: Transport | undefined;
141-
142141
app.get("/mcp", async (req, res) => {
143142
const sessionId = req.headers["mcp-session-id"] as string;
144143
console.log(`Received GET message for sessionId ${sessionId}`);
@@ -161,12 +160,12 @@ app.get("/mcp", async (req, res) => {
161160
app.post("/mcp", async (req, res) => {
162161
const sessionId = req.headers["mcp-session-id"] as string | undefined;
163162
console.log(`Received POST message for sessionId ${sessionId}`);
163+
let serverTransport: Transport | undefined;
164164
if (!sessionId) {
165165
try {
166166
console.log("New streamable-http connection");
167167
try {
168-
await backingServerTransport?.close();
169-
backingServerTransport = await createTransport(req);
168+
serverTransport = await createTransport(req);
170169
} catch (error) {
171170
if (error instanceof SseError && error.code === 401) {
172171
console.error(
@@ -180,12 +179,13 @@ app.post("/mcp", async (req, res) => {
180179
throw error;
181180
}
182181

183-
console.log("Connected MCP client to backing server transport");
182+
console.log("Connected MCP client to server transport");
184183

185184
const webAppTransport = new StreamableHTTPServerTransport({
186185
sessionIdGenerator: randomUUID,
187186
onsessioninitialized: (sessionId) => {
188187
webAppTransports.set(sessionId, webAppTransport);
188+
serverTransports.set(sessionId, serverTransport!);
189189
console.log("Created streamable web app transport " + sessionId);
190190
},
191191
});
@@ -194,7 +194,7 @@ app.post("/mcp", async (req, res) => {
194194

195195
mcpProxy({
196196
transportToClient: webAppTransport,
197-
transportToServer: backingServerTransport,
197+
transportToServer: serverTransport,
198198
});
199199

200200
await (webAppTransport as StreamableHTTPServerTransport).handleRequest(
@@ -229,10 +229,9 @@ app.post("/mcp", async (req, res) => {
229229
app.get("/stdio", async (req, res) => {
230230
try {
231231
console.log("New connection");
232-
232+
let serverTransport: Transport | undefined;
233233
try {
234-
await backingServerTransport?.close();
235-
backingServerTransport = await createTransport(req);
234+
serverTransport = await createTransport(req);
236235
} catch (error) {
237236
if (error instanceof SseError && error.code === 401) {
238237
console.error(
@@ -250,26 +249,24 @@ app.get("/stdio", async (req, res) => {
250249

251250
const webAppTransport = new SSEServerTransport("/message", res);
252251
webAppTransports.set(webAppTransport.sessionId, webAppTransport);
253-
254-
console.log("Created web app transport");
252+
serverTransports.set(webAppTransport.sessionId, serverTransport);
253+
console.log("Created client/server transports");
255254

256255
await webAppTransport.start();
257-
(backingServerTransport as StdioClientTransport).stderr!.on(
258-
"data",
259-
(chunk) => {
260-
webAppTransport.send({
261-
jsonrpc: "2.0",
262-
method: "notifications/stderr",
263-
params: {
264-
content: chunk.toString(),
265-
},
266-
});
267-
},
268-
);
256+
257+
(serverTransport as StdioClientTransport).stderr!.on("data", (chunk) => {
258+
webAppTransport.send({
259+
jsonrpc: "2.0",
260+
method: "notifications/stderr",
261+
params: {
262+
content: chunk.toString(),
263+
},
264+
});
265+
});
269266

270267
mcpProxy({
271268
transportToClient: webAppTransport,
272-
transportToServer: backingServerTransport,
269+
transportToServer: serverTransport,
273270
});
274271

275272
console.log("Set up MCP proxy");
@@ -284,10 +281,9 @@ app.get("/sse", async (req, res) => {
284281
console.log(
285282
"New SSE connection. NOTE: The sse transport is deprecated and has been replaced by streamable-http",
286283
);
287-
284+
let serverTransport: Transport | undefined;
288285
try {
289-
await backingServerTransport?.close();
290-
backingServerTransport = await createTransport(req);
286+
serverTransport = await createTransport(req);
291287
} catch (error) {
292288
if (error instanceof SseError && error.code === 401) {
293289
console.error(
@@ -305,13 +301,15 @@ app.get("/sse", async (req, res) => {
305301

306302
const webAppTransport = new SSEServerTransport("/message", res);
307303
webAppTransports.set(webAppTransport.sessionId, webAppTransport);
308-
console.log("Created web app transport");
304+
console.log("Created client transport");
305+
serverTransports.set(webAppTransport.sessionId, serverTransport);
306+
console.log("Created server transport");
309307

310308
await webAppTransport.start();
311309

312310
mcpProxy({
313311
transportToClient: webAppTransport,
314-
transportToServer: backingServerTransport,
312+
transportToServer: serverTransport,
315313
});
316314

317315
console.log("Set up MCP proxy");

0 commit comments

Comments
 (0)