ashare-mcp
ashare-mcp
Turn Chinese A-share (沪深京) financial statements into tools your LLM can call. 把 A 股财报变成 LLM 可调的工具 —— 一句"平安银行 2024 年报怎么样?"直接拿到结构化三大表。
让 Claude(或任何 MCP 客户端)用一句"平安银行 2024 年报怎么样?"直接拿到结构化的资产负债表 / 利润表 / 现金流量表,字段经过精选、单位明确、缓存友好。
数据来源东方财富,通过 akshare,全部免费、无需 token。
为什么再做一个
GitHub 上"金融 LLM"项目大多卷在 trading agent 和 SEC 10-K RAG——前者同质化严重,后者只服务美股。A 股 + 中文 + MCP 协议层 的组合几乎空白。
ashare-mcp 的定位很窄:做 A 股财报这一件事,做到能被任何 LLM 客户端十秒接入。它不预测股价、不写研报、不替你做决策——它只把数据从东方财富搬到 LLM 的工具调用里,字段干净、单位清楚、错误明确。
Related MCP server: sfc-data-mcp
快速开始
git clone https://github.com/yli769227-jpg/ashare-mcp.git
cd ashare-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -e .跑一次冒烟测试:
python -c "from ashare_mcp.data_source import get_annual_statements; \
r = get_annual_statements('SZ000001', 2024); \
print(r['company_name'], r['balance_sheet']['TOTAL_ASSETS'])"
# -> 平安银行 5769270000000.0接入 Claude Desktop
编辑 ~/Library/Application Support/Claude/claude_desktop_config.json(Mac):
{
"mcpServers": {
"ashare": {
"command": "/absolute/path/to/ashare-mcp/.venv/bin/python",
"args": ["-m", "ashare_mcp.server"]
}
}
}重启 Claude Desktop,就能直接问:
帮我看一下平安银行 2024 年报,总资产、总负债、净利润、经营性现金流分别多少?
工具列表
工具 | 输入 | 输出 |
|
| 年报三大表(精选 ~150 字段) |
|
| 4 条勾稽校验(3 条通用 + 1 条行业感知)+ 误差 |
|
| 同业 N 家横向对比 + 排名 / max-min-avg-std + ROE |
|
| 跨年时间序列 + YoY / CAGR / trend / anomalies |
|
| PDF / DOCX / PPTX / 图片 → LLM-ready markdown(MinerU) |
代码归一化支持 000001 / SZ000001 / sz.000001 / 000001.SZ 多种格式。
cross_check_balance 当前包含 4 条勾稽(前 3 条行业通用,第 4 条行业感知):
资产负债平衡 —
TOTAL_ASSETS = TOTAL_LIABILITIES + TOTAL_EQUITY现金流恒等式 —
NETCASH_OPERATE + NETCASH_INVEST + NETCASH_FINANCE + RATE_CHANGE_EFFECT = CCE_ADD期末/期初现金对账 —
END_CCE − BEGIN_CCE = CCE_ADD营业利润分解(行业感知)
银行:
OPERATE_PROFIT = OPERATE_INCOME − OPERATE_EXPENSE工商企业:
OPERATE_PROFIT = TOTAL_OPERATE_INCOME − TOTAL_OPERATE_COST + OTHER_INCOME + INVEST_INCOME + FAIRVALUE_CHANGE_INCOME + ASSET_IMPAIRMENT_INCOME + CREDIT_IMPAIRMENT_INCOME + ASSET_DISPOSAL_INCOME [+ EXCHANGE_INCOME]行业自动识别:有
ACCEPT_DEPOSIT > 10 亿走银行公式,有TOTAL_OPERATE_INCOME+TOTAL_OPERATE_COST走工商公式,否则skipped(保险等暂不支持)
容忍度:前 3 条 1 万元(单项舍入),第 4 条 1000 万元(多项加总舍入累积)。字段缺失或行业无法识别时该条 skipped,不影响其它校验。实测 3 行业(银行 / 白酒 / 电池)4 家公司 2024 年报全过 4/4。
走 lru cache 联动:先调 get_three_statements 后调 cross_check_balance,后者 < 1ms 秒回(同一只股票数据已在内存)。
compare_peers 默认 metrics:TOTAL_ASSETS / TOTAL_OPERATE_INCOME / PARENT_NETPROFIT / NETCASH_OPERATE / TOTAL_EQUITY,自动派生 ROE = PARENT_NETPROFIT / 平均权益(本年期末权益 + 去年期末权益的均值,去年数据走 lru cache 几乎无成本;去年数据缺失时降级为期末权益,在 roe_method 字段标 ending_equity_fallback)。自动 fallback:银行业 TOTAL_OPERATE_INCOME 缺失时退到 OPERATE_INCOME 并在 fallbacks 字段标注。并发实现:ThreadPoolExecutor(max_workers=8),N 家公司并行拉(单家失败不挂整体,记入 errors)。实测 4 大银行 2024 年报对比 ~38s 跑完;招行 ROE 12.85%(零售之王长期领跑)。
HTTP API 模式
除了 MCP stdio 协议,项目还提供一个 FastAPI HTTP wrapper,供 Web 前端、curl、Postman 等任意 HTTP 客户端调用——这是给 Web demo 用的:
pip install -e .
ashare-mcp-http
# Uvicorn running on http://0.0.0.0:80005 个 endpoint(完整 schema 见 /docs FastAPI 自动生成的 OpenAPI 页面):
方法 | 路径 | 对应 MCP tool |
|
| (健康检查 + 版本号) |
|
|
|
|
|
|
|
|
|
|
|
|
错误统一格式:{"error": "...", "code": "INVALID_INPUT" | "UPSTREAM_ERROR"}(HTTP 422 / 502)。CORS 默认 *,生产部署前应收紧到具体域名。/api/compare-peers 单次最多 20 个代码(防请求放大);公开部署建议在反向代理层(Nginx / Cloudflare 等)再加限流。
冒烟测试:
curl 'http://localhost:8000/api/statements?stock_code=000001&year=2024' | jq '.company_name, .balance_sheet.TOTAL_ASSETS'
# "平安银行"
# 5769270000000Web 前端 demo
web/ 子目录是一个 React + Vite + TypeScript + Tailwind 写的 4-tab 前端,直接调上面的 HTTP API,给非技术用户也能用浏览器试一下:
cd web
npm install
cp .env.example .env.local # 默认 VITE_API_BASE=http://localhost:8000
npm run dev # 开发预览 → http://localhost:5173
npm run build # 生产构建到 dist/4 个 tab 对应 4 个核心工具:三大报表 / 勾稽校验 / 同业对比 / 历史趋势。需要后端 ashare-mcp-http 同时跑在 :8000。详见 web/README.md。
PDF 文档解析(可选)
parse_document 工具用 opendatalab/MinerU 把 PDF / DOCX / PPTX / 图片(招股书、研报、年报扫描件等)解析成 LLM-ready 的 markdown。由于 MinerU pipeline 后端需要 torch + transformers 等几 GB 依赖,单独走 extra 安装:
pip install -e ".[pdf]" # 装 mineru
# 若要解析 PDF / 图片,还需 pipeline extras:
pip install "mineru[pipeline]"不装也不影响其它 4 个工具——只是调用 parse_document 时会以 RuntimeError("mineru not installed") 友好失败。
架构
flowchart LR
LLM[Claude / 任意 MCP 客户端] -->|JSON-RPC over stdio| Server[ashare-mcp<br/>FastMCP server]
Web[Web 前端<br/>React + Vite] -->|HTTP / JSON| HTTP[ashare-mcp-http<br/>FastAPI wrapper]
Curl[curl / Postman / 其它] -->|HTTP / JSON| HTTP
Server -->|共享业务层| Core[业务模块<br/>checks / peer_compare / history]
HTTP -->|共享业务层| Core
Core -->|代码归一化| Norm[股票代码归一化<br/>SZ/SH/BJ 自动判断]
Core -->|拉取三表| DS[数据源封装<br/>akshare 包装层]
DS -->|缓存命中| Cache[(进程内存缓存<br/>lru_cache)]
DS -->|缓存未命中| YearlyEM[akshare<br/>by_yearly_em]
YearlyEM -->|HTTP| EM[东方财富<br/>财报数据接口]
DS -->|字段过滤| Filter[剔除元数据列<br/>剔除同比列<br/>剔除空/零字段]关键设计:
字段名保留东方财富原始英文(
TOTAL_ASSETS/LOAN_ADVANCE/NETPROFIT)。LLM 直接能理解,且银行 / 工商企业 / 保险等不同行业字段都在同一份字典里,无需做行业判断。进程内存缓存让"同一公司多年份对比"几乎零成本——冷启动一次拉全量,后续年份切换 < 1ms。
日志走 stderr,不污染 MCP stdio 协议通道。
部署
仓库已内置三份部署配置,前后端分开部署:
文件 | 平台 | 部署对象 | 关键配置 |
| 后端 | Nixpacks 构建(Python 3.11),启动 | |
| 前端 | 构建 |
后端(Railway):连接仓库后 Railway 自动读 nixpacks.toml 构建(锁 Python 3.11,不装 [pdf] extra),$PORT 由平台注入(见 http_app.py)。健康检查打 /healthz。
前端(Vercel):框架识别为 Vite,构建 web/ 子目录输出到 web/dist。部署前在 Vercel 环境变量里设置 VITE_API_BASE 指向你的 Railway 后端地址。
公开部署提醒:
http_app.py的 CORS 默认*,生产应收紧到具体前端域名;/api/compare-peers单请求上限 20 个代码,建议反向代理层再加限流。
路线图
版本 | 工具 | 状态 |
v0 |
| ✅ |
v1 |
| ✅ |
v1 |
| ✅ |
v1.5 |
| ✅ |
v1.5 |
| ✅ |
v2 | 跨年趋势工具 | ✅ |
v2 |
| ✅ |
v2(当前) | FastAPI HTTP wrapper + Web 前端 demo + pytest + CI | ✅ |
v3 | 季度数据 + 同比/环比派生指标 | 待定 |
v3 | 公开 demo 站部署配置(Vercel 前端 + Railway 后端) | ✅( |
v3 | MCP 官方 registry 发布 | 待定 |
本地开发
# 装 dev 依赖(包含 pytest / httpx)
pip install -e ".[dev]"
# 跑测试套件(全部离线,akshare 走 mock,~1.5s)
pytest tests/ -v
# 增量验证(每次改完跑一遍)
python -c "from ashare_mcp.server import mcp; \
import asyncio; print([t.name for t in asyncio.run(mcp.list_tools())])"
# 起 HTTP server 本地预览
ashare-mcp-http
# 另一终端:
curl http://localhost:8000/healthzCI
.github/workflows/ci.yml 跑两个 job:
Backend matrix:Python 3.10 / 3.11 / 3.12 —
pip install -e ".[dev]"+pytest tests/ -v+ 验证 MCP & HTTP 入口都能 importFrontend(Node 20)—
cd web && npm ci+tsc --noEmit+npm run build
PDF 路径(parse_document)默认 skip(mineru 是 optional);要本地跑这部分:pip install -e ".[dev,pdf]" && pytest tests/test_parse_document.py -v。
数据声明
数据源:东方财富,通过 akshare。
数据延迟、口径、准确性以东方财富为准,不构成投资建议。
仅用于教育与研究目的。
License
MIT — see LICENSE.
Available Tools
3 toolscompare_peersA
同业 N 家公司同年年报横向对比,自动算排名 / 最大最小 / 均值 / 标准差,加派生指标 ROE。
参数: stock_codes: 公司代码列表,如 ['000001', '600036', '601398']。建议 2-10 家。 支持各种格式:'000001' / 'SZ000001' / 'sz.000001' / '000001.SZ'。 year: 年份。 metrics: 可选,自定义对比字段。默认包括: TOTAL_ASSETS / TOTAL_OPERATE_INCOME / PARENT_NETPROFIT / NETCASH_OPERATE / TOTAL_EQUITY。 派生指标 ROE = PARENT_NETPROFIT / TOTAL_EQUITY 总是会算上。 银行业 TOTAL_OPERATE_INCOME 缺失时自动 fallback 到 OPERATE_INCOME(在 fallbacks 字段里标注)。
返回: { "year": 2024, "report_date": "2024-12-31", "metrics": ["TOTAL_ASSETS", ..., "ROE"], "companies": [ { "stock_code": "SZ000001", "company_name": "平安银行", "values": {metric: number}, "ranks": {metric: rank}, # 1 = 最大 "fallbacks": {original_key: actual_key} | null } ], "summary": { metric: {"max", "min", "avg", "std", "count"} }, "errors": [ {"stock_code": "...", "error": "..."} # 单家失败不挂整体 ] }
并发实现: ThreadPoolExecutor(max_workers=8),N 家公司并行拉。 缓存联动: 已经查过的公司走 lru cache,< 1ms 复用。
| Name | Required | Description | Default |
|---|---|---|---|
| stock_codes | Yes | ||
| year | Yes | ||
| metrics | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses concurrency (ThreadPoolExecutor with 8 workers), caching (lru cache), single-failure tolerance, and fallback logic for bank metrics. Return structure is detailed with example JSON.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections for parameters, return fields, and implementation details. Every sentence adds value without redundancy. Length is appropriate for a complex tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, yet description provides complete return structure with example JSON, concurrency, caching, and error handling. Covers all behavioral aspects needed for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 0% coverage, but description fully explains stock_codes formats, year, metrics default and optional, and derived ROE. Provides examples and constraints, compensating completely for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it compares annual reports of N peer companies horizontally, computes ranks, min/max, mean, std, and derived ROE. It distinguishes from siblings like cross_check_balance and get_three_statements by specifying peer comparison logic.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly recommends 2-10 companies, describes default metrics, and explains derived ROE always included. It doesn't explicitly state when not to use or alternatives, but provides clear context for appropriate use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cross_check_balanceA
跑财务勾稽校验,检测三大表数据是否互相自洽。返回每条校验的 passed/failed/skipped 状态与误差。
参数: stock_code: A 股代码,支持多种格式(同 get_three_statements)。 year: 年份,如 2024。仅支持年报。
返回: { "stock_code": "SZ000001", "company_name": "平安银行", "report_date": "2024-12-31", "checks": [ { "name": "balance_sheet_equation", "label": "资产负债平衡", "formula": "TOTAL_ASSETS = TOTAL_LIABILITIES + TOTAL_EQUITY", "lhs_value": 5769270000000.0, "rhs_value": 5769270000000.0, "diff": 0.0, "tolerance": 10000.0, "status": "passed" }, ... ], "summary": {"total": 3, "passed": 3, "failed": 0, "skipped": 0} }
当前 v1 包含 3 条行业通用勾稽:
资产负债平衡: TOTAL_ASSETS = TOTAL_LIABILITIES + TOTAL_EQUITY
现金流恒等式: 三大现金流 + 汇率影响 = 现金净增加额
期末/期初现金对账: END_CCE - BEGIN_CCE = CCE_ADD
容忍度 1 万元(财报舍入)。字段缺失时该条 status='skipped',不影响其它校验。
| Name | Required | Description | Default |
|---|---|---|---|
| stock_code | Yes | ||
| year | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations given, but description fully covers behavior: checks three specific equations with tolerance, returns passed/failed/skipped status, handles missing fields gracefully, and notes annual-only support.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with intro, parameter details, return format example, and list of checks. Every sentence is informative and no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description provides full return example and explains all statuses and tolerance. Parameter semantics are fully covered, and sibling references add context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning beyond schema: explains stock_code format and links to sibling tool, clarifies year only supports annual reports, and includes example values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool performs financial cross-check validation among three statements, distinguishing it from siblings like get_three_statements and compare_peers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides parameter specifics (stock_code supports multiple formats, year only annual reports) and lists the three checks. Does not explicitly exclude use cases, but context suffices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_three_statementsA
拉取 A 股某只股票某年的年报三大财务报表(资产负债表 / 利润表 / 现金流量表)。
参数: stock_code: A 股代码,支持多种格式 —— '000001' / 'SZ000001' / 'sz.000001' / '000001.SZ'。 year: 年份(整数),如 2024。仅支持年报(报告期 12-31)。
返回: { "stock_code": "SZ000001", "company_name": "平安银行", "report_date": "2024-12-31", "currency": "CNY", "unit": "yuan (元)", "balance_sheet": {...}, # 字段如 TOTAL_ASSETS / LOAN_ADVANCE / ACCEPT_DEPOSIT "income_statement": {...}, # 字段如 OPERATE_INCOME / NETPROFIT / PARENT_NETPROFIT "cash_flow_statement": {...}, # 字段如 NETCASH_OPERATE / NETCASH_INVEST / NETCASH_FINANCE }
数据源: 东方财富(via akshare)。字段名为东方财富原始英文(SCREAMING_SNAKE_CASE)。 单位: 人民币元。 缓存: 进程内存缓存,同一只股票多次查询(不同年份)只走一次网络。
| Name | Required | Description | Default |
|---|---|---|---|
| stock_code | Yes | ||
| year | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full weight. It discloses caching behavior, data source, currency, unit, and field naming conventions, but does not mention authentication or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a brief intro, bullet points for parameters, and a clear return format, though it could be slightly more concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and lack of output schema, the description covers all relevant aspects: purpose, parameters, return structure, data source, caching, and units, making it fully informative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description adds crucial detail: multiple accepted formats for stock_code and the requirement that year be an integer for annual reports only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (拉取/fetch), resource (年报三大财务报表), and scope (A股某只股票某年), distinguishing it from sibling tools like compare_peers and cross_check_balance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description specifies that only annual reports are supported and provides parameter formats, but does not explicitly compare to sibling tools or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
compare_peers - First observed
cross_check_balance - First observed
get_three_statements
TDQS
Scored across 3 tools
Each tool has a clear, distinct purpose: retrieving financial statements, cross-checking consistency, and comparing peers. There is no overlap or ambiguity.
All tool names follow a consistent snake_case verb_noun pattern (compare_peers, cross_check_balance, get_three_statements), making them predictable and clear.
Three tools is minimal but sufficient for the focused domain of A-share annual financial analysis. The count feels well-scoped without being overly thin.
The tools cover core workflows: data retrieval, internal consistency checks, and peer comparison. Minor gaps like quarterly data or individual ratio lookups exist, but the surface is largely complete for annual report analysis.
Maintenance
Related MCP Connectors
MCP server giving AI agents one-connection access to China A-share market intelligence: financials,
China A-share market data for research, backtesting and AI agents via MCP.
A-share market data over MCP: quotes, K-line, financials, money flow, boards, sectors, macro.
Financial data and research MCP for US/CN/JP equities: filings, statements, ownership, signals.
Related MCP Servers
- AlicenseBqualityDmaintenanceMCP server that provides access to Chinese stock market data using akshare-one49341 PyPI226MIT
- FlicenseNot gradedqualityDmaintenanceMCP server that wraps SFC financial data API into 32 tools for comprehensive A-share market data, including real-time quotes, rankings, limit-up statistics, news, themes, financials, charts, research reports, and watchlists.-
- AlicenseAqualityCmaintenanceA-share market data MCP server via baostock. Full-stack coverage: K-line, financials, DCF/DDM/PEG valuation, 11 technical indicators with proper split-day volume handling (OBV/MFI on raw bars), CN-style KDJ (J=3K-2D), risk metrics (Beta/Sharpe/MaxDD with stock-suspension-aware aligned returns), and PBoC macro data.2511MIT
- AlicenseAqualityDmaintenanceMCP server to fetch Vietnamese corporate financial reports (balance sheet, income statement, cash flow) from cafef.vn using public API, no PDF or OCR needed.34 npm1MIT