Skip to content

Commit 84c1f0b

Browse files
liconcso1z
authored andcommitted
fix(0.0.8) 修复Cursor报错:TypeError: terminated: Body Timeout Error Calling MCP tool ,参考modelcontextprotocol/typescript-sdk#270
1 parent 6f52d44 commit 84c1f0b

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

src/server.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,11 +807,57 @@ export class FeishuMcpServer {
807807

808808
async startHttpServer(port: number): Promise<void> {
809809
const app = express();
810+
const transports: {[sessionId: string]: SSEServerTransport} = {};
811+
const sseConnections = new Map<string, { res: Response, intervalId: NodeJS.Timeout }>();
812+
const KEEP_ALIVE_INTERVAL_MS = 25000; // Send keep-alive every 25 seconds
813+
810814

811815
app.get('/sse', async (_req: Request, res: Response) => {
812816
console.log('New SSE connection established');
813817
this.sseTransport = new SSEServerTransport('/messages', res as unknown as ServerResponse<IncomingMessage>);
814-
await this.server.connect(this.sseTransport);
818+
819+
const sessionId = this.sseTransport.sessionId; // Get session ID from transport
820+
transports[sessionId] = this.sseTransport;
821+
// Start keep-alive ping
822+
const intervalId = setInterval(() => {
823+
if (sseConnections.has(sessionId) && !res.writableEnded) {
824+
res.write(': keepalive\n\n');
825+
} else {
826+
// Should not happen if close handler is working, but clear just in case
827+
clearInterval(intervalId);
828+
sseConnections.delete(sessionId);
829+
}
830+
}, KEEP_ALIVE_INTERVAL_MS);
831+
// Store connection details
832+
sseConnections.set(sessionId, { res, intervalId });
833+
console.log(`[SSE Connection] Client connected: ${sessionId}, starting keep-alive.`);
834+
res.on("close", () => {
835+
console.log(`[SSE Connection] Client disconnected: ${sessionId}, stopping keep-alive.`);
836+
// Clean up transport
837+
delete transports[sessionId];
838+
// Clean up keep-alive interval
839+
const connection = sseConnections.get(sessionId);
840+
if (connection) {
841+
clearInterval(connection.intervalId);
842+
sseConnections.delete(sessionId);
843+
}
844+
});
845+
// Connect server to transport *after* setting up handlers
846+
try {
847+
await this.server.connect(this.sseTransport)
848+
} catch (error) {
849+
console.error(`[SSE Connection] Error connecting server to transport for ${sessionId}:`, error);
850+
// Ensure cleanup happens even if connect fails
851+
clearInterval(intervalId);
852+
sseConnections.delete(sessionId);
853+
delete transports[sessionId];
854+
if (!res.writableEnded) {
855+
res.status(500).end('Failed to connect MCP server to transport');
856+
}
857+
}
858+
859+
860+
// await this.server.connect(this.sseTransport);
815861
});
816862

817863
app.post('/messages', async (req: Request, res: Response) => {

0 commit comments

Comments
 (0)