加密货币市场数据API服务

一个基于FastAPI和CCXT的统一加密货币市场数据API服务,提供REST和WebSocket接口,支持多种交易所数据获取、缓存和限流功能。

  • by raai2005
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 raai2005/crypto-mcp-server

使用说明

加密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" } }

常用代码:

  • 4001 BadRequestError(业务逻辑级别的验证)
  • 4220 请求验证错误(FastAPI/Pydantic)
  • 4290 RateLimitError(每个汇率限制器)
  • 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 是一个逗号分隔的字符串,它会自动解析为列表。