使用说明
加密MCP服务器(FastAPI+CXT)
该服务使用FastAPI、ccxt(异步)和可选的Redis缓存为加密市场数据提供统一的REST和WebSocket API。它提供了严格的请求/响应模式、标准化的错误处理、简单的速率限制和可配置的CORS。
亮点
- FastAPI应用程序下有版本路线
/v1/* - 用于自动收报机、OHLCV和订单簿的异步CCXT客户端
- 可选Redis缓存+内存TTL缓存,单次飞行合并
- 标准错误模式
{error: {code, message}} - 配置驱动的CORS和超时
- 按汇率限制
- 用于自动收报机的WebSocket流媒体
- 覆盖测试
项目结构
app/main.py:应用入口点、中间件、启动/关闭、路由器注册app/api/endpoints.py:REST和WebSocket端点app/models/schemas.py:Pydantic v2请求/响应模型和枚举app/services/ccxt_client.py:异步CCXT包装器+规范化+错误映射app/services/cache_manager.py:内存TTL缓存、Redis缓存、单次飞行app/services/redis_client.py:安全Redis初始化/关闭/获取app/services/error_handler.py:类型化服务错误+FastAPI处理程序app/services/rate_limiter.py:每个按键限制器的固定窗口requirements.txt:Python依赖关系tests/:API、服务、错误映射和缓存测试
需求
- Python 3.11+(在3.13上测试)
- Windows PowerShell(下面的命令)或您选择的shell
- 可选:Redis(本地/Docker/Memurai/WSL)用于外部缓存
安装程序(Windows PowerShell)
# From the repo root
python -m venv .venv
& ".venv\Scripts\Activate.ps1"
python -m pip install --upgrade pip
pip install -r requirements.txt
环境配置
创建一个 .env repo根目录下的文件(显示的值是示例)。所有这些都是可选的;在开发中应用了合理的默认值。
# Environment
ENV=development
# CORS: comma-separated list or `*` in development
CORS_ALLOW_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
# Redis (optional). If not reachable, the app falls back to in-memory cache
REDIS_URL=redis://localhost:6379/0
# Default exchanges list (comma-separated)
DEFAULT_EXCHANGES=binance,kraken,coinbase
# Request timeout for upstream ccxt calls (seconds)
REQUEST_TIMEOUT_SECONDS=15
# Per-exchange rate limit (max requests/sec)
MAX_REQUESTS_PER_EXCHANGE_PER_SEC=5
# Cache TTLs (seconds)
PRICE_CACHE_TTL_SECONDS=2
OHLCV_CACHE_TTL_SECONDS=10
ORDERBOOK_CACHE_TTL_SECONDS=2
运行服务器
& "$PWD\.venv\Scripts\python.exe" -m uvicorn app.main:app --reload
- 健康:
http://127.0.0.1:8000/health→{ "status": "ok" } - 文档(Swagger用户界面):
http://127.0.0.1:8000/docs
如果Redis没有运行,您可能会在日志中看到连接警告;该应用程序仍然使用内存缓存运行。
可选:启动Redis
- Docker桌面:
docker run --name redis -p 6379:6379 -d redis:7-alpine
- 原生Windows替代方案:Memurai(兼容Redis);或者在WSL中运行Redis。
API概述
-
GET /health- 退货
{status: "ok"}
- 退货
-
GET /v1/ticker- 查询:
exchange,symbol(例如。,BTC/USDT) - 答复:
{ exchange, symbol, base, quote, price, timestamp }
- 查询:
-
GET /v1/price(别名/v1/ticker) -
GET /v1/ohlcv- 查询:
exchange,symbol,timeframe,limit timeframe示例:1m,5m,15m,1h,4h,1d(以交易所支持为准)- 答复:
{ exchange, symbol, timeframe, candles: [{ t, o, h, l, c, v }], count }
- 查询:
-
GET /v1/orderbook- 查询:
exchange,symbol,depth(例如,10、50) - 答复:
{ exchange, symbol, timestamp, bids: [[price, size]...], asks: [[price, size]...] }
- 查询:
-
GET /v1/health(如果包含在路由器中) -
WS /ws/ticker- 查询:
exchange,symbol,interval_ms(例如,1000) - 定期发送股票快照+心跳
- 查询:
示例请求
# Ticker
curl "http://127.0.0.1:8000/v1/ticker?exchange=binance&symbol=BTC/USDT"
# OHLCV
curl "http://127.0.0.1:8000/v1/ohlcv?exchange=binance&symbol=BTC/USDT&timeframe=1m&limit=100"
# Orderbook
curl "http://127.0.0.1:8000/v1/orderbook?exchange=binance&symbol=BTC/USDT&depth=20"
错误 所有非2xx响应都使用一致的模式:
{ "error": { "code": 4290, "message": "rate limit exceeded" } }
常用代码:
4001BadRequestError(业务逻辑级别的验证)4220请求验证错误(FastAPI/Pydantic)4290RateLimitError(每个汇率限制器)5020上游错误(交换/ccxt/网络问题)5000内部错误(意外)
缓存
- 用于快速路径的内存TTL
- 可选的Redis缓存,用于跨进程持久化
- 单次飞行合并,避免因缓存丢失而造成踩踏
速率限制
- 每个汇率限制器的简单固定窗口(1秒窗口)
- 可通过以下方式配置
MAX_REQUESTS_PER_EXCHANGE_PER_SEC
测试
# Full test suite with coverage
$py = "$PWD/.venv/Scripts/python.exe"; & $py -m pytest -q --maxfail=1 --disable-warnings --cov=app --cov-report=term-missing
# Run only API tests
$py = "$PWD/.venv/Scripts/python.exe"; & $py -m pytest tests/test_api.py -q
可选的pytest-asyncio配置,以避免未来的弃用警告(创建 pytest.ini):
[pytest]
asyncio_default_fixture_loop_scope = function
假设
- 符号使用ccxt格式
BASE/QUOTE(例如。,BTC/USDT) - 目标交易所必须支持时间表
- 实时数据需要网络访问
- Redis是可选的;当不可用时,使用内存缓存
- CORS在生产中具有限制性;仅在需要时扩大
备注
- WebSocket流是基于轮询的可移植性;将来可以与交易所特定的流交换
- 错误信息在生产中是安全的;详细的跟踪仅在开发中记录
模块化加密MCP服务器(FastAPI层)
此目录包含一个基于FastAPI的模块化架构,可以与MCP(模型上下文协议)工具层集成。它专注于关注点的干净分离:配置、API路由、数据提供程序客户端、缓存、错误处理和异步执行。
结构
mcp_server/
app/
main.py # FastAPI app entrypoint
config.py # Settings management (env, defaults)
api/endpoints.py # HTTP routes exposing services
services/ccxt_client.py# CCXT async wrapper (multi-exchange)
services/cmc_client.py # CoinMarketCap client
services/cache_manager.py # Simple async TTL cache
services/error_handler.py # Custom exception + handler
models/schemas.py # Pydantic models
tests/
test_endpoints.py # Route tests
test_services.py # Cache/service tests
requirements.txt
README.md
.gitignore
FastAPI运行
安装依赖项(首选虚拟环境):
pip install -r mcp_server/requirements.txt
uvicorn mcp_server.app.main:app --reload
关键组件
- 配置:通过Pydantic进行集中设置
BaseSettings. - 服务:可重用逻辑(交换交互、列表检索、转换)。
- 缓存:用于价格和OHLCV响应的轻量级异步TTL缓存。
- 错误处理:具有自定义异常类的统一JSON错误格式。
- 模型:使用Pydantic的强类型请求/响应模式。
- 异步执行:所有外部I/O(CCXT、HTTP调用)都是异步完成的。
扩展到MCP
您可以通过将服务层导入到现有的MCP工具中来公开这些服务功能 FastMCP stdio服务器(例如,包装 get_price, get_ohlcv, listings, convert).这使协议逻辑与数据访问分开。
端点示例
GET /health–服务健康GET /price/{exchange}/{symbol}?currency=USD–实时价格GET /ohlcv/{exchange}/{symbol}?timeframe=1h&limit=100–历史蜡烛GET /listings?limit=25–顶级市场列表(CoinMarketCap)GET /convert?amount=1&from_symbol=BTC&to_symbol=ETH–跨货币转换
测试
pytest mcp_server/tests -q
备注
- CoinMarketCap端点需要
CMC_API_KEY在环境方面。 - CCXT交换符号必须与交换格式相匹配(例如。,
BTC/USDT). - 基本缓存清除是幼稚的(最旧的条目);必要时更换LRU。
配置和环境
设置在中定义 mcp_server/app/config.py 使用 pydantic-settings。它们从以下位置自动加载 .env 加上操作系统环境变量。
支持的环境变量:
| 变量 | 描述 | 默认值 |
|---|---|---|
CMC_API_KEY |
CoinMarketCap API密钥(需要登录/转换) | None |
REDIS_URL |
可选持久缓存的Redis连接URI | None |
DEFAULT_EXCHANGES |
以逗号分隔的要预加载的默认交换列表 | binance |
BASE_CURRENCY |
转换/价格的默认法定货币/报价货币 | USD |
PRICE_CACHE_TTL_SECONDS |
价格缓存条目的TTL | 30 |
OHLCV_CACHE_TTL_SECONDS |
OHLCV蜡烛缓存的TTL | 3600 |
MARKET_CACHE_TTL_SECONDS |
TTL用于市场/列表缓存 | 300 |
REQUEST_TIMEOUT_SECONDS |
出站HTTP调用超时 | 30 |
访问设置
您可以直接导入全局设置实例:
from app.config import settings
print(settings.default_exchanges)
或者获取一个新的(缓存的)实例:
from mcp_server.app.config import get_settings
cfg = get_settings()
示例 .env
CMC_API_KEY=your_key_here
REDIS_URL=redis://localhost:6379/0
DEFAULT_EXCHANGES=binance,kraken,coinbase
BASE_CURRENCY=USD
PRICE_CACHE_TTL_SECONDS=45
OHLCV_CACHE_TTL_SECONDS=1800
MARKET_CACHE_TTL_SECONDS=300
REQUEST_TIMEOUT_SECONDS=25
如果 DEFAULT_EXCHANGES 是一个逗号分隔的字符串,它会自动解析为列表。