Skip to main content
Glama
index.ts4.98 kB
#!/usr/bin/env node /** * FitSlot MCP Server * * An MCP server for integrating with the FitSlot API, providing: * - Ticket management for support * - Chatbot assistance with FAQs * - Bioimpedance PDF analysis */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { FitSlotAPIService } from './services/fitslot-api.service.js'; import { ChatbotService } from './services/chatbot.service.js'; import { PDFAnalysisService } from './services/pdf-analysis.service.js'; import { OpenAIService } from './services/openai.service.js'; import { createTicketTools } from './tools/ticket.tools.js'; import { createChatbotTools } from './tools/chatbot.tools.js'; import { createPDFTools } from './tools/pdf.tools.js'; import { logger } from './utils/logger.js'; import { FitSlotConfig, OpenAIConfig } from './types/index.js'; /** * Configuration for FitSlot API */ const config: FitSlotConfig = { apiUrl: process.env.FITSLOT_API_URL || 'https://api.fitslot.com', apiKey: process.env.FITSLOT_API_KEY, timeout: parseInt(process.env.FITSLOT_API_TIMEOUT || '30000') }; const openAIConfig: OpenAIConfig = { apiKey: process.env.OPENAI_API_KEY, model: process.env.OPENAI_MODEL, organization: process.env.OPENAI_ORG, project: process.env.OPENAI_PROJECT, temperature: process.env.OPENAI_TEMPERATURE ? Number(process.env.OPENAI_TEMPERATURE) : undefined, maxTokens: process.env.OPENAI_MAX_TOKENS ? Number(process.env.OPENAI_MAX_TOKENS) : undefined }; /** * Initialize services */ const apiService = new FitSlotAPIService(config); const openAIService = new OpenAIService(openAIConfig); const chatbotService = new ChatbotService(openAIService); const pdfService = new PDFAnalysisService(openAIService); /** * Create all tools */ const ticketTools = createTicketTools(apiService); const chatbotTools = createChatbotTools(chatbotService); const pdfTools = createPDFTools(pdfService); const allTools = { ...ticketTools, ...chatbotTools, ...pdfTools }; /** * Create and configure MCP server */ const server = new Server( { name: 'fitslot-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); /** * Handler for listing available tools */ server.setRequestHandler(ListToolsRequestSchema, async () => { logger.info('Listing available tools'); return { tools: Object.entries(allTools).map(([name, tool]) => { const shape = tool.parameters.shape as Record<string, any>; return { name, description: tool.description, inputSchema: { type: 'object' as const, properties: shape, required: Object.keys(shape).filter( key => !(shape[key].isOptional && shape[key].isOptional()) ) } }; }) }; }); /** * Handler for tool execution */ server.setRequestHandler(CallToolRequestSchema, async (request) => { const toolName = request.params.name; logger.info('Executing tool', { toolName, params: request.params.arguments }); const tool = allTools[toolName as keyof typeof allTools]; if (!tool) { logger.error('Tool not found', { toolName }); throw new Error(`Unknown tool: ${toolName}`); } try { // Validate and parse arguments const parsedArgs = tool.parameters.parse(request.params.arguments || {}) as any; // Execute the tool const result = await tool.execute(parsedArgs); logger.info('Tool executed successfully', { toolName }); return result; } catch (error) { logger.error('Tool execution failed', { toolName, error }); return { content: [ { type: 'text', text: JSON.stringify( { success: false, error: error instanceof Error ? error.message : 'Unknown error', details: error instanceof Error ? error.stack : undefined }, null, 2 ) } ], isError: true }; } }); /** * Start the server */ async function main() { logger.info('Starting FitSlot MCP Server', { apiUrl: config.apiUrl, hasApiKey: !!config.apiKey }); const transport = new StdioServerTransport(); await server.connect(transport); logger.info('FitSlot MCP Server started successfully'); logger.info('Available tools:', { tools: Object.keys(allTools), count: Object.keys(allTools).length }); } // Handle graceful shutdown process.on('SIGINT', () => { logger.info('Received SIGINT, shutting down gracefully'); process.exit(0); }); process.on('SIGTERM', () => { logger.info('Received SIGTERM, shutting down gracefully'); process.exit(0); }); // Start the server main().catch((error) => { logger.error('Failed to start server', error); process.exit(1); });

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/osmarsant/fitslot-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server