mcp ai toolkit support

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-10-09 00:43:37 +02:00
padre fd14a0fda6
commit e5e120de11

Ver fichero

@@ -1,9 +1,10 @@
/**
* HTTP Server for CUDA Quantum MCP
* Provides REST API endpoints and Server-Sent Events for quantum computing operations
* Provides MCP JSON-RPC endpoints and Server-Sent Events for quantum computing operations
* Compatible with VS Code AI Toolkit and MCP clients
*/
import express, { Request, Response } from 'express';
import express, { Request, Response, NextFunction } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import swaggerJsdoc from 'swagger-jsdoc';
@@ -13,6 +14,35 @@ import { createServer } from 'http';
import { initializePythonBridge, getPythonBridge } from './bridge/python-bridge.js';
import { Logger, LogLevel } from './utils/logger.js';
// Import MCP tool handlers
import {
quantumCircuitTools,
handleCreateQuantumKernel,
handleApplyQuantumGate,
handleAddMeasurement,
handleCreateCommonCircuit,
handleListQuantumKernels,
handleVisualizeCircuit
} from './tools/circuit-tools.js';
import {
quantumExecutionTools,
handleSampleQuantumCircuit,
handleObserveHamiltonian,
handleGetQuantumState,
handleRunQuantumAlgorithm,
handleVariationalOptimization
} from './tools/execution-tools.js';
import {
hardwareBackendTools,
handleSetQuantumTarget,
handleListQuantumBackends,
handleGetPlatformInfo,
handleTestBackendConnectivity,
handleConfigureGpuAcceleration
} from './tools/hardware-tools.js';
/**
* HTTP Server configuration
*/
@@ -42,6 +72,30 @@ interface WSClient {
subscriptions: Set<string>;
}
/**
* MCP JSON-RPC Request interface
*/
interface JsonRpcRequest {
jsonrpc: '2.0';
id?: string | number;
method: string;
params?: any;
}
/**
* MCP JSON-RPC Response interface
*/
interface JsonRpcResponse {
jsonrpc: '2.0';
id?: string | number;
result?: any;
error?: {
code: number;
message: string;
data?: any;
};
}
/**
* Swagger API Documentation Configuration
*/
@@ -405,6 +459,16 @@ export class CudaQuantumHttpServer {
});
});
// ===== MCP JSON-RPC Endpoints =====
// Main MCP endpoint for JSON-RPC requests
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));
this.app.get('/sse', this.handleMcpSSE.bind(this));
// ===== Legacy REST API Endpoints (for backward compatibility) =====
// Quantum Kernels
this.app.post('/api/kernels', this.handleCreateKernel.bind(this));
this.app.get('/api/kernels', this.handleListKernels.bind(this));
@@ -422,10 +486,266 @@ export class CudaQuantumHttpServer {
this.app.post('/api/targets', this.handleSetTarget.bind(this));
this.app.get('/api/platform', this.handleGetPlatform.bind(this));
// Server-Sent Events
// Server-Sent Events (legacy)
this.app.get('/api/events', this.handleSSE.bind(this));
}
/**
* Handle MCP JSON-RPC requests
*/
private async handleMcpJsonRpc(req: Request, res: Response): Promise<void> {
try {
const request = req.body as JsonRpcRequest;
// Validate JSON-RPC format
if (request.jsonrpc !== '2.0' || !request.method) {
const errorResponse: JsonRpcResponse = {
jsonrpc: '2.0',
id: request.id,
error: {
code: -32600,
message: 'Invalid Request',
data: 'Request must be JSON-RPC 2.0 with a method'
}
};
res.status(400).json(errorResponse);
return;
}
this.logger.debug(`MCP JSON-RPC: ${request.method}`, request.params);
let result: any;
// Handle MCP protocol methods
switch (request.method) {
case 'initialize':
result = await this.handleMcpInitialize(request.params);
break;
case 'tools/list':
result = await this.handleMcpListTools();
break;
case 'tools/call':
result = await this.handleMcpCallTool(request.params);
break;
case 'resources/list':
result = { resources: [] }; // No resources for now
break;
case 'prompts/list':
result = { prompts: [] }; // No prompts for now
break;
default:
const errorResponse: JsonRpcResponse = {
jsonrpc: '2.0',
id: request.id,
error: {
code: -32601,
message: 'Method not found',
data: `Unknown method: ${request.method}`
}
};
res.status(404).json(errorResponse);
return;
}
// Send success response
const response: JsonRpcResponse = {
jsonrpc: '2.0',
id: request.id,
result
};
res.json(response);
} catch (error) {
this.logger.error('MCP JSON-RPC error:', error);
const errorResponse: JsonRpcResponse = {
jsonrpc: '2.0',
id: req.body?.id,
error: {
code: -32603,
message: 'Internal error',
data: error instanceof Error ? error.message : String(error)
}
};
res.status(500).json(errorResponse);
}
}
/**
* Handle MCP initialize
*/
private async handleMcpInitialize(params: any): Promise<any> {
return {
protocolVersion: '2024-11-05',
serverInfo: {
name: 'cuda-quantum-mcp',
version: '1.0.0'
},
capabilities: {
tools: {},
resources: {},
prompts: {}
}
};
}
/**
* Handle MCP list tools
*/
private async handleMcpListTools(): Promise<any> {
const allTools = [
...quantumCircuitTools,
...quantumExecutionTools,
...hardwareBackendTools
];
return { tools: allTools };
}
/**
* Handle MCP call tool
*/
private async handleMcpCallTool(params: any): Promise<any> {
const { name, arguments: args } = params;
this.logger.info(`Executing MCP tool: ${name}`);
try {
let result: any;
switch (name) {
// Quantum Circuit Tools
case 'create_quantum_kernel':
result = await handleCreateQuantumKernel(args);
break;
case 'apply_quantum_gate':
result = await handleApplyQuantumGate(args);
break;
case 'add_measurement':
result = await handleAddMeasurement(args);
break;
case 'create_common_circuit':
result = await handleCreateCommonCircuit(args);
break;
case 'list_quantum_kernels':
result = await handleListQuantumKernels(args);
break;
case 'visualize_circuit':
result = await handleVisualizeCircuit(args);
break;
// Quantum Execution Tools
case 'sample_quantum_circuit':
result = await handleSampleQuantumCircuit(args);
break;
case 'observe_hamiltonian':
result = await handleObserveHamiltonian(args);
break;
case 'get_quantum_state':
result = await handleGetQuantumState(args);
break;
case 'run_quantum_algorithm':
result = await handleRunQuantumAlgorithm(args);
break;
case 'variational_optimization':
result = await handleVariationalOptimization(args);
break;
// Hardware Backend Tools
case 'set_quantum_target':
result = await handleSetQuantumTarget(args);
break;
case 'list_quantum_backends':
result = await handleListQuantumBackends(args);
break;
case 'get_platform_info':
result = await handleGetPlatformInfo(args);
break;
case 'test_backend_connectivity':
result = await handleTestBackendConnectivity(args);
break;
case 'configure_gpu_acceleration':
result = await handleConfigureGpuAcceleration(args);
break;
default:
throw new Error(`Unknown tool: ${name}`);
}
// Broadcast to SSE clients
this.broadcastSSE('tool_executed', { tool: name, result });
return result;
} catch (error) {
this.logger.error(`Error executing tool ${name}:`, error);
throw error;
}
}
/**
* Handle MCP SSE endpoint
*/
private handleMcpSSE(req: Request, res: Response): void {
const clientId = Math.random().toString(36).substring(2, 15);
// Setup SSE headers
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
'X-Accel-Buffering': 'no'
});
// Store client
const client: SSEClient = {
id: clientId,
response: res,
subscriptions: new Set(['all'])
};
this.sseClients.set(clientId, client);
// Send initial connection event with MCP endpoint notification
const initMessage = {
type: 'endpoint',
uri: `/mcp`,
timestamp: new Date().toISOString()
};
res.write(`data: ${JSON.stringify(initMessage)}\n\n`);
// Send keepalive every 30 seconds
const keepaliveInterval = setInterval(() => {
if (this.sseClients.has(clientId)) {
try {
res.write(`: keepalive\n\n`);
} catch (error) {
clearInterval(keepaliveInterval);
this.sseClients.delete(clientId);
}
} else {
clearInterval(keepaliveInterval);
}
}, 30000);
// Handle client disconnect
req.on('close', () => {
clearInterval(keepaliveInterval);
this.sseClients.delete(clientId);
this.logger.debug(`MCP SSE client ${clientId} disconnected`);
});
this.logger.debug(`MCP SSE client ${clientId} connected`);
}
/**
* Setup Swagger documentation
*/