Skip to main content
Glama

analyze_natural_query

Process natural language queries about companies, financials, governance, or market performance to extract insights from Spanish stock exchange data.

Instructions

Process and execute complex natural language queries about companies, financials, governance, or markets

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesNatural language query (e.g., "Which banking stocks have grown most in the last month?", "Show me companies with high governance risk", "Compare energy sector performance")
contextNoOptional context or previous query results to build upon

Implementation Reference

  • The core handler function that processes natural language queries. It uses regex pattern matching to interpret the query intent (e.g., banking performance, risk assessment, comparisons) and executes the appropriate analytics workflows, database queries, and generates structured results with execution plans and suggestions.
    async analyzeNaturalQuery(query: string, context?: string): Promise<any> {
      const lowerQuery = query.toLowerCase();
      const analysis = {
        original_query: query,
        context: context,
        interpretation: '',
        suggested_actions: [],
        results: {},
        execution_plan: []
      };
    
      try {
        // Banking-related queries
        if (lowerQuery.match(/\b(bank|banking|financial)\b.*\b(grow|growth|performance|best|worst)\b/)) {
          analysis.interpretation = 'Banking sector performance analysis';
          analysis.execution_plan.push('Get banking sector companies', 'Analyze recent performance', 'Rank by growth');
          
          const bankingCompanies = await this.db.getCompaniesBySector('banking');
          const performances = await this.analyzeCompanyPerformances(bankingCompanies, 30);
          analysis.results = {
            sector: 'Banking',
            companies_analyzed: bankingCompanies.length,
            top_performers: performances.slice(0, 5),
            analysis_period: '30 days'
          };
        }
        
        // High risk queries
        else if (lowerQuery.match(/\b(risk|risky|governance|red flag)\b/)) {
          analysis.interpretation = 'Risk assessment analysis';
          analysis.execution_plan.push('Analyze governance risks', 'Check market risks', 'Generate risk report');
          
          const companies = await this.db.getAllCompanies();
          const interlocks = await this.db.getBoardInterlocks();
          const governanceRisks = await this.getGovernanceRiskFactors(companies, interlocks);
          
          analysis.results = {
            total_companies_analyzed: companies.length,
            governance_risks: governanceRisks,
            high_risk_companies: governanceRisks.governance_red_flags.filter(f => f.severity === 'high').length,
            recommendations: this.generateRiskRecommendations(governanceRisks)
          };
        }
        
        // Comparison queries
        else if (lowerQuery.match(/\b(compare|vs|versus|against)\b/)) {
          analysis.interpretation = 'Company comparison analysis';
          
          // Try to extract company names from the query
          const companyPatterns = [
            /\b(santander|san\.mc|san)\b/i,
            /\b(bbva|bbva\.mc)\b/i,
            /\b(iberdrola|ibe\.mc|ibe)\b/i,
            /\b(telefonica|tef\.mc|tef)\b/i,
            /\b(inditex|itx\.mc|itx)\b/i
          ];
          
          const foundCompanies = [];
          for (const pattern of companyPatterns) {
            if (lowerQuery.match(pattern)) {
              const match = lowerQuery.match(pattern);
              if (match) foundCompanies.push(match[0].toUpperCase());
            }
          }
          
          if (foundCompanies.length >= 2) {
            analysis.results = await this.compareCompanies(foundCompanies, ['all']);
          } else {
            analysis.results = {
              error: 'Could not identify companies to compare',
              suggestion: 'Try: "Compare Santander vs BBVA" or use company symbols like SAN.MC vs BBVA.MC'
            };
          }
        }
        
        // Sector performance queries
        else if (lowerQuery.match(/\b(sector|industry).*\b(performance|trend|growth)\b/)) {
          const sectorMatch = lowerQuery.match(/\b(banking|energy|telecom|textile|steel|aviation|infrastructure)\b/);
          const sector = sectorMatch ? sectorMatch[1] : 'energy'; // default to energy as example
          
          analysis.interpretation = `${sector} sector performance analysis`;
          const sectorResults = await this.getSectorCorrelationAnalysis(30);
          analysis.results = {
            ...sectorResults,
            focused_sector: sector
          };
        }
        
        // Price/trend queries
        else if (lowerQuery.match(/\b(price|trend|forecast|prediction)\b/)) {
          analysis.interpretation = 'Price trend analysis';
          const companies = await this.db.getAllCompanies();
          const topPerformers = await this.db.getTopPerformers(30, 10);
          
          analysis.results = {
            analysis_type: 'Price trends over 30 days',
            top_performers: topPerformers,
            trend_summary: this.generateTrendSummary(topPerformers)
          };
        }
        
        // General fallback
        else {
          analysis.interpretation = 'General market overview';
          const companies = await this.db.getAllCompanies();
          const recent_news = await this.db.getRecentNews(undefined, 5);
          const top_performers = await this.db.getTopPerformers(7, 5);
          
          analysis.results = {
            total_companies: companies.length,
            recent_market_news: recent_news.length,
            weekly_top_performers: top_performers,
            market_snapshot: 'Current IBEX 35 overview'
          };
        }
    
        analysis.suggested_actions = this.generateActionSuggestions(analysis.interpretation, analysis.results);
        
        return analysis;
      } catch (error) {
        return {
          ...analysis,
          error: `Failed to process natural language query: ${error}`,
          fallback_suggestion: 'Try using specific tool names like get_all_companies, get_recent_news, or get_board_interlocks'
        };
      }
    }
  • The input schema definition for the 'analyze_natural_query' tool, specifying the expected parameters: a required 'query' string and optional 'context' string.
    inputSchema: {
      type: 'object',
      properties: {
        query: {
          type: 'string',
          description: 'Natural language query (e.g., "Which banking stocks have grown most in the last month?", "Show me companies with high governance risk", "Compare energy sector performance")',
        },
        context: {
          type: 'string',
          description: 'Optional context or previous query results to build upon',
        },
      },
      required: ['query'],
    },
  • src/index.ts:657-659 (registration)
    The switch case in the CallToolRequest handler that dispatches calls to 'analyze_natural_query' to the AnalyticsManager's analyzeNaturalQuery method.
    case 'analyze_natural_query':
      result = await this.analytics.analyzeNaturalQuery((args as any)?.query, (args as any)?.context);
      break;
  • src/index.ts:361-378 (registration)
    The tool registration in the ListTools response, including name, description, and input schema.
    {
      name: 'analyze_natural_query',
      description: 'Process and execute complex natural language queries about companies, financials, governance, or markets',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Natural language query (e.g., "Which banking stocks have grown most in the last month?", "Show me companies with high governance risk", "Compare energy sector performance")',
          },
          context: {
            type: 'string',
            description: 'Optional context or previous query results to build upon',
          },
        },
        required: ['query'],
      },
    },
  • TypeScript declaration of the analyzeNaturalQuery function signature.
    analyzeNaturalQuery(query: string, context?: string): Promise<any>;
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions 'process and execute' but doesn't clarify what execution entails—whether it returns data, generates reports, or performs analyses. There's no information about performance characteristics, error handling, or output format. The description is too vague about the tool's actual behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core functionality. It avoids unnecessary words and gets straight to the point. However, it could be slightly more structured by explicitly mentioning the tool's domain scope upfront.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity implied by 'complex natural language queries' and the lack of annotations and output schema, the description is insufficient. It doesn't explain what kind of results to expect, how queries are processed, or any limitations. For a tool with no structured output documentation, the description should provide more context about the execution outcome.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents both parameters thoroughly. The description doesn't add any meaningful semantics beyond what's in the schema—it doesn't explain how the 'query' parameter should be structured beyond 'natural language' or how 'context' integrates with processing. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Process and execute complex natural language queries about companies, financials, governance, or markets.' It specifies the verb ('process and execute'), resource ('natural language queries'), and domain scope. However, it doesn't explicitly differentiate from siblings like 'execute_custom_query' or 'analyze_trends' that might overlap in functionality.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With many sibling tools available (e.g., 'analyze_trends', 'compare_companies', 'execute_custom_query'), there's no indication of what makes this tool distinct or when it should be preferred over others. Usage is implied by the description but not explicitly stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/anbrme/ibex35-mcp-server'

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