MCP Server that exposes AKShare financial data functions as tools
This server exposes 5 financial data tools from the AKShare library. All tools are READ_ONLY wrappers around external library functions that return pandas DataFrames formatted as markdown/csv/json. Critical deficiencies: (1) NO input schemas are visible in the source code, tools are registered via @mcp.tool() decorator on wrapped functions with no explicit parameter validation or schema definition; (2) Descriptions are extremely generic (all follow the pattern 'From akshare.X - returns DataFrame formatted as markdown, csv, or json'), under 100 characters, providing no actionable guidance on when/why to use each tool or what data they return; (3) Parameter documentation is completely absent, the underlying akshare functions likely have parameters (filters, date ranges, etc.) but none are described in the tool registration; (4) Output schemas are undocumented, LLMs cannot predict what fields a stock index query returns; (5) No error handling, validation, or recovery guidance; (6) Tool names do not follow verb_noun convention (should be get_stock_zh_index_spot, list_global_indices, etc.). The server is essentially a thin passthrough with minimal MCP-level metadata.
From akshare.index_global_spot_em - returns DataFrame formatted as markdown, csv, or json
From akshare.stock_yjbb_em - returns DataFrame formatted as markdown, csv, or json
From akshare.stock_zh_a_spot_em - returns DataFrame formatted as markdown, csv, or json
From akshare.stock_zh_index_spot_em - returns DataFrame formatted as markdown, csv, or json
From akshare.stock_zt_pool_em - returns DataFrame formatted as markdown, csv, or json
NO input schemas defined for any tool. All 5 tools registered with @mcp.tool() decorator on bare akshare library functions with no schema, parameter descriptions, or validation. Per hard scoring rule: schema score MUST be 0 for tools without visible input schema.
Descriptions are generic boilerplate (15-20 chars each): 'From akshare.stock_zh_index_spot_em - returns DataFrame formatted as markdown, csv, or json'. They provide zero actionable guidance on WHAT data the tool returns, WHEN to use it, or WHAT fields are in the response. Per hard scoring rule: description score CANNOT exceed 20 when under 20 chars.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 26 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 25 | - | v1 |
Tool names do not follow verb_noun convention. Should start with action verbs (get_, list_, fetch_). 'stock_zh_index_spot_em' is a noun-only name that does not convey the action, LLM cannot infer intent from name alone. Baseline: 90% of A+ tools start with action verb.
No output schemas documented. LLMs cannot predict what fields stock_zh_index_spot_em returns (symbol? price? volume? timestamp?). Without documented output schemas, agents cannot plan downstream tool calls or extract required fields. Baseline: 100% of A+ tools have documented return types.
Underlying akshare functions almost certainly accept parameters (date filters, limits, symbol filters) but none are exposed or documented in the MCP tool definitions. register() function wraps functions but does not inspect or expose their parameter signatures. Tool definitions appear parameter-less, which is almost certainly incorrect.
No error handling or recovery guidance. If an akshare call fails (network timeout, invalid data, rate limit), wrapped output_format() function will crash with an unhandled exception. No try-catch, no actionable error messages guiding LLM to retry or use alternative tool.
Output format (markdown/csv/json) is a global server setting, not a per-tool or per-call parameter. All tools produce the same format. If LLM needs markdown for readability and JSON for parsing in different contexts, it cannot choose, the global setting forces one format for all calls.