mcp ai toolkit support

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-10-09 00:57:33 +02:00
padre e5e120de11
commit 9bb5dba95b

Ver fichero

@@ -460,13 +460,15 @@ export class CudaQuantumHttpServer {
}); });
// ===== MCP JSON-RPC Endpoints ===== // ===== 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', this.handleMcpJsonRpc.bind(this));
this.app.post('/mcp/v1', this.handleMcpJsonRpc.bind(this)); this.app.post('/mcp/v1', this.handleMcpJsonRpc.bind(this));
// MCP SSE endpoint for streaming // MCP SSE endpoint for streaming (separate endpoint)
this.app.get('/mcp/sse', this.handleMcpSSE.bind(this));
this.app.get('/sse', this.handleMcpSSE.bind(this)); 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) ===== // ===== Legacy REST API Endpoints (for backward compatibility) =====
// Quantum Kernels // Quantum Kernels
@@ -696,6 +698,8 @@ export class CudaQuantumHttpServer {
private handleMcpSSE(req: Request, res: Response): void { private handleMcpSSE(req: Request, res: Response): void {
const clientId = Math.random().toString(36).substring(2, 15); const clientId = Math.random().toString(36).substring(2, 15);
this.logger.info(`MCP SSE client connecting: ${clientId}`);
// Setup SSE headers // Setup SSE headers
res.writeHead(200, { res.writeHead(200, {
'Content-Type': 'text/event-stream', 'Content-Type': 'text/event-stream',
@@ -714,36 +718,53 @@ export class CudaQuantumHttpServer {
this.sseClients.set(clientId, client); this.sseClients.set(clientId, client);
// Send initial connection event with MCP endpoint notification // Send initial endpoint event - this is critical for MCP handshake
const initMessage = { const protocol = req.protocol || 'https';
type: 'endpoint', const host = req.get('host') || 'localhost:3000';
uri: `/mcp`, const baseUrl = `${protocol}://${host}`;
timestamp: new Date().toISOString()
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(() => { const keepaliveInterval = setInterval(() => {
if (this.sseClients.has(clientId)) { if (this.sseClients.has(clientId)) {
try { try {
res.write(`: keepalive\n\n`); res.write(`: keepalive\n\n`);
} catch (error) { } catch (error) {
this.logger.warn(`Keepalive failed for client ${clientId}`);
clearInterval(keepaliveInterval); clearInterval(keepaliveInterval);
this.sseClients.delete(clientId); this.sseClients.delete(clientId);
} }
} else { } else {
clearInterval(keepaliveInterval); clearInterval(keepaliveInterval);
} }
}, 30000); }, 15000);
// Handle client disconnect // Handle client disconnect
req.on('close', () => { req.on('close', () => {
clearInterval(keepaliveInterval); clearInterval(keepaliveInterval);
this.sseClients.delete(clientId); 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`);
} }
/** /**