Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This server defines 5 tools with explicit schemas and descriptions, but has critical gaps in parameter documentation and output schema specification. Tool naming follows verb_noun convention (get_, place_), but parameter descriptions are inconsistent and sparse. The server lacks any documented output schema structure, making it impossible for LLMs to plan downstream operations. Error handling is absent from visible code. The server operates over STDIO, which limits its production applicability. Overall quality is below median for production-grade MCP servers.
No output schemas documented for any tool. LLMs cannot determine what fields to expect in responses, breaking tool chaining and forcing extra discovery calls.
Irreversible operations (place_buy_order, place_sell_order) lack any confirmation or dry-run capability. An agent mistake will execute trades without recourse.
Parameter descriptions are inconsistent and sparse. 'symbol' parameter in get_bars has no description. 'order_type' enum values are documented in description text, not as formal JSON Schema enum constraint. 'price' parameter behavior depends on 'order_type' (required for Limit, ignored for Market), but this mutual dependency is not documented.
tradestation_get_barstradestation_place_buy_order
Recommendations
Add explicit output schemas to all tools. For get_bars, document: {bars: [{timestamp, open, high, low, close, volume}, ...], symbol, unit, interval}. For place_buy_order/sell_order, document: {order_id, symbol, size, price, order_type, status, created_at}. For get_positions/balances, document the field structure (e.g., {positions: [{symbol, shares, entry_price, current_price}, ...]}). See pattern:response-shaper.
Convert 'order_type' and 'unit' from free-form strings to formal JSON Schema enum constraints. Example: 'order_type': {'type': 'string', 'enum': ['Market', 'Limit', 'StopMarket'], 'description': 'Type of order...'}. This prevents LLM hallucination.
Add min/max constraints to all numeric parameters. Example: 'interval': {'type': 'number', 'minimum': 1, 'maximum': 1440, 'description': 'Minutes per bar (1-1440)...'}. Example: 'size': {'type': 'number', 'minimum': 1, 'description': 'Number of shares (minimum 1)...'}.
Expand tool descriptions to 50-150 characters with WHAT, WHEN, and what it returns. Example for get_positions: 'Retrieve all open positions in the account. Call this to review current holdings, entry prices, and P&L before placing new orders. Returns array of {symbol, shares, entry_price, current_price, unrealized_pnl}.'
Add parameter descriptions to all undescribed parameters. Example: 'symbol' in get_bars should be 'Stock or ETF ticker symbol (e.g., AAPL, SPY)'. Example: 'price' in place_sell_order should be 'Limit price (required for order_type=Limit, ignored for Market).'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Tool descriptions are too brief to guide LLM selection. 'Get account positions' (30 chars) and 'Get account balances' (20 chars) lack context on WHEN to call them, what data structure they return, or their relationship to other tools.
No error handling documented. Code shows bare 'ValueError' for unknown tool names (src/portfolio_service/brokers/tradestation/tools.py:call_tool), and no guidance for API failures, authentication errors, or insufficient balance/permissions.
Parameter 'order_type' uses free-form string with enum values only in description text ('Possible values are Market, Limit, StopMarket'). Should be a formal JSON Schema enum constraint to prevent LLM hallucination of invalid order types.
Parameter 'unit' in get_bars is free-form string with enum values only in description ('Minute, Daily, Weekly, Monthly'). Should be a formal enum in JSON Schema.
Document mutual parameter dependencies in descriptions. Example: 'price' parameter should state: 'Required if order_type=Limit; ignored if order_type=Market or StopMarket.' Example: bars_back/firstdate should state 'Choose one: either bars_back (for recent bars) or firstdate (for historical range).'
Implement confirmation flow for irreversible operations. Add a 'tradestation_confirm_buy_order' or dry-run variant that returns order preview without execution. See pattern:confirmation-request.
Add comprehensive error handling with actionable guidance. Example: if symbol not found, return 'Symbol "XYZ" not found. Did you mean: XYZK (related ticker)?' Example: if insufficient balance, return 'Insufficient buying power ($X needed, $Y available). Reduce size or deposit funds first.' See pattern:recovery-guide.
Add per-tool permission scopes and security notes. Document that place_buy_order and place_sell_order require real-money trading permissions and should only be called after explicit user consent. See pattern:scope-declaration.
Expand tool descriptions for read-only tools. Example for get_balances: 'Retrieve account balances including total equity, available cash, and buying power. Call this before placing orders to verify sufficient funds. Returns {total_equity, cash_balance, buying_power, margin_used}.'
Consider adding a 'list_positions' or 'describe_account' discovery tool that returns account metadata (account_type, currency, margin_ratio, trading_hours) to help agents understand account constraints before executing trades.