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
JavaScript
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