Skip to content

Commit 02140e2

Browse files
committed
Refactor http transport into separate file.
1 parent 0b0f485 commit 02140e2

2 files changed

Lines changed: 54 additions & 52 deletions

File tree

src/http-transport.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2+
import express from "express";
3+
import { Request, Response } from "express";
4+
import { server } from './server.js';
5+
6+
export async function runHttpServer(port: number): Promise<void> {
7+
// We return a new promise that never resolves to keep the server alive.
8+
return new Promise((resolve, reject) => {
9+
// Start a server based on the official @modelcontextprotocol/sdk documentation.
10+
const app = express();
11+
app.use(express.json());
12+
13+
app.post('/', async (req: Request, res: Response) => {
14+
// In stateless mode, create a new instance of transport and server for each request
15+
// to ensure complete isolation. A single instance would cause request ID collisions
16+
// when multiple clients connect concurrently.
17+
18+
try {
19+
const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
20+
sessionIdGenerator: undefined,
21+
});
22+
res.on('close', () => {
23+
transport.close();
24+
server.close();
25+
});
26+
await server.connect(transport);
27+
await transport.handleRequest(req, res, req.body);
28+
} catch (error) {
29+
console.error('Error handling MCP request:', error);
30+
if (!res.headersSent) {
31+
res.status(500).json({
32+
jsonrpc: '2.0',
33+
error: {
34+
code: -32603,
35+
message: 'Internal server error',
36+
},
37+
id: null,
38+
});
39+
}
40+
}
41+
});
42+
43+
// Start the server
44+
const httpServerInstance = app.listen(port, () => {
45+
console.log(`MCP Stateless Streamable HTTP Server listening on port ${port}`);
46+
});
47+
48+
httpServerInstance.on('error', (err) => {
49+
console.error(`HTTP Server failed to start or encountered an error: ${err.message}`);
50+
reject(err);
51+
});
52+
});
53+
}

src/index.ts

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#!/usr/bin/env node
22

33
import { FilteredStdioServerTransport } from './custom-stdio.js';
4-
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5-
import express from "express";
6-
import { Request, Response } from "express";
4+
import { runHttpServer } from './http-transport.js';
75
import { server } from './server.js';
86
import { configManager } from './config-manager.js';
97
import { join, dirname } from 'path';
@@ -140,55 +138,6 @@ async function runServer() {
140138
}
141139
}
142140

143-
async function runHttpServer(port: number) {
144-
// We return a new promise that never resolves to keep the server alive.
145-
return new Promise((resolve, reject) => {
146-
// Start a server based on the official @modelcontextprotocol/sdk documentation.
147-
const app = express();
148-
app.use(express.json());
149-
150-
app.post('/', async (req: Request, res: Response) => {
151-
// In stateless mode, create a new instance of transport and server for each request
152-
// to ensure complete isolation. A single instance would cause request ID collisions
153-
// when multiple clients connect concurrently.
154-
155-
try {
156-
const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
157-
sessionIdGenerator: undefined,
158-
});
159-
res.on('close', () => {
160-
transport.close();
161-
server.close();
162-
});
163-
await server.connect(transport);
164-
await transport.handleRequest(req, res, req.body);
165-
} catch (error) {
166-
console.error('Error handling MCP request:', error);
167-
if (!res.headersSent) {
168-
res.status(500).json({
169-
jsonrpc: '2.0',
170-
error: {
171-
code: -32603,
172-
message: 'Internal server error',
173-
},
174-
id: null,
175-
});
176-
}
177-
}
178-
});
179-
180-
// Start the server
181-
const httpServerInstance = app.listen(port, () => {
182-
console.log(`MCP Stateless Streamable HTTP Server listening on port ${port}`);
183-
});
184-
185-
httpServerInstance.on('error', (err) => {
186-
console.error(`HTTP Server failed to start or encountered an error: ${err.message}`);
187-
reject(err);
188-
});
189-
});
190-
}
191-
192141
async function runStdioServer() {
193142
console.error("Connecting server through stdio transport ...");
194143
const transport = new FilteredStdioServerTransport();

0 commit comments

Comments
 (0)