Skip to main content
Glama
mohantee

StockAnalysis

by mohantee

šŸ“Š MCP Stock Analysis Server

A full-featured Model Context Protocol (MCP) server for real-time stock analysis, built as a reference implementation demonstrating how to combine MCP tools, live API data fetching, JSON file persistence, and rich interactive Prefab UI dashboards — all wired together in a clean Python codebase.


Intention — Why This Project Exists

This project serves as a comprehensive MCP example that goes beyond "hello world". It demonstrates:

Concept

What This Project Shows

MCP Tool Registration

7 tools registered via @mcp.tool() decorators on a MCPServer instance

Live API Integration

Fetching real-time financial data from Yahoo Finance via yfinance

Data Persistence

Every API response is written to disk as structured JSON with timestamps

Rich UI via Prefab

Each tool returns a fully interactive HTML dashboard (charts, gauges, tables) built with prefab-ui

HTML Export

Dashboards are also saved as standalone dashboard.html for browser viewing

MCP Client

A standalone test_client.py that connects over stdio transport, lists tools, and calls them interactively

Claude Desktop Skill

Ready-to-paste configuration for plugging this server into Claude Desktop or any MCP host

Multi-Market Support

Handles US (NYSE/NASDAQ), Indian NSE (.NS), and BSE (.BO) tickers

Whether you're learning MCP, building your own tools, or want a working stock analysis agent — this project is a complete starting point.


Related MCP server: Yahoo Finance MCP Server

Architecture Overview

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                        MCP Client                               │
│  (Claude Desktop / test_client.py / Any MCP Host)               │
│                                                                 │
│  Connects via stdio transport ──► ClientSession ──► call_tool() │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                         │ stdio (stdin/stdout)
                         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      MCP Server (server.py)                     │
