chore: refactor server, prepare for browser reuse (#490)
This commit is contained in:
@@ -22,18 +22,13 @@ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
||||
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
||||
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
||||
|
||||
import { createConnection } from './connection.js';
|
||||
import type { Server } from './server.js';
|
||||
|
||||
import type { Connection } from './connection.js';
|
||||
import type { FullConfig } from './config.js';
|
||||
|
||||
export async function startStdioTransport(config: FullConfig, connectionList: Connection[]) {
|
||||
const connection = await createConnection(config);
|
||||
await connection.connect(new StdioServerTransport());
|
||||
connectionList.push(connection);
|
||||
export async function startStdioTransport(server: Server) {
|
||||
await server.createConnection(new StdioServerTransport());
|
||||
}
|
||||
|
||||
async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse, url: URL, sessions: Map<string, SSEServerTransport>, connectionList: Connection[]) {
|
||||
async function handleSSE(server: Server, req: http.IncomingMessage, res: http.ServerResponse, url: URL, sessions: Map<string, SSEServerTransport>) {
|
||||
if (req.method === 'POST') {
|
||||
const sessionId = url.searchParams.get('sessionId');
|
||||
if (!sessionId) {
|
||||
@@ -51,15 +46,11 @@ async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: htt
|
||||
} else if (req.method === 'GET') {
|
||||
const transport = new SSEServerTransport('/sse', res);
|
||||
sessions.set(transport.sessionId, transport);
|
||||
const connection = await createConnection(config);
|
||||
await connection.connect(transport);
|
||||
connectionList.push(connection);
|
||||
const connection = await server.createConnection(transport);
|
||||
res.on('close', () => {
|
||||
sessions.delete(transport.sessionId);
|
||||
connection.close().catch(e => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(e);
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
void connection.close().catch(e => console.error(e));
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -68,7 +59,7 @@ async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: htt
|
||||
res.end('Method not allowed');
|
||||
}
|
||||
|
||||
async function handleStreamable(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse, sessions: Map<string, StreamableHTTPServerTransport>, connectionList: Connection[]) {
|
||||
async function handleStreamable(server: Server, req: http.IncomingMessage, res: http.ServerResponse, sessions: Map<string, StreamableHTTPServerTransport>) {
|
||||
const sessionId = req.headers['mcp-session-id'] as string | undefined;
|
||||
if (sessionId) {
|
||||
const transport = sessions.get(sessionId);
|
||||
@@ -91,12 +82,8 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r
|
||||
if (transport.sessionId)
|
||||
sessions.delete(transport.sessionId);
|
||||
};
|
||||
const connection = await createConnection(config);
|
||||
connectionList.push(connection);
|
||||
await Promise.all([
|
||||
connection.connect(transport),
|
||||
transport.handleRequest(req, res),
|
||||
]);
|
||||
await server.createConnection(transport);
|
||||
await transport.handleRequest(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,15 +91,15 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r
|
||||
res.end('Invalid request');
|
||||
}
|
||||
|
||||
export function startHttpTransport(config: FullConfig, port: number, hostname: string | undefined, connectionList: Connection[]) {
|
||||
export function startHttpTransport(server: Server, port: number, hostname: string | undefined) {
|
||||
const sseSessions = new Map<string, SSEServerTransport>();
|
||||
const streamableSessions = new Map<string, StreamableHTTPServerTransport>();
|
||||
const httpServer = http.createServer(async (req, res) => {
|
||||
const url = new URL(`http://localhost${req.url}`);
|
||||
if (url.pathname.startsWith('/mcp'))
|
||||
await handleStreamable(config, req, res, streamableSessions, connectionList);
|
||||
await handleStreamable(server, req, res, streamableSessions);
|
||||
else
|
||||
await handleSSE(config, req, res, url, sseSessions, connectionList);
|
||||
await handleSSE(server, req, res, url, sseSessions);
|
||||
});
|
||||
httpServer.listen(port, hostname, () => {
|
||||
const address = httpServer.address();
|
||||
|
||||
Reference in New Issue
Block a user