基于模型上下文协议 (MCP),Futu 证券市场数据和交易接口服务器。它通过标准化的 MCP 协议提供 Futu OpenAPI 功能,支持市场数据订阅和查询等功能。
在使用此项目之前,请确保:
.env文件已被添加到.gitignore中该项目是一个开源工具,旨在简化Futu OpenAPI的集成过程。在使用此项目时请注意以下几点:
# 安装 pipx(如果还没有安装)
brew install pipx # macOS
# 或者 pip install --user pipx # 其他系统
# 安装包
pipx install futu-stock-mcp-server
# 运行服务器
futu-mcp-server
为什么使用pipx?
- pipx专门设计用于将Python应用程序安装到全局环境中
- 自动管理独立虚拟环境以避免依赖冲突
- 命令可以直接使用而无需激活虚拟环境
# 拉取镜像
docker pull your-registry/futu-stock-mcp-server:latest
# 运行容器
docker run -d \
--name futu-mcp-server \
-p 8000:8000 \
-e FUTU_HOST=127.0.0.1 \
-e FUTU_PORT=11111 \
your-registry/futu-stock-mcp-server:latest
git clone https://github.com/yourusername/futu-stock-mcp-server.git
cd futu-stock-mcp-server
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# 创建虚拟环境
uv venv
# 激活虚拟环境
# 在macOS/Linux上:
source .venv/bin/activate
# 在Windows上:
.venv\Scripts\activate
# 在可编辑模式下安装
uv pip install -e .
cp .env.example .env
编辑.env文件,设置您的服务器参数:
HOST=0.0.0.0
PORT=8000
FUTU_HOST=127.0.0.1
FUTU_PORT=11111
在pyproject.toml中添加新的依赖项:
[project]
dependencies = [
# ... 已有的依赖项 ...
"新包>=1.0.0",
]
然后更新您的环境:
uv pip install -e .
此项目使用Ruff进行代码检查和格式化。配置在pyproject.toml中:
[tool.ruff]
line-length = 100
target-version = "py38"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "B", "UP"]
运行检查:
uv pip install ruff
ruff check .
运行格式化:
ruff format .
找到配置文件位置:
~/Library/Application Support/Claude/claude_desktop_config.json添加服务器配置:
{
"mcpServers": {
"futu-stock": {
"command": "futu-mcp-server",
"env": {
"FUTU_HOST": "127.0.0.1",
"FUTU_PORT": "11111"
}
}
}
}
{
"mcpServers": {
"futu-stock": {
"command": "/Users/your-username/.local/bin/futu-mcp-server",
"env": {
"FUTU_HOST": "127.0.0.1",
"FUTU_PORT": "11111"
}
}
}
}
提示 使用
which futu-mcp-server命令查看完整路径
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
server_params = StdioServerParameters(
command="futu-mcp-server",
env={
"FUTU_HOST": "127.0.0.1",
"FUTU_PORT": "11111"
}
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# 初始化连接
await session.initialize()
# 列出可用工具
tools = await session.list_tools()
print("可用工具:", [tool.name for tool in tools.tools])
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "futu-mcp-server",
env: {
FUTU_HOST: "127.0.0.1",
FUTU_PORT: "11111"
}
});
const client = new Client({
name: "futu-stock-client",
version: "1.0.0"
}, {
capabilities: {}
});
await client.connect(transport);
# 通过pip安装后
futu-mcp-server
# 或从源码运行
python -m futu_stock_mcp_server.server
创建.env文件或设置环境变量:
FUTU_HOST=127.0.0.1
FUTU_PORT=11111
LOG_LEVEL=INFO
启动服务器后,您应该看到类似日志:
2024-10-02 14:20:52 | INFO | 正在初始化Futu连接...
2024-10-02 14:20:52 | INFO | Futu连接成功初始化
2024-10-02 14:20:52 | INFO | 正在以stdio模式启动MCP服务器...
2024-10-02 14:20:52 | INFO | 按Ctrl+C停止服务器
完成配置后,重新启动Claude Desktop或其他MCP客户端,您可以:
futu-mcp-server未找到# 确保已正确安装
pipx install futu-stock-mcp-server
# 检查命令是否可用
which futu-mcp-server
# 如果仍然找不到,请检查PATH
echo $PATH | grep -o '[^:]*\.local/bin[^:]*'
kill -9 <pid>强制终止# 检查OpenD是否运行
netstat -an | grep 11111
# 检查环境变量
echo $FUTU_HOST
echo $FUTU_PORT
# 确保具有执行权限
chmod +x ~/.local/bin/futu-mcp-server
# 或者使用完整路径
python -m futu_stock_mcp_server.server
该项目基于MCP官方文档的最佳实践是配置一个日志系统:
logs/futu_server.log自动轮转和清理# 启用调试模式(会向stderr输出日志)
export FUTU_DEBUG_MODE=1
futu-mcp-server
注意不要在MCP客户端中启用调试模式,因为它会向stderr输出日志。
./logs/futu_server.log有关详细日志配置说明,请参阅docs/LOGGING.md。
get_stock_quote:获取股票报价数据get_market_snapshot:获取市场快照get_cur_kline:获取当前K线数据get_history_kline:获取历史K线数据get_rt_data:获取实时数据get_ticker:获取逐笔成交数据get_order_book:获取订单簿数据get_broker_queue:获取经纪队列数据subscribe:订阅实时数据unsubscribe:取消订阅实时数据get_option_chain:获取期权链数据get_option_expiration_date:获取期权到期日期get_option_condor:获取期权鹰式策略数据get_option_butterfly:获取期权蝶式策略数据get_account_list:获取账户列表get_asset_info:获取资产信息get_asset_allocation:获取资产分配信息get_market_state:获取市场状态get_security_info:获取证券信息get_security_list:获取证券列表根据各种条件筛选股票。
参数:
base_filters(可选):基本股票筛选器列表
{
"field_name": int, # 股票字段枚举值
"filter_min": float, # 可选最小值
"filter_max": float, # 可选最大值
"is_no_filter": bool, # 可选,是否跳过筛选
"sort_dir": int # 可选,排序方向
}
- `accumulate_filters`(可选):累积筛选器列表
```python
{
"field_name": int, # 累积字段枚举值
"filter_min": float,
"filter_max": float,
"is_no_filter": bool,
"sort_dir": int,
"days": int # 必需,累积天数
}
```
- `financial_filters`(可选):财务筛选器列表
```python
{
"field_name": int, # 财务字段枚举值
"filter_min": float,
金融市场代码:
- `HK.Motherboard`:香港主板
- `HK.GEM`:香港GEM
- `HK.BK1911`:H股主板
- `HK.BK1912`:H股GEM
- `US.NYSE`:纽约证券交易所
- `US.AMEX`:美国证券交易所
- `US.NASDAQ`:纳斯达克
- `SH.3000000`:上海主板
- `SZ.3000001`:深圳主板
- `SZ.3000004`:深圳创业板
示例:
```python
# 获取价格在10至50港元之间的香港主板股票
filters = {
"base_filters": [{
"field_name": 5, # 当前价格
"filter_min": 10.0,
"filter_max": 50.0
}],
"market": "HK.Motherboard"
}
result = await client.get_stock_filter(**filters)
```
注意事项:
- 每30秒最多请求10次
- 每页返回最多200条结果。
- 建议不超过250个筛选条件。
- 每种类型的累计条件最多10个
- 动态数据排序(如当前价格)可能在不同页面之间有所不同。
- 不能比较不同类型指标(例如,MA5与EMA10)
## 资源
### 市场数据
- `market://{symbol}`:获取某个符号的市场数据
- `kline://{symbol}/{ktype}`:获取某个符号的K线数据
## 提示
### 分析
- `market_analysis`:创建市场分析提示
- `option_strategy`:创建期权策略分析提示
## 错误处理
服务器遵循MCP 2.0错误响应格式:
```json
{
"jsonrpc": "2.0",
"id": "request_id",
"error": {
"code": -32000,
"message": "错误消息",
"data": null
}
}
```
## 安全
- 服务器使用安全的WebSocket连接。
- 所有API调用均通过Futu OpenAPI进行身份验证
- 使用环境变量进行敏感配置。
## 开发
### 添加新工具
要添加新工具,请使用`@mcp.tool()`装饰器:
```python
@mcp.tool()
async def 新工具(param1: str, param2: int) -> Dict[str, Any]:
"""工具描述"""
# 实现
return 结果
```
### 添加新资源
要添加新资源,请使用`@mcp.resource()`装饰器:
```python
@mcp.resource("resource://{param1}/{param2}")
async def 新资源(param1: str, param2: str) -> Dict[str, Any]:
"""资源描述"""
# 实现
return 结果
```
### 添加新提示
要添加新提示,请使用`@mcp.prompt()`装饰器:
```python
@mcp.prompt()
async def 新提示(param1: str) -> str:
"""提示描述"""
return f"提示模板与{param1}"
```
## 许可证
MIT许可证
## 可用的MCP函数
### 市场数据函数
####