Skip to main content
Glama
berlinbra

AlphaVantage-MCP

get-historical-earnings

Retrieve historical earnings data for stocks to analyze company financial performance over time, including annual and quarterly reports.

Instructions

Get historical earnings data for a specific company

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
symbolYesStock symbol for the company (e.g., AAPL, MSFT, IBM)
limit_annualNoOptional: Number of annual earnings to return (default: 5)
limit_quarterlyNoOptional: Number of quarterly earnings to return (default: 8)

Implementation Reference

  • Executes the get-historical-earnings tool: fetches EARNINGS data from Alpha Vantage API using make_alpha_request and formats the response using format_historical_earnings.
    elif name == "get-historical-earnings":
        symbol = arguments.get("symbol")
        limit_annual = arguments.get("limit_annual", 5)
        limit_quarterly = arguments.get("limit_quarterly", 8)
        
        if not symbol:
            return [types.TextContent(type="text", text="Missing symbol parameter")]
    
        symbol = symbol.upper()
    
        async with httpx.AsyncClient() as client:
            earnings_data = await make_alpha_request(
                client,
                "EARNINGS",
                symbol
            )
    
            if isinstance(earnings_data, str):
                return [types.TextContent(type="text", text=f"Error: {earnings_data}")]
    
            formatted_earnings = format_historical_earnings(earnings_data, limit_annual, limit_quarterly)
            earnings_text = f"Historical earnings for {symbol}:\n\n{formatted_earnings}"
    
            return [types.TextContent(type="text", text=earnings_text)]
  • Defines the input schema and parameters for the get-historical-earnings tool.
    types.Tool(
        name="get-historical-earnings",
        description="Get historical earnings data for a specific company",
        inputSchema={
            "type": "object",
            "properties": {
                "symbol": {
                    "type": "string",
                    "description": "Stock symbol for the company (e.g., AAPL, MSFT, IBM)"
                },
                "limit_annual": {
                    "type": "integer",
                    "description": "Optional: Number of annual earnings to return (default: 5)",
                    "default": 5,
                    "minimum": 1
                },
                "limit_quarterly": {
                    "type": "integer",
                    "description": "Optional: Number of quarterly earnings to return (default: 8)",
                    "default": 8,
                    "minimum": 1
                }
            },
            "required": ["symbol"],
        },
    ),
  • Registers the get-historical-earnings tool in the MCP server list_tools() handler.
    types.Tool(
        name="get-historical-earnings",
        description="Get historical earnings data for a specific company",
        inputSchema={
            "type": "object",
            "properties": {
                "symbol": {
                    "type": "string",
                    "description": "Stock symbol for the company (e.g., AAPL, MSFT, IBM)"
                },
                "limit_annual": {
                    "type": "integer",
                    "description": "Optional: Number of annual earnings to return (default: 5)",
                    "default": 5,
                    "minimum": 1
                },
                "limit_quarterly": {
                    "type": "integer",
                    "description": "Optional: Number of quarterly earnings to return (default: 8)",
                    "default": 8,
                    "minimum": 1
                }
            },
            "required": ["symbol"],
        },
    ),
  • Formats the raw earnings data from Alpha Vantage EARNINGS API into a readable text output, handling both annual and quarterly earnings with limits.
    def format_historical_earnings(earnings_data: Dict[str, Any], limit_annual: int = 5, limit_quarterly: int = 8) -> str:
        """Format historical earnings data into a concise string.
        
        Args:
            earnings_data: The response data from the Alpha Vantage EARNINGS endpoint
            limit_annual: Number of annual earnings to display (default: 5)
            limit_quarterly: Number of quarterly earnings to display (default: 8)
            
        Returns:
            A formatted string containing the historical earnings information
        """
        try:
            if "Error Message" in earnings_data:
                return f"Error: {earnings_data['Error Message']}"
    
            symbol = earnings_data.get("symbol", "Unknown")
            formatted = [f"Historical Earnings for {symbol}:\n\n"]
            
            # Format Annual Earnings
            annual_earnings = earnings_data.get("annualEarnings", [])
            if annual_earnings:
                formatted.append("=== ANNUAL EARNINGS ===\n")
                display_annual = annual_earnings[:limit_annual] if limit_annual > 0 else annual_earnings
                
                for earning in display_annual:
                    fiscal_date = earning.get("fiscalDateEnding", "N/A")
                    reported_eps = earning.get("reportedEPS", "N/A")
                    
                    formatted.append(f"Fiscal Year End: {fiscal_date}\n")
                    formatted.append(f"Reported EPS: ${reported_eps}\n")
                    formatted.append("---\n")
                
                if limit_annual > 0 and len(annual_earnings) > limit_annual:
                    formatted.append(f"... and {len(annual_earnings) - limit_annual} more annual reports\n")
                formatted.append("\n")
            
            # Format Quarterly Earnings
            quarterly_earnings = earnings_data.get("quarterlyEarnings", [])
            if quarterly_earnings:
                formatted.append("=== QUARTERLY EARNINGS ===\n")
                display_quarterly = quarterly_earnings[:limit_quarterly] if limit_quarterly > 0 else quarterly_earnings
                
                for earning in display_quarterly:
                    fiscal_date = earning.get("fiscalDateEnding", "N/A")
                    reported_date = earning.get("reportedDate", "N/A")
                    reported_eps = earning.get("reportedEPS", "N/A")
                    estimated_eps = earning.get("estimatedEPS", "N/A")
                    surprise = earning.get("surprise", "N/A")
                    surprise_pct = earning.get("surprisePercentage", "N/A")
                    report_time = earning.get("reportTime", "N/A")
                    
                    formatted.append(f"Fiscal Quarter End: {fiscal_date}\n")
                    formatted.append(f"Reported Date: {reported_date}\n")
                    formatted.append(f"Reported EPS: ${reported_eps}\n")
                    formatted.append(f"Estimated EPS: ${estimated_eps}\n")
                    
                    # Format surprise with proper handling
                    if surprise != "N/A" and surprise_pct != "N/A":
                        try:
                            surprise_float = float(surprise)
                            surprise_pct_float = float(surprise_pct)
                            if surprise_float >= 0:
                                formatted.append(f"Surprise: +${surprise_float:.2f} (+{surprise_pct_float:.2f}%)\n")
                            else:
                                formatted.append(f"Surprise: ${surprise_float:.2f} ({surprise_pct_float:.2f}%)\n")
                        except ValueError:
                            formatted.append(f"Surprise: {surprise} ({surprise_pct}%)\n")
                    else:
                        formatted.append(f"Surprise: {surprise} ({surprise_pct}%)\n")
                    
                    formatted.append(f"Report Time: {report_time}\n")
                    formatted.append("---\n")
                
                if limit_quarterly > 0 and len(quarterly_earnings) > limit_quarterly:
                    formatted.append(f"... and {len(quarterly_earnings) - limit_quarterly} more quarterly reports\n")
            
            if not annual_earnings and not quarterly_earnings:
                formatted.append("No historical earnings data available\n")
                
            return "".join(formatted)
        except Exception as e:
            return f"Error formatting historical earnings data: {str(e)}"
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It states what the tool does but doesn't describe how it behaves: no information about rate limits, authentication requirements, data freshness, error handling, or return format. For a data retrieval tool with zero annotation coverage, this leaves significant gaps in understanding operational behavior.

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

Conciseness5/5

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

The description is a single, efficient sentence that communicates the core purpose without unnecessary words. It's appropriately sized for a straightforward data retrieval tool and front-loads the essential information.

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 tool's moderate complexity (retrieving financial data with filtering parameters), no annotations, and no output schema, the description is insufficiently complete. It doesn't explain what 'historical earnings data' includes (e.g., EPS, revenue, dates), how results are structured, or any behavioral constraints. The agent would need to guess about the return format and operational behavior.

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%, with all parameters well-documented in the schema itself. The description doesn't add any parameter information beyond what's already in the schema (e.g., it doesn't explain what 'historical earnings data' includes or how the limits work). Baseline 3 is appropriate when 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 verb ('Get') and resource ('historical earnings data for a specific company'), making the purpose immediately understandable. It distinguishes from siblings like 'get-earnings-calendar' (future events) and 'get-stock-quote' (current price), though it doesn't explicitly mention these distinctions.

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?

No guidance is provided on when to use this tool versus alternatives. While the description implies it's for historical earnings, it doesn't specify when to choose this over 'get-company-info' (which might include earnings) or 'get-earnings-calendar' (which focuses on future earnings). No exclusions or prerequisites are mentioned.

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/berlinbra/alpha-vantage-mcp'

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