Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The Aster MCP server provides 37 tools covering futures and spot trading. Most tools have descriptions in Chinese and input schemas with basic type definitions. However, there are significant gaps: descriptions are often generic and lack LLM-optimized context; parameter descriptions are minimal (many under 50 characters); output schemas are not documented; error handling guidance is absent; and several security concerns exist around API key exposure. The tool set is well-scoped (read-only market data, account queries, order management, fund transfers) but lacks the polish and explicitness expected of production-grade agent tools.
Descriptions lack LLM-optimized context. Most descriptions are 40 - 60 characters, providing minimal guidance on WHEN to use each tool or what distinguishes similar tools. Example: 'get_positions' is described as '查询持仓。symbol 可选过滤' (Query positions. symbol optional filter). This does not explain whether positions refer to open orders, holdings, margin positions, or leveraged exposure. LLMs cannot disambiguate overlapping tools without clearer context.
Parameter descriptions are minimal or missing. Many parameters lack detail on format, constraints, or valid ranges. Example: 'interval' in get_klines is described as '时间间隔' (time interval) with a default of '1h', but the description does not state that valid values are '1m, 5m, 1h, 4h, 1d' (these appear in the tool description, not the parameter schema). Similarly, 'time_in_force' in create_order has no description at all, the LLM cannot know whether it accepts 'GTC', 'IOC', 'FOK', or other values.
Recommendations
Expand each tool description to 100 - 200 characters. Include WHAT it does, WHEN to use it (vs. similar tools), and a brief description of the return value. Example: 'get_futures_balance, Retrieve your futures account balance (total wallet balance, available balance, unrealized PnL). Use this to check funds before placing orders. Returns an object with { totalWalletBalance, totalUnrealizedProfit, availableBalance }.'
Add descriptions to every parameter. Specify format, constraints, valid values, and examples. Example for 'interval' in get_klines: 'Time interval for candles. Valid values: 1m, 5m, 15m, 1h, 4h, 1d. Default: 1h. Example: "5m" for 5-minute candles.' For 'side': 'Trade direction: BUY (go long) or SELL (go short). Required.'
Document output schemas for each tool. Include a brief description of returned fields and their types. Example: 'Returns { symbol, price (number), timestamp (ISO 8601), 24hChange (%), bid, ask }' or 'Returns array of position objects: [{ symbol, quantity, entryPrice, currentPrice, unrealizedPnL, leverage }].'
Add error handling guidance. For each tool, describe what errors can occur and what the LLM should do. Example: 'If account_id is invalid, returns error: "Account not found. Call list_accounts() to see valid IDs." If balance is insufficient, returns: "Insufficient balance. Current balance: $100, required: $150. Call transfer_funds() to deposit more."'
Use enum constraints for categorical parameters. Replace 'side' (string) with enum: ['BUY', 'SELL']. Replace 'order_type' with enum: ['LIMIT', 'MARKET', 'STOP', 'STOP_MARKET']. Replace 'margin_mode' with enum: ['ISOLATED', 'CROSSED']. This prevents hallucinated invalid values.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Output schemas are not documented. The tool descriptions do not specify what fields are returned, their types, or structure. For example, get_account_info says it returns 'account info (including position summary)' but does not document whether it returns a single object with fields like 'totalWalletBalance', 'totalUnrealizedProfit', 'positions', or an array. This forces LLMs to guess at response structure and invites failed downstream tool calls.
No error handling guidance. Tools lack descriptions of failure modes or recovery steps. Example: if 'account_id' is invalid, what error is returned? What should the LLM do, retry, ask the user, or call a discovery tool? If create_order fails due to insufficient balance, should it suggest calling transfer_funds? Absent error guidance, the LLM cannot plan recovery and will retry blindly or fail.
Credentials stored in ConfigManager without server-side injection pattern. The code shows AsterClient initialized with api_key and api_secret passed from config. If these are loaded from environment or config files that are accessible to the tool process, they risk exposure in logs or traces. The pattern:secret-injection requires credentials to never appear as tool parameters, but the implementation pattern suggests they may be stored in process memory and accessible via introspection.
Overlapping and ambiguous tool names. Multiple 'get_*' tools operate on the same resource types with unclear distinctions. Example: 'get_balance', 'get_account_info', 'get_account_v4' all query account state, the LLM cannot easily decide which to call. Similarly, futures and spot variants ('get_ticker' vs 'get_spot_ticker', 'create_order' vs 'create_spot_order') are prefixed inconsistently. Consider renaming to 'get_futures_balance' / 'get_spot_balance' for clarity.
Missing enum constraints for string parameters. Parameters like 'side' (BUY/SELL), 'order_type' (LIMIT/MARKET/STOP/STOP_MARKET), 'margin_mode' (ISOLATED/CROSSED), 'income_type' (TRANSFER/REALIZED_PNL/FUNDING_FEE/COMMISSION) are free-form strings with no enum schema. LLMs will hallucinate invalid values (e.g., 'BUY_LIMIT' instead of 'BUY' + 'LIMIT') without formal constraints.
Descriptions in Chinese only. Tool descriptions and parameter names are in Chinese. While this may be intentional for a Chinese-language application, LLMs trained primarily on English will struggle to understand intent. Consider providing English descriptions alongside Chinese, or ensure the LLM has been fine-tuned for the target language.
Account ID required for most sensitive operations. Many tools require 'account_id' as a string parameter. The descriptions do not explain what format account_id takes (UUID, numeric, alphanumeric), whether it can be a username or friendly name, or how the LLM should discover valid account IDs. This forces extra discovery calls or relies on LLM knowledge of the system.
Mutually exclusive parameters not documented. Tools like cancel_order accept 'order_id' OR 'orig_client_order_id', but the description only states 'order_id 与 orig_client_order_id 二选一' (choose one of two) in the tool description, not in the parameter descriptions themselves. Similarly, create_spot_order accepts 'quantity' OR 'quote_order_qty' for market buys, but parameter descriptions lack this mutual exclusion guidance.
Rename tools for clarity. Split 'get_account_info' / 'get_account_v4' into a single 'get_futures_account_details' with clear field documentation. Use consistent naming for spot variants: 'get_futures_ticker' / 'get_spot_ticker' instead of 'get_ticker' / 'get_spot_ticker'.
Provide English descriptions alongside Chinese. Either translate descriptions to English or use bilingual format. LLMs rely on English training and will misunderstand or underuse tools with Chinese descriptions.
Document account_id format and discovery. Add a description: 'account_id is an identifier of your account (e.g., "trading-account-1"). If unsure, call list_accounts() [if such a tool exists] or provide the account name you configured during setup.' Consider adding a discovery tool (list_accounts, get_account_by_name) to avoid hardcoding IDs.
Add mutual exclusion warnings to parameter descriptions. Example for cancel_order's order_id field: 'Order ID as returned by get_order(). Mutually exclusive with orig_client_order_id, provide exactly one.' Same for create_spot_order's quantity vs quote_order_qty: 'For MARKET buy orders, use quote_order_qty (spend USD amount). For LIMIT or SELL orders, use quantity (asset amount). Mutually exclusive.'
Implement rate limiting and timeouts. Add descriptions: 'API calls are rate-limited to 1200 per minute. If you receive a 429 error, wait before retrying.' Ensure tools have explicit timeout behavior (e.g., 30 seconds) and return timeout errors with retry guidance.
Validate inputs early and return actionable errors. When the LLM passes 'side: "BUY_LIMIT"', reject with: 'Invalid side. Must be one of: BUY, SELL. (Combine side with order_type: side=BUY, order_type=LIMIT)' instead of a generic 500 error.
Add toolAnnotations for risk management. Mark destructive/write tools with destructiveHint=true and idempotent tools with idempotentHint=true. This lets the MCP client (and audit logging) flag dangerous operations and guide agent planning.
Implement output schema documentation as a comment or structured metadata. Pair each tool with an explicit response structure. Example: '# Response: {"symbol": string, "price": number, "bid": number, "ask": number, "timestamp": ISO 8601 string}' so LLMs can plan downstream tool calls.