This MCP server has severe definition quality issues across nearly all 20 tools. Transport is unknown (hard cap 40/100), tool definitions are inferred from source code rather than explicit MCP registration, input schemas are largely missing or incomplete, and descriptions lack the specificity needed for LLM-driven tool selection. Most tools have generic descriptions (10-40 chars) that fail to explain WHEN to use them or what distinguishes them from similar tools. Parameter schemas are inconsistent: some tools like 'add_price_alert' show partial type information (Decimal, ConditionType, datetime) but these are not JSON Schema validated, and many parameters lack descriptions. No output schemas are documented. Error handling is absent, no recovery guidance, no error categorization. The codebase shows a portfolio management domain but does not conform to MCP's tool contract (stateless, schema-driven, agent-optimized).
No input schemas visible for 11 of 20 tools (analyze_portfolio, validate_portfolio, generate_rebalance_recommendations, get_active_alerts, get_rebalancing_history, get_rebalancing_costs, generate_insights, get_portfolio_summary, and others). Per HARD SCORING RULE, tools without visible schemas must score 0 for schema.
Descriptions are uniformly generic and under 25 characters (e.g. 'Validate the current portfolio against all policies'). Current descriptions do not explain when to use validate_portfolio vs validate_recommendations, or how get_portfolio_insights differs from get_market_insights.
Convert all 20 tools to explicit MCP tool registration with complete JSON Schema input/output definitions. Use the sample in agents/analysis_agent.py (PortfolioAnalysis dataclass) as a template for structured return types.
Expand every tool description to 100-200 chars using the formula: [VERB] [OBJECT] to [OUTCOME]. When to use: [CONDITION]. Example: 'Perform comprehensive portfolio analysis to identify asset allocation, sector exposure, and risk metrics. Use this to understand current portfolio composition before making rebalancing decisions. Requires a loaded portfolio manager instance.'
For tools with parameters, add a JSON Schema description field for each. Example for 'recommendations' in validate_recommendations: 'Dictionary mapping stock symbols to weight changes as decimals (e.g. {"AAPL": 0.05, "MSFT": -0.03}). Weights must sum to zero and values must be in range [-1.0, 1.0].'
Document output schemas inline or in a separate schema registry. For get_portfolio_summary, specify: 'Returns {portfolio_id: string, total_value: float, currency: string, last_updated: ISO8601, holdings_count: int, asset_allocation: {symbol: weight}, sector_allocation: {sector: weight}, risk_metrics: {...}, performance_metrics: {...}}'.
Add error handling with recovery guidance to validate_recommendations, add_price_alert, add_risk_alert, add_performance_alert, get_market_insights, and evaluate_strategy. Example: 'If symbol not found: ensure ticker is correct. If policy violation: return the specific constraint that was breached and suggest next steps (e.g. "reduce position size").'
Tools with complex parameters (add_price_alert, add_risk_alert, add_performance_alert) show type hints (Decimal, ConditionType, datetime) but these are not validated JSON Schema. ConditionType is never defined in visible code; LLMs cannot infer whether it accepts 'above'/'below' or 'gt'/'lt'.
No output schemas documented for any tool. Callers cannot anticipate return structures (e.g. does get_portfolio_summary return {total_value, currency, holdings_count} or raw nested objects?).
Tool definitions are inferred from source code (agents/analysis_agent.py, dcm/alerts.py) rather than explicitly registered via MCP. Per HARD SCORING RULE, inferred tool definitions cap per-tool scores at 50. No evidence of MCP tool registration, stateless request handling, or _meta logLevel support visible in provided code.
No error handling or recovery guidance visible. Tools do not specify error classification (retryable, user-fixable, fatal) or next steps. E.g. validate_recommendations could fail due to invalid symbol, policy violation, or missing market data, none of these scenarios are handled with actionable error messages.
Parameter descriptions missing or trivial. E.g. 'recommendations' in validate_recommendations is described as 'Dictionary of symbol to weight change recommendations' but does not explain format (are weights 0-1 or 0-100?), validation rules, or example usage.
Three near-identical alert tools (add_price_alert, add_risk_alert, add_performance_alert) with overlapping parameter sets. Per pattern:tool, tools doing the same thing differently waste LLM reasoning. These should likely be a single add_alert(alert_type, symbol, metric, ...) tool or clearly distinguished by use case.
set_rebalance_callback accepts a Callable parameter, LLMs cannot pass Python functions or lambda closures. Per pattern:tool-gateway, sensitive operations should use permission checks and audit trails, not callback injection. This design is not agent-friendly.
No tool annotations visible (readOnlyHint, destructiveHint, idempotentHint). Per current MCP spec (2026-07-28), tools should declare whether they modify state. E.g. add_price_alert, record_rebalance, set_rebalance_callback are destructive; most get_* tools are read-only. Annotations aid agent planning.
Define ConditionType enum explicitly. Add to alert parameter descriptions: 'condition: one of ["above", "below"]. Example: "above" triggers alert when price exceeds threshold.'
Consolidate add_price_alert, add_risk_alert, add_performance_alert into a single add_alert(alert_type, symbol, ...) tool or rename to be unambiguous: add_price_threshold_alert, add_risk_metric_alert, add_performance_metric_alert.
Replace set_rebalance_callback(callback: Callable) with a configuration tool or event subscription pattern. Example: add_rebalance_trigger(alert_id: string, action: "auto_rebalance" | "notify_user") so LLMs cannot inject arbitrary code.
Add tool annotations to the MCP schema: mark add_price_alert, add_risk_alert, add_performance_alert, record_rebalance, deactivate_alert, set_rebalance_callback as destructiveHint=true; mark all get_* and analyze_* tools as readOnlyHint=true.
For list-returning tools (get_active_alerts, get_rebalancing_history), add pagination parameters: limit (1-100, default 20) and offset. Return {items: [...], total: int, limit: int, offset: int} so agents can iterate large result sets.
Review validate_portfolio and validate_recommendations return structure. Ensure both return {is_valid: bool, violations: [string], warnings: [string]} consistently so agents can check either tool and interpret results identically.
Add missing parameter descriptions: evaluate_strategy's 'portfolio_manager' parameter is typed as PortfolioManager but agents cannot construct this. Document its source or redesign to accept portfolio_id: string instead.