UNPKG

@cgaspard/webappmcp

Version:

WebApp MCP - Model Context Protocol integration for web applications with server-side debugging tools

149 lines 5.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IntegratedMCPServer = void 0; const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); const ws_1 = require("ws"); const index_js_2 = require("./tools/index.js"); class IntegratedMCPServer { constructor(config) { this.ws = null; this.isConnected = false; this.wsUrl = config.wsUrl; this.authToken = config.authToken; this.server = new index_js_1.Server({ name: 'webapp-mcp', version: '0.1.0', }, { capabilities: { tools: {}, }, }); this.setupHandlers(); } setupHandlers() { this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => { return { tools: (0, index_js_2.registerTools)(), }; }); this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (!this.isConnected) { throw new Error('Not connected to web application'); } try { const result = await this.executeToolOnClient(name, args); return result; } catch (error) { return { content: [ { type: 'text', text: `Error executing tool: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], }; } }); } async connectWebSocket() { return new Promise((resolve, reject) => { const headers = {}; if (this.authToken) { headers['Authorization'] = `Bearer ${this.authToken}`; } this.ws = new ws_1.WebSocket(this.wsUrl, { headers }); this.ws.on('open', () => { console.error('Connected to WebApp WebSocket'); this.isConnected = true; this.ws.send(JSON.stringify({ type: 'init', url: 'mcp-server', })); resolve(); }); this.ws.on('message', (data) => { const message = JSON.parse(data.toString()); if (message.type === 'connected') { console.error(`MCP Server registered with clientId: ${message.clientId}`); } }); this.ws.on('close', () => { console.error('Disconnected from WebApp WebSocket'); this.isConnected = false; this.scheduleReconnect(); }); this.ws.on('error', (error) => { console.error('WebSocket error:', error); reject(error); }); }); } scheduleReconnect() { if (this.reconnectTimer) return; this.reconnectTimer = setTimeout(async () => { this.reconnectTimer = null; try { await this.connectWebSocket(); } catch (error) { console.error('Reconnection failed:', error); } }, 5000); } async executeToolOnClient(toolName, args) { return new Promise((resolve, reject) => { const requestId = Math.random().toString(36).substring(7); const timeout = setTimeout(() => { reject(new Error('Tool execution timeout')); }, 30000); const messageHandler = (data) => { const message = JSON.parse(data.toString()); if (message.requestId === requestId) { clearTimeout(timeout); this.ws.off('message', messageHandler); if (message.error) { reject(new Error(message.error)); } else { resolve({ content: [ { type: 'text', text: JSON.stringify(message.result, null, 2), }, ], }); } } }; this.ws.on('message', messageHandler); this.ws.send(JSON.stringify({ type: 'execute_tool', requestId, tool: toolName, args, })); }); } async start() { try { // Connect to WebSocket first await this.connectWebSocket(); // Then start MCP server const transport = new stdio_js_1.StdioServerTransport(); await this.server.connect(transport); console.error('Integrated MCP Server started'); } catch (error) { console.error('Failed to start MCP server:', error); process.exit(1); } } } exports.IntegratedMCPServer = IntegratedMCPServer; //# sourceMappingURL=mcp-server.js.map