Skip to main content
Glama

TreePod Financial MCP Agent

by janetsep
server.js12.3 kB
#!/usr/bin/env node import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; // Importar módulos que implementan la Guía de Trabajo Fundamental import { validator } from './src/utils/validator.js'; import { dataLoader } from './src/data/dataLoader.js'; import { businessCalculator } from './src/business/calculator.js'; /** * 🏕️ TreePod Glamping - Agente Financiero MCP * Agente inteligente que responde consultas sobre el negocio TreePod * directamente dentro de Claude Desktop. * * ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: * - Sin datos hardcodeados * - Sin inventar información * - Validación robusta * - Trazabilidad completa * - Arquitectura modular */ const server = new McpServer({ name: 'treepod-financial', version: '1.0.0', }); // --- Herramienta: analyze_finances --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, validación, trazabilidad server.registerTool( 'analyze_finances', { title: 'Analizar finanzas', description: 'Analiza las finanzas actuales de TreePod Glamping con métricas clave basado en datos reales', inputSchema: z.object({ period: z.string().default('current'), }), }, async ({ period }) => { validator.log('info', `Iniciando análisis financiero para período: ${period}`); try { // Usar módulo de cálculo sin hardcodeo const result = await businessCalculator.analyzeFinancialMetrics(period); validator.log('info', 'Análisis financiero completado exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en análisis financiero: ${error.message}`); return validator.generateInsufficientDataResponse( 'análisis financiero', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: calculate_tariff --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, validación robusta server.registerTool( 'calculate_tariff', { title: 'Calcular tarifa', description: 'Calcula tarifas para reservas según temporada, personas y canal basado en configuración real', inputSchema: z.object({ checkin_date: z.string(), checkout_date: z.string(), guests: z.number().min(1).max(4), channel: z.string().optional().default('directo'), }), }, async ({ checkin_date, checkout_date, guests, channel = 'directo' }) => { validator.log('info', `Iniciando cálculo de tarifa: ${guests} huéspedes, ${checkin_date} a ${checkout_date}, canal ${channel}`); try { // Usar módulo de cálculo sin hardcodeo const result = await businessCalculator.calculateTariff(checkin_date, checkout_date, guests, channel); validator.log('info', 'Cálculo de tarifa completado exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en cálculo de tarifa: ${error.message}`); return validator.generateInsufficientDataResponse( 'cálculo de tarifa', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: check_occupancy --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, datos reales server.registerTool( 'check_occupancy', { title: 'Verificar ocupación', description: 'Verifica estado de ocupación actual y futura de los domos basado en datos reales', inputSchema: z.object({ date_range: z.string().default('today'), }), }, async ({ date_range = 'today' }) => { validator.log('info', `Iniciando verificación de ocupación para período: ${date_range}`); try { // Cargar datos reales sin hardcodeo const businessData = await dataLoader.loadBusinessStatus(); const domosStatus = await dataLoader.loadDomosStatus(); // Validar que tenemos datos suficientes if (!businessData && !domosStatus) { return validator.generateInsufficientDataResponse( 'datos de ocupación', 'No se pudo acceder a los datos de estado del negocio ni de domos' ); } if (!domosStatus) { return validator.generateInsufficientDataResponse( 'estado de domos', 'No se pudo acceder al estado actual de los domos' ); } const result = await businessCalculator.analyzeOccupancy(businessData, domosStatus, date_range); validator.log('info', 'Verificación de ocupación completada exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en verificación de ocupación: ${error.message}`); return validator.generateInsufficientDataResponse( 'verificación de ocupación', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: compare_competition --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, datos reales server.registerTool( 'compare_competition', { title: 'Comparar competencia', description: 'Compara precios y servicios con la competencia basado en datos reales', inputSchema: z.object({ analysis_type: z.string().default('all'), }), }, async ({ analysis_type = 'all' }) => { validator.log('info', `Iniciando análisis de competencia tipo: ${analysis_type}`); try { // Cargar datos reales de competencia const competitionData = await dataLoader.loadCompetitionData(); if (!competitionData) { return validator.generateInsufficientDataResponse( 'datos de competencia', 'El sistema de inteligencia competitiva no ha generado reportes recientes. Ejecuta el agente competitivo para obtener datos actualizados.' ); } const result = await businessCalculator.analyzeCompetition(competitionData, analysis_type); validator.log('info', 'Análisis de competencia completado exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en análisis de competencia: ${error.message}`); return validator.generateInsufficientDataResponse( 'análisis de competencia', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: generate_report --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, datos reales server.registerTool( 'generate_report', { title: 'Generar reporte', description: 'Genera reportes ejecutivos del negocio basado en datos reales', inputSchema: z.object({ report_type: z.string().default('monthly'), format: z.string().default('summary'), }), }, async ({ report_type = 'monthly', format = 'summary' }) => { validator.log('info', `Iniciando generación de reporte tipo: ${report_type}, formato: ${format}`); try { // Validar parámetros de entrada const inputValidation = validator.validateUserInput({ report_type, format }, { report_type: { required: true, type: 'string', enum: ['monthly', 'occupancy', 'financial', 'competition'] }, format: { required: true, type: 'string', enum: ['summary', 'detailed'] } }); if (!inputValidation.valid) { return validator.generateInsufficientDataResponse( 'parámetros de reporte', `Errores: ${inputValidation.errors.join(', ')}` ); } const result = await businessCalculator.generateReport(report_type, format); validator.log('info', 'Reporte generado exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en generación de reporte: ${error.message}`); return validator.generateInsufficientDataResponse( 'generación de reporte', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: get_business_status --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, datos reales server.registerTool( 'get_business_status', { title: 'Estado del negocio', description: 'Estado general actual del negocio con alertas y KPIs basado en datos reales', inputSchema: z.object({ format: z.string().optional().default('summary') }), }, async () => { validator.log('info', 'Iniciando consulta de estado general del negocio'); try { const result = await businessCalculator.getBusinessStatus(); validator.log('info', 'Estado del negocio obtenido exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico obteniendo estado del negocio: ${error.message}`); return validator.generateInsufficientDataResponse( 'estado del negocio', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: optimize_pricing --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, datos reales server.registerTool( 'optimize_pricing', { title: 'Optimizar precios', description: 'Sugiere optimizaciones de precios basado en competencia y ocupación usando datos reales', inputSchema: z.object({ strategy: z.string().default('maximize_revenue'), }), }, async ({ strategy = 'maximize_revenue' }) => { validator.log('info', `Iniciando optimización de precios con estrategia: ${strategy}`); try { // Validar parámetros de entrada const inputValidation = validator.validateUserInput({ strategy }, { strategy: { required: true, type: 'string', enum: ['maximize_revenue', 'maximize_occupancy', 'balanced', 'competitive'] } }); if (!inputValidation.valid) { return validator.generateInsufficientDataResponse( 'estrategia de optimización', `Errores: ${inputValidation.errors.join(', ')}` ); } const result = await businessCalculator.optimizePricing(strategy); validator.log('info', 'Optimización de precios completada exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en optimización de precios: ${error.message}`); return validator.generateInsufficientDataResponse( 'optimización de precios', 'Error interno del sistema. Contacta al administrador.' ); } } ); // --- Herramienta: predict_revenue --- // ✅ IMPLEMENTA GUÍA DE TRABAJO FUNDAMENTAL: Sin hardcodeo, datos reales server.registerTool( 'predict_revenue', { title: 'Predecir ingresos', description: 'Predice ingresos futuros basado en datos históricos y tendencias reales', inputSchema: z.object({ period: z.string().default('next_month'), }), }, async ({ period = 'next_month' }) => { validator.log('info', `Iniciando predicción de ingresos para período: ${period}`); try { // Validar parámetros de entrada const inputValidation = validator.validateUserInput({ period }, { period: { required: true, type: 'string', enum: ['next_week', 'next_month', 'next_quarter', 'next_semester', 'next_year'] } }); if (!inputValidation.valid) { return validator.generateInsufficientDataResponse( 'período de predicción', `Errores: ${inputValidation.errors.join(', ')}` ); } const result = await businessCalculator.predictRevenue(period); validator.log('info', 'Predicción de ingresos completada exitosamente'); return result; } catch (error) { validator.log('error', `Error crítico en predicción de ingresos: ${error.message}`); return validator.generateInsufficientDataResponse( 'predicción de ingresos', 'Error interno del sistema. Contacta al administrador.' ); } } ); // Iniciar el servidor const transport = new StdioServerTransport(); server.connect(transport).then(() => { console.error('🏕️ TreePod Financial MCP - Servidor de prueba iniciado'); }).catch((error) => { console.error('❌ Error iniciando servidor:', error); process.exit(1); });

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/janetsep/treepod-financial-mcp'

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