This server has significant definition quality gaps across most dimensions. While tool names follow verb_noun convention and schemas are present, descriptions lack depth and error handling is minimal. 9 of 10 tools have generic descriptions under 150 characters that fail to explain WHEN to use them or WHAT prerequisites exist. Parameter descriptions are sparse (e.g., 'Stock symbol e.g. RELIANCE' repeated across many tools with no format constraints). No output schemas are documented. Error handling is basic string returns with no recovery guidance. The single WRITE operation (place_virtual_trade) lacks confirmation patterns or dry-run support. This server is typical of community MCP tools, functional but not production-grade.
Descriptions severely lack LLM decision context. Most tools (analyze_sentiment, get_portfolio_pnl, scan_market, get_sector_heatmap) have descriptions under 100 characters that do not explain WHEN the tool should be called instead of similar alternatives, WHAT data it requires beyond the parameter name, or WHAT the agent should do with the result. Examples: 'Analyze news sentiment for a stock symbol and generate a trade bias (BUY/SELL/HOLD) based on sentiment score' (92 chars) does not explain how sentiment differs from technical signals, or what 'sentiment score' means numerically.
Output schemas are completely undocumented. The source code shows that tools return JSON (e.g., {'price': 1412.8, 'change_pct': -0.41} for get_live_price, {'sentiment_score': ..., 'signal': 'BUY|SELL|HOLD'} for analyze_sentiment), but the tool definitions do NOT include documented return schemas. LLMs cannot plan downstream tool calls or know which fields to extract without this. The rubric baseline shows 100% of A+ tools have documented return types.
get_live_priceget_options_chain
Recommendations
Expand tool descriptions to 100-200 characters, following the rubric baseline. For each tool, answer: What does it do? When should the LLM call it (vs similar tools)? What data does it return? Example: 'analyze_sentiment' should read: 'Analyze news headlines for a stock to generate a quantitative sentiment score (0 - 100). Use this BEFORE generate_signal to understand market narrative. Returns sentiment_score (0=very negative, 100=very positive), headlines, and trade_bias (BUY/SELL/HOLD). Requires NEWS_API_KEY; defaults to neutral (50) if unconfigured.'
Document output schemas for ALL tools. Add a 'returns' field to each tool definition showing the JSON structure. Example for get_live_price: returns: {type: 'object', properties: {price: {type: 'number'}, change_pct: {type: 'number'}, volume: {type: 'number'}, symbol: {type: 'string'}}}
Add JSON Schema enum constraints for categorical parameters. Convert 'side' (place_virtual_trade) and 'option_type' (calculate_greeks) from free-form strings to enums: {type: 'string', enum: ['BUY', 'SELL']} and {type: 'string', enum: ['CE', 'PE']}. Add timeframe enum to generate_signal if '1d', '1h', '15m' are valid values.
Replace cookie-cutter parameter descriptions with format constraints. For 'symbol', change 'Stock symbol e.g. RELIANCE, TCS, NIFTY' to 'NSE/BSE stock ticker (uppercase, 1 - 10 chars) or index name (NIFTY, NIFTY50, SENSEX, BANKNIFTY). Case-insensitive. Do not include .NS or .BO suffix; the tool resolves it internally.' For 'expiry' in get_options_chain, add format: 'ISO 8601 date (YYYY-MM-DD). Must be a valid expiry in the options calendar. If omitted, defaults to the nearest expiry.'
Score history
Overall score trend
First recorded score · v2 rubric
47/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
F
47
2026-07-28+
v2
source verified
62/100
Get real-time profit/loss for all positions in the virtual portfolio
get_sector_heatmapread onlysource verified62/100
Get sector-wise average % change heatmap for IT, Banking, Auto, Pharma, Energy, and FMCG
place_virtual_tradewritesource verified62/100
Execute a virtual BUY or SELL trade at the current live market price with optional stop-loss and target alerts
scan_marketread onlysource verified60/100
Scan Nifty 50 stocks with filters for price range, change percentage, and sector
Parameter descriptions are cookie-cutter and lack actionable constraints. 'Stock symbol e.g. RELIANCE, TCS, NIFTY' appears identically across 8 tools but does not specify: valid length, allowed characters, case sensitivity, whether the tool accepts index names (NIFTY is an index, not a stock), or how to look up valid symbols. The rubric requires 'The project key (2-10 uppercase letters, e.g. PROJ)', specific format constraints, not generic examples.
Missing enum constraints on free-form string parameters. 'side' (place_virtual_trade) accepts 'BUY' or 'SELL' but this is documented only as a parameter description string, not as a JSON Schema enum. 'timeframe' (generate_signal) likely accepts '1d', '1h', '15m', etc., but no enum is specified. LLMs cannot validate before calling and will hallucinate invalid values. The rubric requires: when a parameter accepts one of a known set of values, declare it as an enum.
place_virtual_trade (the only WRITE operation) lacks confirmation or dry-run support. An agent can execute 'place_virtual_trade(RELIANCE, 100, BUY)' with no confirmation step, immediately committing a virtual trade. While virtual, the pattern still violates the principle that irreversible operations should support confirm-before-execute or dry-run. No dry-run parameter exists, and the description does not mention confirmation.
Error handling is minimalist and lacks recovery guidance. The source code shows basic string error returns like {'error': 'symbol is required'} but does not implement the pattern of actionable error responses. Example: if analyze_sentiment fails due to missing NewsAPI key, it defaults to neutral (score=50) with no indication to the user that data is degraded. A production tool should return {'error': 'NewsAPI key not configured. Sentiment will default to neutral (score=50). Set NEWS_API_KEY in modules/tools.py to enable live news analysis.'}, giving the agent next steps.
No pagination support despite likely large result sets. scan_market and get_options_chain may return many results (50+ options strikes, 100+ stocks in scan), but neither tool accepts limit or offset/page parameters. The rubric requires tools returning lists to accept pagination parameters and return a total count or next_cursor. Without pagination, large results blow the context window.
Parameter naming lacks type suffixes, leading to potential LLM confusion. 'symbol' is used across all tools but not clarified as symbol_name vs symbol_id. 'expiry' in get_options_chain could mean expiry_date or expiry_timestamp; the format 'YYYY-MM-DD' is described but not enforced via format constraint in schema. Numeric parameters like 'min_price', 'max_price' in scan_market lack min/max bounds in the schema. The rubric baseline shows A+ tools use suffixes (user_id, user_name, user_email) and explicit range constraints.
Undocumented parameter dependencies. In generate_signal, the 'timeframe' parameter behavior likely depends on whether the underlying API supports that timeframe, but no dependency hints are provided. calculate_greeks accepts optional volatility and risk_free_rate with defaults (0.20, 0.065) but does not explain why these defaults are appropriate for Indian equities or when the agent should override them. The rubric requires: 'If parameters are mutually exclusive or dependent, state this in descriptions.'
Implement pagination for list-returning tools. Add limit (default 20, max 100) and offset (default 0) parameters to scan_market, get_options_chain, and detect_unusual_activity. Return a response object with 'results' array, 'total' count, and 'has_more' boolean so agents can iterate.
Add a dry-run or confirmation step for place_virtual_trade. Option A: add a 'confirm' boolean parameter (default false), when false, return a preview without executing. Option B: return result type 'pending' (Multi Round-Trip Requests pattern) asking the user to confirm before committing. At minimum, the tool description must state: 'This tool executes immediately. Review the parameters carefully before calling.'
Improve error handling with actionable recovery guidance. When NewsAPI key is missing in analyze_sentiment or generate_signal, return {error: 'NewsAPI key not configured. Sentiment analysis will default to neutral (score=50). To enable live news analysis, set NEWS_API_KEY in modules/tools.py to a valid key from https://newsapi.org.', code: 'MISSING_API_KEY', is_retryable: false}. When a symbol is not found, return {error: 'Symbol INVALID_SYM not found in NSE/BSE. Did you mean: INFY, INFOSYS?', available_symbols: [nearest matches]}.
Document parameter dependencies explicitly. In calculate_greeks, note: 'volatility and risk_free_rate are optional. Defaults (volatility=0.20, risk_free_rate=0.065) assume 20% implied volatility and 6.5% India risk-free rate. Override if you have a different market assumption.' In generate_signal, clarify: 'timeframe defaults to 1d (daily). Other valid values depend on the data provider; common values: 1h, 15m, 5m. If an invalid timeframe is passed, the tool returns an error with available options.'
Add type-specific parameter naming where ambiguous. Change 'symbol' to 'symbol_name' to clarify it is a display name, not an internal ID. Change 'expiry' to 'expiry_date' to clarify format. For optional parameters with defaults, note the defaults in descriptions: 'sector (optional, default: all sectors), filter results to a specific sector. Valid values: IT, Banking, Auto, Pharma, Energy, FMCG.'
Validate inputs early and return clear constraint violations. If a user passes symbol='reliance' (lowercase), either normalize it or return {error: 'Symbol must be uppercase. Did you mean: RELIANCE?', suggestion: 'RELIANCE'}. If quantity is negative in place_virtual_trade, return {error: 'Quantity must be positive integer (got -100). To SELL, set side=SELL with a positive quantity.', code: 'INVALID_QUANTITY', is_retryable: false}.
Strip irrelevant API metadata from responses. If get_live_price returns yfinance raw data with 50 fields, return only: {symbol, price, change_pct, volume, timestamp}. Every extra field wastes tokens and dilutes signal. Document in the tool: 'Returns a compact summary of live market data; does not include intraday chart, fundamental ratios, or analyst ratings. Use generate_signal for comprehensive analysis.'
Add dependency hints to discovery tools. For scan_market, note: 'Use this to discover stocks matching your criteria (price range, sector, % change). Once you find an interesting stock, call generate_signal or analyze_sentiment to get actionable trade signals.' For get_options_chain, note: 'Fetch all available option strikes and expiries for a stock. To price a specific option or assess its risk, pass strike_price and expiry_days to calculate_greeks.'
Ensure tool chain continuity. Verify that outputs from one tool contain IDs/references the next tool accepts. For example, scan_market returns a list of symbols, verify that get_live_price, analyze_sentiment, and generate_signal all accept those symbols directly. If scan_market returns {symbol: 'RELIANCE', ...}, then generate_signal must accept symbol='RELIANCE' without requiring a lookup.