│                                                                 │
│  MCPServer("StockAnalysis")                                     │
│    ā”œā”€ā”€ @mcp.tool()  analyze_stock(ticker)                       │
│    ā”œā”€ā”€ @mcp.tool()  get_stock_price(ticker)                     │
│    ā”œā”€ā”€ @mcp.tool()  get_stock_history(ticker, period)           │
│    ā”œā”€ā”€ @mcp.tool()  get_financials(ticker)                      │
│    ā”œā”€ā”€ @mcp.tool()  compare_peers(ticker)                       │
│    ā”œā”€ā”€ @mcp.tool()  get_technical_analysis(ticker)              │
│    └── @mcp.tool()  get_sector_overview(sector)                 │
│                                                                 │
│  Each tool:                                                     │
│    1. Calls stock_data.py ─► yfinance API                       │
│    2. Calls file_writer.py ─► data/*.json                       │
│    3. Calls ui/dashboard.py ─► PrefabApp (interactive HTML)     │
│    4. Returns serialized JSON to the client                     │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Server Details

Entry Point & Transport

The server is defined in server.py and uses the MCPServer class from the mcp Python SDK (FastMCP):

from mcp.server.mcpserver import MCPServer

mcp = MCPServer(
    "StockAnalysis",
    instructions="A stock analysis server that provides comprehensive financial data..."
)
  • Transport: stdio (stdin/stdout) — the standard transport for AI assistants like Claude

  • Logging: All logs go to stderr (required for stdio transport so logs don't interfere with MCP protocol messages)

  • Entry point: src.server:main (registered in pyproject.toml as the stock-mcp console script)

Server Startup

def main():
    """Entry point for the MCP server."""
    mcp.run()

When mcp.run() is called, the server:

  1. Starts listening on stdin for MCP protocol messages

  2. Responds to initialize, list_tools, and call_tool requests

  3. Returns tool results (text or Prefab UI JSON) via stdout


Available Tools (Functions)

The server exposes 7 tools, each decorated with @mcp.tool(). Tools accept simple typed parameters and return either plain text or serialized Prefab UI JSON.

1. analyze_stock(ticker: str) → str

Full comprehensive analysis — the flagship tool. Fetches everything and builds a multi-tab dashboard using Prefab.

Step

Action

1

Fetches company info via fetch_stock_info()

2

Fetches 1-month and 1-year price history

3

Computes technical indicators (RSI, MACD, Bollinger, SMAs)

4

Fetches quarterly/annual financial statements

5

Fetches and compares sector peers

6

Writes all data to individual JSON files in data/

7

Writes a timestamped full report: {TICKER}_full_report_{timestamp}.json

8

Builds and returns a tabbed Prefab UI dashboard

Example: analyze_stock("AAPL")


2. get_stock_price(ticker: str) → str

Quick price lookup — returns a formatted text summary (no UI dashboard).

Returns current price, day change (absolute + percentage), day range, 52-week range, market cap, P/E ratio, analyst target price, and recommendation.

Example: get_stock_price("RELIANCE.NS")

Sample output:

šŸ“ˆ Apple Inc. (AAPL)
   Exchange: NMS | Sector: Technology
   Current Price: USD 226.84
   Day Change:    +1.23 (+0.55%)
   Day Range:     USD 224.50 - 227.90
   52-Week Range: USD 164.08 - 237.49
   Market Cap:    3.45T
   P/E Ratio:     34.72
   Target Price:  USD 240.00 (buy)

3. get_stock_history(ticker: str, period: str = "1y") → str

Price history with interactive charts. Fetches OHLCV data and returns an AreaChart (short-term) or LineChart (long-term) with volume bars.

Period

Interval Used

Chart Type

1d

5-minute

AreaChart

5d

15-minute

AreaChart

1mo

1-hour

AreaChart

3mo – 1y

Daily

LineChart

2y – 5y

Weekly

LineChart

max

Monthly

LineChart

Example: get_stock_history("TSLA", "6mo")


4. get_financials(ticker: str) → str

Financial statements and ratios — quarterly/annual revenue & income bar charts, profit margin line charts, key ratios table, and balance sheet highlights.

Data extracted:

  • Quarterly: Total Revenue, Net Income, Gross Profit, Operating Income

  • Annual: Total Revenue, Net Income

  • Margins: Gross, Operating, Net (computed as percentages)

  • Balance sheet: Total Assets, Total Liabilities, Total Equity, Total Debt, Cash, Net Debt

Example: get_financials("GOOGL")


5. compare_peers(ticker: str) → str

Sector peer comparison — identifies peers in the same sector and compares them using a radar chart and sortable data table.

Metrics compared: P/E Ratio, P/B Ratio, Dividend Yield, ROE, Profit Margin, Revenue Growth, Beta.

Normalization: All metrics are scaled to 0–100 for the radar chart using abs(value) / max(abs(values)) * 100.

Example: compare_peers("NVDA")


6. get_technical_analysis(ticker: str) → str

Technical indicators with buy/sell/hold signals. Computes the following from 1-year daily data:

Indicator

Parameters

Signal Logic

RSI

Window: 14

> 70 → Overbought, < 30 → Oversold

MACD

Fast: 12, Slow: 26, Signal: 9

MACD > Signal → Bullish

SMA

20, 50, 200

SMA 50 > SMA 200 → Golden Cross (Bullish)

EMA

12, 26

Displayed in indicator table

Bollinger Bands

Window: 20, Std Dev: 2

Chart overlay

Overall Signal: Weighted vote across RSI, MACD, SMA cross, and price vs SMA 20:

  • bullish_count > bearish_count + 1 → Buy

  • bearish_count > bullish_count + 1 → Sell

  • Otherwise → Hold

Example: get_technical_analysis("RELIANCE.NS")


7. get_sector_overview(sector: str) → str

Sector-level breakdown — shows a pie chart of market cap distribution and a sortable table of representative stocks.

Supported sectors (with 6 representative tickers each): Technology, Financial Services, Healthcare, Consumer Cyclical, Energy, Communication Services, Industrials, Consumer Defensive, Basic Materials, Real Estate, Utilities

Example: get_sector_overview("Technology")


Invoking the Yahoo Finance API & Writing to Files

API Layer (stock_data.py)

All data fetching is centralized in stock_data.py. It uses yfinance to call the Yahoo Finance API and returns typed dataclasses:

Function

Returns

API Call

fetch_stock_info(ticker)

StockInfo

yf.Ticker(ticker).info

fetch_price_history(ticker, period)

PriceHistory

yf.Ticker(ticker).history(period, interval)

compute_technical_analysis(ticker)

TechnicalAnalysis

yf.Ticker(ticker).history("1y", "1d") + ta library

fetch_financials(ticker)

FinancialData

.quarterly_financials, .financials, .balance_sheet

fetch_peer_comparison(ticker, max_peers)

PeerData

yf.Ticker().info for each peer

Key design decisions:

  • All values pass through _safe_get() which handles None, NaN, and Inf safely

  • Large numbers are formatted with _format_large_number() → "3.45T", "150.20B", "3.20M"

  • Each dataclass has a .to_dict() method for JSON serialization

File Persistence Layer (file_writer.py)

Every tool call persists its data to the data/ directory via file_writer.py:

write_data(ticker, "info", info.to_dict())              # → data/AAPL_info.json
write_data(ticker, "history", data, period="1mo")        # → data/AAPL_history_1mo.json
write_data(ticker, "analysis", analysis.to_dict())       # → data/AAPL_analysis.json
write_data(ticker, "financials", financials.to_dict())   # → data/AAPL_financials.json
write_data(ticker, "peers", peers.to_dict())             # → data/AAPL_peers.json
write_analysis_report(ticker, full_report)               # → data/AAPL_full_report_20260829_191739.json

File naming: {TICKER}_{data_type}[_{period}].json — dots in tickers (e.g., .NS) are replaced with underscores.

Full reports include a timestamp suffix: {TICKER}_full_report_{YYYYMMDD_HHMMSS}.json

Resulting Data Directory

data/
ā”œā”€ā”€ AAPL_info.json                          # Company info snapshot
ā”œā”€ā”€ AAPL_history_1mo.json                   # 1-month OHLCV data
ā”œā”€ā”€ AAPL_history_1y.json                    # 1-year OHLCV data
ā”œā”€ā”€ AAPL_analysis.json                      # Technical indicators + signals
ā”œā”€ā”€ AAPL_financials.json                    # Income statements + balance sheet
ā”œā”€ā”€ AAPL_peers.json                         # Peer comparison metrics
ā”œā”€ā”€ AAPL_full_report_20260829_191739.json   # Comprehensive timestamped report
└── dashboard.html                          # Last-generated interactive dashboard

Dynamic UI with Prefab UI

How It Works

Each tool (except get_stock_price) returns an interactive dashboard built with Prefab UI — a Python library for composing rich HTML dashboards using a declarative context-manager pattern.

The flow is:

Tool function
  └── build_*_dashboard()    (src/ui/dashboard.py)
        └── Compose UI with component helpers  (src/ui/components.py)
              └── PrefabApp context manager → in-memory HTML app
                    └── _app_to_json(app)
                          ā”œā”€ā”€ app.to_json() → MCP transport (JSON over stdio)
                          └── app.html() → data/dashboard.html (browser viewable)

Dashboard Builder (dashboard.py)

dashboard.py contains 6 builder functions that compose PrefabApp instances:

Builder Function

Used By

Layout

build_full_dashboard()

analyze_stock

Tabbed: Price Charts, Technical Analysis, Financials, Peers

build_price_dashboard()

get_stock_history

Header + price chart + volume bars

build_technical_dashboard()

get_technical_analysis

Header + RSI/MACD/Bollinger/SMA panels

build_financials_dashboard()

get_financials

Header + ratios table + financial charts

build_peers_dashboard()

compare_peers

Header + radar chart + comparison table

build_sector_dashboard()

get_sector_overview

Pie chart + sector stocks table

Reusable Components (components.py)

components.py provides 7 component builder functions:

Component Function

Prefab Widgets Used

stock_header_card()

Card, Badge, Metric, Progress (day & 52w range bars), Row, Grid

key_metrics_row()

Grid of Card + Metric (Market Cap, P/E, EPS, Div Yield, Beta, Volume)

key_ratios_card()

DataTable with 10 financial ratios

price_chart()

AreaChart (short-term) or LineChart (long-term) + BarChart (volume)

technical_analysis_panel()

Ring (RSI gauge), BarChart (MACD histogram), LineChart (Bollinger + SMA), DataTable (indicator values)

financials_section()

BarChart (revenue/income), LineChart (margins), DataTable (balance sheet)

peer_comparison_section()

RadarChart (normalized metrics), DataTable (detailed comparison)

Viewing Dashboards

Dashboards are accessible in three ways:

  1. MCP Client UI: MCP hosts that support Prefab UI render the dashboard inline

  2. Browser via test client: The test client starts a local HTTP server on http://localhost:8765/dashboard.html

  3. Standalone Prefab serve:

    uv run prefab serve src/ui/dashboard.py

Client Details

Test Client (test_client.py)

The project includes a fully functional interactive MCP client in test_client.py that demonstrates the complete client-side MCP flow:

What It Does

  1. Starts a local HTTP server on port 8765 to serve data/dashboard.html

  2. Launches the MCP server as a subprocess via StdioServerParameters

  3. Connects over stdio using stdio_client() and ClientSession

  4. Lists all available tools with their parameters

  5. Provides an interactive REPL for calling tools

Connection Code

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

server_params = StdioServerParameters(
    command=sys.executable,       # Current Python interpreter
    args=["-m", "src.server"],    # Run the server as a module
    cwd=".",
)

async with stdio_client(server_params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()

        # List tools
        tools_result = await session.list_tools()

        # Call a tool
        result = await session.call_tool("analyze_stock", {"ticker": "AAPL"})

Running the Client

uv run python test_client.py

Interactive Usage

[*] Connecting to MCP Stock Analysis Server...
[OK] Connected!
[UI] Local Dashboard Server: http://localhost:8765/dashboard.html

[TOOLS] Available tools (7):
  1. analyze_stock
     Params: ticker*: string
  2. get_stock_price
     Params: ticker*: string
  ...

==================================================
Type a tool name and arguments to call it.
Examples:
  analyze_stock ticker=AAPL
  get_stock_price ticker=RELIANCE.NS
  get_stock_history ticker=TSLA period=6mo
  get_sector_overview sector=Technology
Type 'list' to see tools again, 'quit' to exit.
==================================================

>> analyze_stock ticker=AAPL
[...] Calling analyze_stock({'ticker': 'AAPL'})...
šŸ“Š [Prefab UI Dashboard Generated!]
   View Live in Browser šŸ‘‰ http://localhost:8765/dashboard.html

When a tool returns Prefab UI JSON (detected via "$prefab" key), the client:

  • Prints a message pointing to the dashboard URL

  • Automatically opens the dashboard in your default browser


Plugin as a Skill to Claude Desktop

Claude Desktop Configuration

Add the following to your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "stock-analysis": {
      "command": "uv",
      "args": [
        "run",
        "--directory", "/absolute/path/to/MCP",
        "python", "-m", "src.server"
      ]
    }
  }
}

Important: Replace /absolute/path/to/MCP with the actual absolute path to this project directory.

After adding the config:

  1. Restart Claude Desktop

  2. You should see a šŸ”Œ icon indicating the MCP server is connected

  3. Ask Claude to analyze stocks — it will automatically discover and use the 7 tools

Other MCP Hosts

For other MCP-compatible hosts, add to your MCP configuration:

{
  "stock-analysis": {
    "command": "uv",
    "args": [
      "run",
      "--directory", "/absolute/path/to/MCP",
      "python", "-m", "src.server"
    ],
    "transport": "stdio"
  }
}

Example Prompts for Claude

Once the server is connected, try these prompts:

  • "Analyze Apple stock and show me the full dashboard"

  • "What's the current price of RELIANCE.NS?"

  • "Show me Tesla's price history for the last 6 months"

  • "Compare NVDA with its sector peers"

  • "Run a technical analysis on MSFT"

  • "Give me an overview of the Technology sector"


uv Build & Run

Install Dependencies

# Navigate to the project directory
cd MCP

# Sync all dependencies (creates .venv automatically)
uv sync

This reads pyproject.toml and installs:

Dependency

Version

Purpose

mcp[cli]

≄ 1.0.0

MCP server SDK + CLI tools

prefab-ui

≄ 0.5.0

Interactive dashboard UI framework

yfinance

≄ 0.2.40

Yahoo Finance API wrapper

pandas

≄ 2.0.0

Data manipulation

numpy

≄ 1.24.0

Numerical computations

ta

≄ 0.11.0

Technical analysis indicators (RSI, MACD, Bollinger, etc.)

Run the MCP Server

# Option 1: Run with MCP Inspector (interactive testing UI in the browser)
uv run mcp dev src/server.py

# Option 2: Run directly via stdio transport (for AI assistants)
uv run python -m src.server

# Option 3: Use the console script alias
uv run stock-mcp

Run the Test Client

uv run python test_client.py

Preview Dashboard Standalone

uv run prefab serve src/ui/dashboard.py

Build a Distributable Wheel

# Build the wheel package
uv build

# The wheel is output to dist/
# dist/mcp_stock_analysis-1.0.0-py3-none-any.whl

Alternative: Install with pip

# Install in editable mode
pip install -e .

# Run the server
python -m src.server

Ticker Format

Market

Format

Example

US (NYSE / NASDAQ)

Plain symbol

AAPL, TSLA, MSFT, GOOGL

India (NSE)

Symbol + .NS

RELIANCE.NS, TCS.NS, INFY.NS

India (BSE)

Symbol + .BO

TATAMOTORS.BO, SBIN.BO


Project Structure

MCP/
ā”œā”€ā”€ pyproject.toml              # Project config, dependencies, build system, console scripts
ā”œā”€ā”€ uv.lock                     # Locked dependency versions
ā”œā”€ā”€ README.md                   # This file
ā”œā”€ā”€ test_client.py              # Interactive MCP client (stdio transport + local dashboard server)
ā”œā”€ā”€ data/                       # Persisted stock data (auto-created, JSON files + dashboard.html)
│   ā”œā”€ā”€ .gitkeep
│   ā”œā”€ā”€ AAPL_info.json
│   ā”œā”€ā”€ AAPL_history_1y.json
│   ā”œā”€ā”€ AAPL_analysis.json
│   ā”œā”€ā”€ AAPL_financials.json
│   ā”œā”€ā”€ AAPL_peers.json
│   ā”œā”€ā”€ AAPL_full_report_*.json
│   └── dashboard.html          # Last-generated interactive dashboard
└── src/
    ā”œā”€ā”€ __init__.py              # Package marker
    ā”œā”€ā”€ server.py                # MCPServer definition + 7 @mcp.tool() functions
    ā”œā”€ā”€ stock_data.py            # yfinance data fetcher (5 functions, 5 dataclasses)
    ā”œā”€ā”€ file_writer.py           # JSON persistence to data/ directory
    └── ui/
        ā”œā”€ā”€ __init__.py          # Package marker
        ā”œā”€ā”€ dashboard.py         # 6 PrefabApp builder functions
        └── components.py        # 7 reusable Prefab UI component builders

Tech Stack

Layer

Technology

Role

MCP Server

mcp (FastMCP Python SDK)

Tool registration, stdio transport, protocol handling

Data Source

yfinance

Yahoo Finance API wrapper for stock data

Technical Analysis

ta + pandas + numpy

RSI, MACD, Bollinger Bands, SMA/EMA computation

UI Framework

prefab-ui (PrefectHQ)

Declarative interactive dashboards (charts, tables, gauges)

File Storage

JSON (stdlib)

Structured data persistence to data/ directory

Build System

hatchling

PEP 517 build backend

Package Manager

uv

Fast dependency resolution and virtual environment management


License

MIT

Available Tools

7 tools
analyze_stockA

Perform a comprehensive stock analysis and generate an interactive dashboard.

Fetches company info, price history (short & long term), technical indicators, financial statements, and peer comparison. All data is persisted to JSON files. An interactive HTML dashboard is saved and a file:/// link is included in the response — always share this link with the user so they can view the full visual dashboard in their browser.

Args: ticker: Stock ticker symbol (e.g., AAPL, TSLA, RELIANCE.NS, TCS.NS)

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

No annotations are provided, so the description carries full behavioral burden. It discloses meaningful side effects an agent must know: JSON files are persisted to disk, an HTML dashboard is written, and a file link is returned that should be shared. It does not state auth requirements or failure modes, but the persistence/dashboard behavior is well conveyed.

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?

Front-loads the purpose, then the data fetched, then the important dashboard/file-link instruction. Slightly longer than strictly needed but every sentence earns its place by describing outputs and the persistence side effect.

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

Completeness4/5

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

For a complex aggregate tool with no annotations, the description covers what data is gathered, the disk side effects, the dashboard output, and how to use the returned link. An output schema exists, so return values need not be detailed. It is complete enough to invoke correctly, though it omits any auth or rate-limit considerations.

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

Parameters4/5

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

Schema coverage is 0% and there is one parameter. The description compensates by giving example ticker formats including exchange suffixes (AAPL, RELIANCE.NS, TCS.NS), which is real value beyond the bare 'string' in the schema.

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

Purpose5/5

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

States a specific verb+resource ('Perform a comprehensive stock analysis and generate an interactive dashboard') and the enumeration of fetched data (company info, price history, technical indicators, financials, peers) clearly positions it as the umbrella tool over siblings like get_stock_price and get_financials.

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

Usage Guidelines3/5

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

Does not explicitly tell the agent when to use this aggregate tool versus the narrower siblings. The scope (fetching many data types at once) implies it supersedes the specialized tools, but no exclusion or condition is stated.

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

compare_peersA

Compare a stock with its sector peers.

Identifies peer companies in the same sector and compares key metrics including P/E, ROE, margins, growth, and beta using radar charts and sortable data tables. A file:/// link to the interactive dashboard is included — always share it with the user.

Args: ticker: Stock ticker symbol (e.g., AAPL, RELIANCE.NS)

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the output artifacts (radar charts, sortable data tables, a file:/// interactive dashboard link) and gives an explicit directive to always share that link. Permissions/rate limits are not addressed, but for a read-only comparison this is a minor gap.

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?

Content is front-loaded with purpose first, then output behavior, then args. It is slightly padded by an Args block that partly duplicates the schema, but there is no real waste.

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

Completeness4/5

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

For a single-parameter tool with an output schema, the description is complete enough: it covers purpose, compared metrics, and output artifacts. Return values are already covered by the output schema, so no further explanation is needed for correct invocation.

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

Parameters4/5

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

Schema coverage is 0% (only 'type: string' for ticker), so the description must compensate, and it does by defining ticker as a stock ticker symbol and giving concrete examples including an international format (AAPL, RELIANCE.NS). This is meaningfully more than the bare schema provides.

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 states a specific verb (compare) and resource (a stock vs its sector peers) and enumerates the metrics compared (P/E, ROE, margins, growth, beta). This clearly distinguishes it from get_stock_price or get_financials, though it does not explicitly contrast with the similarly-named sibling get_sector_overview.

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?

There is no explicit when-to-use guidance and no alternatives are named. The agent must infer from the purpose that this tool is for peer comparison rather than standalone analysis, but no conditions or exclusions are provided to route between the six sibling tools.

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

get_financialsB

Get financial statements, key ratios, and balance sheet data.

Displays quarterly and annual revenue/income charts, profit margins, and balance sheet highlights in an interactive dashboard. A file:/// link to the interactive dashboard is included — always share it with the user.

Args: ticker: Stock ticker symbol (e.g., AAPL, RELIANCE.NS)

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/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. It does disclose the output form (an interactive dashboard with charts and highlights) and a non-obvious behavioral requirement to always share the file:/// link, but it omits auth needs, error behavior for invalid tickers, and rate limits.

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?

Front-loaded with the core purpose, then output behavior, then args. Efficient, with each sentence adding something, though the Args block could be tighter.

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

Completeness4/5

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

An output schema exists, so return values need not be explained; the description still adds a useful note that a dashboard link is returned and should be shared. Only error handling and invalid-ticker behavior are missing.

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

Parameters4/5

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

Schema coverage is 0%, so the description must compensate; it documents the single 'ticker' argument and adds meaningful format examples (AAPL, RELIANCE.NS) that reveal international ticker support not present in the schema.

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?

Specific verb 'get' plus resource 'financial statements, key ratios, and balance sheet data' clearly states what the tool returns. It is distinguishable from get_stock_price/get_stock_history by content, though it doesn't explicitly contrast itself with analyze_stock or compare_peers.

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 on when to choose this over sibling tools such as analyze_stock, compare_peers, or get_technical_analysis. The only directive ('always share it with the user') is an output-handling instruction, not selection guidance.

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

get_sector_overviewA

Get an overview of stocks in a specific market sector.

Shows market cap distribution, key metrics comparison, and a sortable table of stocks in the specified sector.

Supported sectors: Technology, Financial Services, Healthcare, Consumer Cyclical, Energy, Communication Services, Industrials, Consumer Defensive, Basic Materials, Real Estate, Utilities

Args: sector: Market sector name (e.g., Technology, Healthcare)

ParametersJSON Schema
NameRequiredDescriptionDefault
sectorYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/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. It implies read-only behavior via 'Get' and describes the output components (market cap distribution, key metrics, sortable table), but does not state permissions, data freshness, rate limits, or side effects. Some useful context, but not rich behavioral disclosure.

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?

Front-loads the purpose in the first sentence, then describes output and lists supported sectors before an Args section. The Args section slightly duplicates the supported sectors list, but overall the structure is efficient and easy to scan.

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

Completeness4/5

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

For a low-complexity, one-parameter tool with an output schema and no annotations, the description covers purpose, output content, and valid sector values. It omits explicit usage guidance relative to siblings and data freshness details, leaving minor gaps but nothing critical for correct invocation.

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

Parameters5/5

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

Schema description coverage is 0% for the single sector parameter, so the description must compensate. It does so thoroughly by listing all 11 supported sector values and giving examples, effectively documenting the allowed values even though the schema lacks an enum. Only minor gaps like case sensitivity remain.

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?

States a specific verb ('Get') and resource ('overview of stocks in a specific market sector'), and the description makes clear it is a sector-level aggregate rather than a single-stock tool. However, it does not explicitly name or distinguish itself from sibling tools like analyze_stock or compare_peers, so a 4 rather than 5.

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

Usage Guidelines3/5

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

No explicit when-to-use or when-not-to-use guidance, and no alternatives are named. The first sentence implies usage for sector-level overviews, and the supported sectors list helps parameter selection, but the agent must infer when to prefer this over individual stock tools. Implied usage only.

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

get_stock_historyA

Get stock price history with interactive charts.

Fetches OHLCV data for the specified period and displays it as an interactive area/line chart with volume bars. A file:/// link to the interactive dashboard is included — always share it with the user.

Args: ticker: Stock ticker symbol (e.g., AAPL, RELIANCE.NS) period: Time period - one of: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, max

ParametersJSON Schema
NameRequiredDescriptionDefault
periodNo1y
tickerYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

Without annotations, the description carries full burden and does well: it specifies the data type (OHLCV), the visualization (area/line chart with volume bars), and includes a file:/// link to an interactive dashboard with a clear instruction to always share it with the user. Missing details like rate limits or auth, but strong overall.

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?

Front-loaded with a clear one-sentence purpose, followed by concise details and an Args section listing all parameters. Every sentence earns its place with no redundancy.

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

Completeness4/5

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

For a low-complexity tool with an output schema, the description covers purpose, parameters, and behavioral traits. It does not explain return values beyond the chart/link, but the output schema handles that. Slightly missing edge-case or limitation notes keeps it from a 5.

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

Parameters5/5

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

With 0% schema description coverage, the description fully compensates by documenting both parameters: ticker with examples (AAPL, RELIANCE.NS) and period with an explicit list of allowed values (1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, max).

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

Purpose5/5

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

States a specific verb (Get) and resource (stock price history), and names the output format (interactive charts). Clear enough to distinguish from siblings like get_stock_price and analyze_stock.

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

Usage Guidelines3/5

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

No explicit when-to-use or when-not-to-use guidance is given. The name and context imply it is for historical price data, but the description does not compare it to siblings such as get_stock_price or analyze_stock.

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

get_stock_priceA

Get the current stock price with day change and key metrics.

Quick lookup tool that returns current price, day change, and key metrics directly as text.

Args: ticker: Stock ticker symbol (e.g., AAPL, RELIANCE.NS)

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

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

No annotations exist, so the description carries the full burden. It does disclose that results come back 'directly as text' rather than structured data, which is useful. It says nothing about data freshness/delay, rate limits, or auth requirements, which matter for a market-data tool.

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?

Front-loaded with the core purpose and compact overall. The second sentence partly restates the first (price/day change/key metrics), a minor redundancy rather than bloat.

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

Completeness4/5

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

An output schema exists, so return-value detail is largely handled elsewhere; the description still names the main fields. For a one-parameter lookup tool this is nearly sufficient, with only freshness/auth caveats missing.

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

Parameters4/5

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

Schema description coverage is 0%, so the schema gives no help for the single ticker parameter. The description compensates by supplying concrete example formats including an exchange-suffixed symbol (AAPL, RELIANCE.NS), clarifying accepted syntax beyond the bare 'string' type.

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?

States a specific verb ('Get') and resource ('current stock price') plus what payload comes back (day change, key metrics). It is distinguishable from siblings like get_stock_history or analyze_stock, though it never explicitly contrasts itself with them.

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

Usage Guidelines3/5

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

The phrase 'Quick lookup tool' implies this is for fast, single-ticker spot checks, which is a usable usage cue. However, it gives no explicit when-to-use vs when-not guidance or names alternatives such as get_stock_history for trend data.

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

get_technical_analysisA

Get technical analysis with RSI, MACD, Bollinger Bands, and moving averages.

Computes and displays technical indicators including:

  • RSI (14) with overbought/oversold signals

  • MACD (12, 26, 9) with histogram

  • Bollinger Bands (20, 2)

  • SMA (20, 50, 200) and EMA (12, 26)

  • Overall Buy/Sell/Hold signal

A file:/// link to the interactive dashboard is included — always share it with the user.

Args: ticker: Stock ticker symbol (e.g., AAPL, RELIANCE.NS)

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It usefully discloses the output composition and the fact that a file:// interactive dashboard link is returned and must be shared, which is genuine behavioral context. It omits auth requirements, rate limits, and any note on latency or failure modes for invalid tickers.

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?

Purpose is front-loaded in the first line, details are structured as a compact bullet list, and the sharing instruction is stated once without padding. Every element earns its place.

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

Completeness4/5

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

An output schema exists, so return-value explanation is not strictly needed, yet the description still orients the agent on indicator set and the dashboard link. Combined with ticker-format guidance, an agent has what it needs to call it correctly; only ticker-suffix rules and sibling routing are left open.

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

Parameters4/5

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

Schema coverage is 0% and the single required parameter is undocumented in the schema, so the description must compensate — and it does by giving concrete examples (AAPL, RELIANCE.NS) that reveal exchange-suffix formatting. This adds meaning the schema lacks, though it does not say whether the suffix is required or optional.

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?

States a specific verb (Get) and resource (technical analysis) and enumerates exactly what is computed (RSI, MACD, Bollinger Bands, SMA/EMA, overall signal). It does not, however, differentiate itself from the sibling 'analyze_stock', which likely overlaps — an agent cannot tell from this text which one to pick.

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

Usage Guidelines3/5

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

Usage is implied by the indicator list (invoke when you need technical indicators for a ticker), and it gives one behavioral instruction — always share the file:// dashboard link. There is no explicit when-to-use vs. analyze_stock or get_stock_price routing, and no exclusions or prerequisites.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv1.0.0
    • First observedanalyze_stock
    • First observedcompare_peers
    • First observedget_financials
    • First observedget_sector_overview
    • First observedget_stock_history
    • First observedget_stock_price
    • First observedget_technical_analysis

TDQS

A3.9/5.0

Scored across 7 tools

Disambiguation4/5

Individual tools target distinct data types (price, history, financials, technicals, peers, sector), but analyze_stock is an umbrella that duplicates all of them. Descriptions clarify intent, yet an agent may still wonder whether to call the comprehensive tool or the specialized ones.

Naming Consistency5/5

All tool names use snake_case with a verb-first pattern (analyze_stock, get_stock_price, get_stock_history, compare_peers, etc.). The convention is consistent and predictable across the set.

Tool Count5/5

Seven tools is well-scoped for a stock analysis server, covering core retrieval tasks without excessive fragmentation. Each tool has a clear role and none feels redundant beyond the umbrella analysis tool.

Completeness4/5

Core coverage is strong: current price, history, financials, technicals, peer comparison, sector overview, and a comprehensive analysis tool. Minor gaps include standalone tools for company profile, news, dividends, or earnings, but these are workable for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    F
    maintenance
    Provides real-time stock market data and financial analysis through Yahoo Finance integration. Enables users to get quotes, historical prices, fundamentals, dividends, analyst forecasts, and growth projections for any stock symbol.
    4
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides real-time stock quotes, historical price data, financial news, and multi-stock comparisons using Yahoo Finance data. Enables users to access comprehensive financial market information through natural language queries.
    447 npm
    MIT
  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides real-time financial data from Yahoo Finance, enabling stock price lookups, historical data analysis, company information retrieval, and multi-stock comparisons through natural language queries.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides comprehensive financial data from Yahoo Finance, enabling retrieval of stock prices, company information, financial statements, options data, analyst recommendations, and market news through natural language queries.
    MIT