From 9bb5dba95bee806ad9fb96e36abb24f315e9425a Mon Sep 17 00:00:00 2001 From: ale Date: Thu, 9 Oct 2025 00:57:33 +0200 Subject: [PATCH] mcp ai toolkit support Signed-off-by: ale --- src/http-server.ts | 47 +++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/http-server.ts b/src/http-server.ts index 35f55e5..215bbfe 100644 --- a/src/http-server.ts +++ b/src/http-server.ts @@ -460,13 +460,15 @@ export class CudaQuantumHttpServer { }); // ===== MCP JSON-RPC Endpoints ===== - // Main MCP endpoint for JSON-RPC requests + // Main MCP endpoint for JSON-RPC requests (root endpoint) + this.app.post('/', this.handleMcpJsonRpc.bind(this)); this.app.post('/mcp', this.handleMcpJsonRpc.bind(this)); this.app.post('/mcp/v1', this.handleMcpJsonRpc.bind(this)); - // MCP SSE endpoint for streaming - this.app.get('/mcp/sse', this.handleMcpSSE.bind(this)); + // MCP SSE endpoint for streaming (separate endpoint) this.app.get('/sse', this.handleMcpSSE.bind(this)); + this.app.get('/mcp/sse', this.handleMcpSSE.bind(this)); + this.app.get('/events', this.handleMcpSSE.bind(this)); // ===== Legacy REST API Endpoints (for backward compatibility) ===== // Quantum Kernels @@ -696,6 +698,8 @@ export class CudaQuantumHttpServer { private handleMcpSSE(req: Request, res: Response): void { const clientId = Math.random().toString(36).substring(2, 15); + this.logger.info(`MCP SSE client connecting: ${clientId}`); + // Setup SSE headers res.writeHead(200, { 'Content-Type': 'text/event-stream', @@ -714,36 +718,53 @@ export class CudaQuantumHttpServer { this.sseClients.set(clientId, client); - // Send initial connection event with MCP endpoint notification - const initMessage = { - type: 'endpoint', - uri: `/mcp`, - timestamp: new Date().toISOString() + // Send initial endpoint event - this is critical for MCP handshake + const protocol = req.protocol || 'https'; + const host = req.get('host') || 'localhost:3000'; + const baseUrl = `${protocol}://${host}`; + + const endpointMessage = { + jsonrpc: '2.0', + method: 'endpoint', + params: { + uri: baseUrl + } }; - res.write(`data: ${JSON.stringify(initMessage)}\n\n`); + + res.write(`event: endpoint\n`); + res.write(`data: ${JSON.stringify(endpointMessage)}\n\n`); + + this.logger.info(`Sent endpoint to client ${clientId}: ${baseUrl}`); - // Send keepalive every 30 seconds + // Send keepalive every 15 seconds const keepaliveInterval = setInterval(() => { if (this.sseClients.has(clientId)) { try { res.write(`: keepalive\n\n`); } catch (error) { + this.logger.warn(`Keepalive failed for client ${clientId}`); clearInterval(keepaliveInterval); this.sseClients.delete(clientId); } } else { clearInterval(keepaliveInterval); } - }, 30000); + }, 15000); // Handle client disconnect req.on('close', () => { clearInterval(keepaliveInterval); this.sseClients.delete(clientId); - this.logger.debug(`MCP SSE client ${clientId} disconnected`); + this.logger.info(`MCP SSE client ${clientId} disconnected`); }); - this.logger.debug(`MCP SSE client ${clientId} connected`); + req.on('error', (error) => { + this.logger.error(`MCP SSE client ${clientId} error:`, error); + clearInterval(keepaliveInterval); + this.sseClients.delete(clientId); + }); + + this.logger.info(`MCP SSE client ${clientId} connected successfully`); } /**