UNPKG

sia-vision-mcp-server

Version:

Enhanced v2 MCP server with improved error handling, validation, and comprehensive tool schemas for SIA.Vision storytelling platform

196 lines • 7.72 kB
#!/usr/bin/env node import express from 'express'; import { FirebaseClient } from './services/firebase-client.js'; import { v2CoreTools } from './tools/v2-core-tools.js'; import dotenv from 'dotenv'; // Load environment variables dotenv.config(); const API_KEY = process.env.SIA_API_KEY; const BASE_URL = process.env.SIA_MCP_BASE_URL || 'https://us-central1-sia-vision.cloudfunctions.net'; const PORT = process.env.PORT || 3000; if (!API_KEY) { console.error('āŒ SIA_API_KEY environment variable is required'); process.exit(1); } // Minimal v2-first tool set for fallback listing const allTools = [...v2CoreTools]; console.log(`šŸ”§ Initializing SIA.Vision MCP HTTP Server with ${allTools.length} tools`); /** * HTTP MCP Server for Claude Custom Connectors * * Implements the Model Context Protocol over HTTP for remote access */ class SIAVisionMCPHTTPServer { client; app; constructor() { this.client = new FirebaseClient(BASE_URL, API_KEY); this.app = express(); this.setupExpress(); } setupExpress() { // Parse JSON bodies this.app.use(express.json()); // Enable CORS for Claude this.app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); if (req.method === 'OPTIONS') { res.sendStatus(200); return; } next(); }); // Health check endpoint this.app.get('/health', (req, res) => { res.json({ status: 'healthy', server: 'sia-vision-mcp-server', version: '1.0.1', tools: allTools.length, timestamp: new Date().toISOString() }); }); // Server info endpoint for Claude discovery this.app.get('/info', (req, res) => { res.json({ name: 'SIA.Vision MCP Server', version: '1.0.1', description: 'MCP server for SIA.Vision storytelling platform', capabilities: { tools: true, resources: false, prompts: false }, tools: allTools.map(tool => ({ name: tool.name, description: tool.description })), documentation: 'https://www.npmjs.com/package/sia-vision-mcp-server' }); }); // MCP JSON-RPC endpoint this.app.post('/mcp', async (req, res) => { try { const { method, params, id } = req.body; console.log(`šŸ“„ MCP Request: ${method}`, { params, id }); let result; switch (method) { case 'initialize': result = { protocolVersion: '2024-11-05', capabilities: { tools: {} }, serverInfo: { name: 'sia-vision-mcp-server', version: '1.0.1' } }; break; case 'tools/list': try { // Prefer authoritative tools list from Firebase Functions MCP endpoint const remote = await this.client.listTools(); result = { tools: remote.tools }; } catch (err) { // Fallback to minimal v2 core tool list console.warn(`āš ļø Falling back to minimal local tool list: ${err instanceof Error ? err.message : String(err)}`); result = { tools: allTools }; } break; case 'tools/call': const { name, arguments: args } = params; // Find the tool const tool = allTools.find(t => t.name === name); if (!tool) { return res.json({ jsonrpc: '2.0', id, error: { code: -32601, message: `Tool '${name}' not found` } }); } // Execute via Firebase client const toolResult = await this.client.executeTool(name, args); result = { content: [ { type: 'text', text: typeof toolResult === 'string' ? toolResult : JSON.stringify(toolResult, null, 2) } ] }; break; default: return res.json({ jsonrpc: '2.0', id, error: { code: -32601, message: `Method '${method}' not found` } }); } res.json({ jsonrpc: '2.0', id, result }); } catch (error) { console.error(`āŒ MCP error:`, error); res.json({ jsonrpc: '2.0', id: req.body.id, error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error' } }); } }); } async start() { try { console.log('šŸš€ Starting SIA.Vision MCP HTTP Server...'); // Start Express server this.app.listen(PORT, () => { console.log(`āœ… SIA.Vision MCP Server running on port ${PORT}`); console.log(`🌐 Health check: http://localhost:${PORT}/health`); console.log(`šŸ“‹ Server info: http://localhost:${PORT}/info`); console.log(`šŸ”— MCP endpoint: http://localhost:${PORT}/mcp`); console.log(`šŸ“š Available tools: ${allTools.length}`); }); // Health check const isHealthy = await this.client.healthCheck(); if (isHealthy) { console.log('āœ… Firebase Functions connection healthy'); } else { console.warn('āš ļø Firebase Functions connection issue'); } } catch (error) { console.error('āŒ Failed to start server:', error); process.exit(1); } } } // Start the server const mcpServer = new SIAVisionMCPHTTPServer(); mcpServer.start().catch(console.error); // Graceful shutdown process.on('SIGINT', () => { console.log('\nšŸ›‘ Shutting down SIA.Vision MCP Server...'); process.exit(0); }); process.on('SIGTERM', () => { console.log('\nšŸ›‘ Shutting down SIA.Vision MCP Server...'); process.exit(0); }); //# sourceMappingURL=http-server.js.map