A comprehensive MCP server for stock market analysis with price data, portfolio management, technical analysis, alerts, dividend tracking, sector analysis, risk metrics, and market sentiment tracking
Stock Market Analyzer has 22 tools with mixed definition quality. All tools have descriptions and input schemas present in the source code. Naming is generally strong (verb-noun pattern: get_*, set_*, calculate_*, etc.). However, there are notable gaps: (1) descriptions lack WHEN/WHY guidance for agent decision-making, they state WHAT but rarely explain when to call this tool vs. a similar one; (2) many parameters lack detailed constraints (e.g., 'period' accepted as free-form string '1mo', '6mo', '1y', '5y' without enum constraint); (3) no output schemas are documented, forcing LLMs to infer response structure; (4) error handling is basic (try/except returning error strings) with no recovery guidance; (5) tool composition has redundancy (e.g., both check_alerts and list_alerts return alert status, creating decision ambiguity for agents). Strengths: all 22 tools have non-empty descriptions (90+ chars typical), all parameters have type annotations (string, number, integer), risk classifications are present (READ_ONLY vs WRITE), and naming is consistently verb-first. Weaknesses prevent this from reaching 60+.
Add a stock holding to your portfolio.
Analyzes a stock for a potential buy opportunity using a simple moving average (SMA) crossover. A buy signal is indicated when the short-term SMA crosses above the long-term SMA.
Comprehensive trend analysis combining multiple indicators.
Calculate Beta - measures stock volatility relative to market. Beta > 1: More volatile than market. Beta < 1: Less volatile than market. Beta = 1: Moves with market.
Calculate MACD (Moving Average Convergence Divergence) for trend analysis. MACD crossing above signal line indicates bullish, below indicates bearish.
Calculate expected annual dividend income from your portfolio holdings.
No output schemas documented. LLMs cannot infer what fields each tool returns, forcing agents to guess field names for downstream operations. E.g., after view_portfolio(), the agent doesn't know the field structure (is it 'total_value', 'portfolio_value', 'current_value'?) and may make wrong assumptions. This breaks tool chaining.
Parameter constraints not enforced via enums or formal schemas. The 'period' parameter (used in 6+ tools) accepts free-form strings like '1mo', '6mo', '1y', '5y', 'max' without enum constraint. LLMs may hallucinate invalid values ('2years', 'last_year', '12m'). Should be: enum=['1mo', '3mo', '6mo', '1y', '5y', 'max'].
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 53 | - | v1 |
Calculate comprehensive risk metrics for your entire portfolio. Includes volatility, beta, Sharpe ratio, and diversification metrics.
Calculate the Relative Strength Index (RSI) for a stock. RSI values above 70 indicate overbought, below 30 indicate oversold.
Calculate the Sharpe Ratio for a stock. Measures risk-adjusted return. Higher Sharpe ratio indicates better risk-adjusted performance.
Check all active alerts and see which ones have been triggered.
Find stocks with high dividend yields. Searches popular dividend-paying stocks.
Get dividend payment history for a stock.
Get current dividend yield and related metrics for a stock.
Gets historical price data (Open, High, Low, Close, Volume) for a stock.
Gets the most recent market price for a given stock ticker.
Get comprehensive information about a stock including fundamentals and key metrics.
List all configured alerts (active and triggered).
Remove (sell) shares from your portfolio.
Set a price alert for a stock. You'll be notified when checking alerts if the condition is met.
Set an RSI alert for a stock. Useful for overbought (RSI > 70) or oversold (RSI < 30) notifications.
View all current holdings with current prices and profit/loss.
View recent transaction history.
alert_type parameter accepts 'above' or 'below' but is documented as free-form string with no enum constraint. Both set_price_alert and set_rsi_alert should declare alert_type as enum=['above', 'below']. Current implementation relies on runtime validation in the tool code; agents may still pass invalid values.
Redundant tools with unclear distinction. Both check_alerts and list_alerts appear to return alert status; the difference is not documented. LLMs will struggle to choose between them. One should be removed or their purposes clarified (e.g., check_alerts = triggered status, list_alerts = all configured alerts). Same issue with view_portfolio (current holdings) vs view_transactions (history), the distinction is clear in names but not in descriptions.
Descriptions lack WHEN guidance. Examples: 'Get comprehensive information about a stock...' (get_stock_info) does not explain when to call this vs get_latest_price or get_historical_data. Descriptions answer WHAT, not WHEN. Per pattern:tool-description, descriptions should include 'When should the LLM call it instead of a similar tool?'
No pagination parameters on list-like tools. view_transactions accepts a 'limit' parameter (good), but view_portfolio, list_alerts, and check_alerts do not. If a user has 1000+ holdings or alerts, these tools risk returning unbounded lists that exhaust context windows. Per pattern:paginated-result, list tools should accept limit and offset/cursor.
Error handling returns raw exception strings (e.g., 'Error setting price alert: {e}'). Per pattern:recovery-guide, errors should guide LLM recovery: 'Invalid ticker. Try search_stocks() to find the correct symbol.' Current errors are generic and non-actionable.
Risk classification present (READ_ONLY vs WRITE) but no tool annotations in MCP schema. Per current spec (2026-07-28), tools should include readOnlyHint, destructiveHint, and idempotentHint. This metadata helps agents reason about side effects and retry safety. No evidence of these annotations in the FastMCP server code.
Date parameter format not validated. purchase_date, sale_date, and dividend history calls accept 'YYYY-MM-DD' per description, but no enum or regex pattern enforces it. LLMs may pass 'Jan 15 2024' or '01/15/2024', causing silent failures. Should declare: format='date' or pattern='^\d{4}-\d{2}-\d{2}$'.