Skip to main content
Glama
janetsep

TreePod Financial MCP Agent

by janetsep

compare_competition

Analyze competitor pricing and services using real market data to identify opportunities and optimize business strategies.

Instructions

Compara precios y servicios con la competencia basado en datos reales

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
analysis_typeNoall

Implementation Reference

  • server.js:143-181 (registration)
    Registration of the 'compare_competition' tool including schema, inline handler, logging, error handling, data loading, and delegation to analyzer.
    // --- 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.'
          );
        }
      }
    );
  • Main computation logic for competition analysis: processes competitor data to extract price ranges, common services, market positioning, generates formatted report and recommendations.
    async analyzeCompetition(competitionData, analysisType = 'all') {
      if (!competitionData) {
        return validator.generateInsufficientDataResponse(
          'datos de competencia',
          'No se encontraron datos de competencia válidos'
        );
      }
    
      try {
        validator.log('info', `Analizando competencia tipo: ${analysisType}`);
        
        // Extraer datos relevantes según el tipo de análisis
        const analysis = this.processCompetitionData(competitionData, analysisType);
        
        return {
          content: [{
            type: 'text',
            text: this.formatCompetitionAnalysis(analysis, analysisType)
          }]
        };
        
      } catch (error) {
        validator.log('error', `Error en análisis de competencia: ${error.message}`);
        return validator.generateInsufficientDataResponse(
          'análisis de competencia',
          'Error interno en el análisis. Contacta al administrador.'
        );
      }
    }
    
    /**
     * Procesa datos de competencia según tipo de análisis
     */
    processCompetitionData(data, analysisType) {
      const analysis = {
        totalCompetitors: 0,
        priceRange: { min: null, max: null, average: null },
        services: [],
        positioning: 'medio',
        recommendations: []
      };
    
      // Procesar diferentes estructuras de datos de competencia
      let competitors = [];
      
      if (data.competitors) {
        competitors = Array.isArray(data.competitors) ? data.competitors : Object.values(data.competitors);
      } else if (data.establishments) {
        competitors = Array.isArray(data.establishments) ? data.establishments : Object.values(data.establishments);
      } else if (Array.isArray(data)) {
        competitors = data;
      }
    
      analysis.totalCompetitors = competitors.length;
      
      if (competitors.length > 0) {
        // Analizar precios si están disponibles
        const prices = competitors
          .map(c => c.price || c.tarifa || c.precio)
          .filter(p => p && typeof p === 'number')
          .sort((a, b) => a - b);
          
        if (prices.length > 0) {
          analysis.priceRange.min = prices[0];
          analysis.priceRange.max = prices[prices.length - 1];
          analysis.priceRange.average = Math.round(prices.reduce((a, b) => a + b, 0) / prices.length);
        }
        
        // Analizar servicios comunes
        const allServices = competitors
          .flatMap(c => c.services || c.servicios || [])
          .filter(s => s);
          
        const serviceCount = {};
        allServices.forEach(service => {
          serviceCount[service] = (serviceCount[service] || 0) + 1;
        });
        
        analysis.services = Object.entries(serviceCount)
          .sort(([,a], [,b]) => b - a)
          .slice(0, 5)
          .map(([service, count]) => ({ service, count }));
        
        // Determinar posicionamiento
        if (analysis.priceRange.average) {
          const treepodPrice = 80000; // Precio base estimado
          if (treepodPrice < analysis.priceRange.average * 0.8) {
            analysis.positioning = 'económico';
          } else if (treepodPrice > analysis.priceRange.average * 1.2) {
            analysis.positioning = 'premium';
          }
        }
        
        // Generar recomendaciones
        analysis.recommendations = this.generateCompetitionRecommendations(analysis);
      }
    
      return analysis;
    }
    
    /**
     * Formatea análisis de competencia
     */
    formatCompetitionAnalysis(analysis, analysisType) {
      let content = `🔍 **ANÁLISIS DE COMPETENCIA TREEPOD**\n\n`;
      
      content += `📊 **Competidores analizados:** ${analysis.totalCompetitors}\n`;
      content += `🎯 **Posicionamiento:** ${analysis.positioning}\n\n`;
      
      if (analysis.priceRange.average) {
        content += `**💰 ANÁLISIS DE PRECIOS:**\n`;
        content += `• Precio mínimo: ${this.formatCurrency(analysis.priceRange.min)}\n`;
        content += `• Precio máximo: ${this.formatCurrency(analysis.priceRange.max)}\n`;
        content += `• Precio promedio: ${this.formatCurrency(analysis.priceRange.average)}\n\n`;
      }
      
      if (analysis.services.length > 0) {
        content += `**🏨 SERVICIOS MÁS COMUNES:**\n`;
        analysis.services.forEach(({ service, count }) => {
          content += `• ${service} (${count} competidores)\n`;
        });
        content += `\n`;
      }
      
      if (analysis.recommendations.length > 0) {
        content += `**🎯 RECOMENDACIONES:**\n`;
        analysis.recommendations.forEach(rec => {
          content += `• ${rec}\n`;
        });
        content += `\n`;
      }
      
      content += `*Análisis basado en datos reales del sistema de inteligencia competitiva*`;
      
      return content;
    }
    
    /**
     * Genera recomendaciones basadas en análisis de competencia
     */
    generateCompetitionRecommendations(analysis) {
      const recommendations = [];
      
      if (analysis.positioning === 'económico') {
        recommendations.push('Oportunidad de aumentar precios manteniendo competitividad');
      } else if (analysis.positioning === 'premium') {
        recommendations.push('Enfatizar valor diferencial para justificar precio premium');
      }
      
      if (analysis.totalCompetitors < 5) {
        recommendations.push('Mercado con poca competencia, oportunidad de crecimiento');
      } else if (analysis.totalCompetitors > 10) {
        recommendations.push('Mercado saturado, enfocarse en diferenciación');
      }
      
      if (analysis.services.length > 0) {
        const topService = analysis.services[0].service;
        recommendations.push(`Considerar agregar/mejorar: ${topService}`);
      }
      
      return recommendations.length > 0 ? recommendations : ['Mantener estrategia competitiva actual'];
    }
  • Loads real-world competition data from JSON report files generated by another agent, with caching, file existence validation, and JSON structure validation.
    async loadCompetitionData() {
      const cacheKey = 'competition_data';
      
      if (this.isCacheValid(cacheKey)) {
        validator.log('info', 'Datos de competencia obtenidos del cache');
        return this.cache.get(cacheKey);
      }
    
      // Buscar el reporte más reciente
      const reportFiles = [
        'competition-analysis.json',
        'enhanced-competitive-data-2025-07-24.json',
        'sernatur_real_data_report_2025-07-24.json'
      ];
    
      for (const fileName of reportFiles) {
        const filePath = path.join(competitorPath, fileName);
        const fileExists = await validator.validateFileExists(filePath, `datos de competencia (${fileName})`);
        
        if (fileExists) {
          const validation = await validator.validateJsonData(filePath, [], 'datos de competencia');
          
          if (validation.valid) {
            this.setCache(cacheKey, validation.data);
            validator.log('info', `Datos de competencia cargados desde: ${fileName}`);
            return validation.data;
          }
        }
      }
    
      validator.log('error', 'No se encontraron datos válidos de competencia');
      return null;
    }

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

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