Mrigank923/mcp_server
If you are the rightful owner of mcp_server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The MCP Server is a FastAPI-based microservice designed to provide market data endpoints with a pluggable backend and caching capabilities.
MCP Server
A compact FastAPI microservice that exposes market data endpoints (ticker, OHLCV, orderbook, trades) backed by a pluggable MarketService and an async Redis cache.
It uses a pluggable MarketService backend (ccxt adapter is included), and an async Redis cache for short-term caching.
This README documents project structure, how to set up and run locally, configuration env vars, API details, schema types, testing, known compatibility notes, and assumptions made during development.
Goals & approach
- Provide a thin HTTP API on top of a market data service (
MarketService) so clients can request ticker, OHLCV, order book and recent trades. - Keep the HTTP layer minimal: endpoints are GET-only and forward requests to the service layer, returning 502 on service errors.
- Use an async Redis client (
redis.asyncio) to cache responses and share state across workers/processes. - Use
ccxtas the adapter to fetch market data from exchanges; the adapter is wrapped inapp/adapters/ccxt_adapter.pyand used byapp/services/market_service.py.
Quick summary
- Base URL (dev): http://localhost:8000
- API prefix:
/api/v1 - Key features:
- FastAPI endpoints that call an async
MarketService(ccxt adapter) - Async Redis caching (
redis.asyncio) inapp/cache/redis_cache.py - Pydantic schemas in
app/schemas.pyused for validation and docs
- FastAPI endpoints that call an async
Repository layout
mcp_server/
├─ app/
│ ├─ api/v1/endpoints.py # FastAPI routes (mounted at /api/v1)
│ ├─ cache/redis_cache.py # async redis helper (init/get/set/close)
│ ├─ services/market_service.py # business logic, caching orchestration
│ ├─ adapters/ccxt_adapter.py # ccxt wrapper to fetch exchange data
│ ├─ config.py # pydantic settings and env defaults
│ ├─ schemas.py # Pydantic response/request schemas
│ └─ main.py # FastAPI app, startup/shutdown hooks
├─ requirements.txt
├─ run_server.sh # convenience script to start uvicorn
├─ Dockerfile
├─ docker-compose.yml
└─ tests/unit/ # unit tests
API endpoints
All endpoints are GET and mounted at /api/v1.
-
GET
/— Health check. Returns:{ "status": "ok" }. -
GET
/api/v1/ticker- Query params:
symbol(required, e.g.BTC/USDT),exchange(optional, e.g.binance) - Returns ticker object for the symbol (see
app/schemas.py->TickerModel).
- Query params:
-
GET
/api/v1/ohlcv- Query params:
symbol(required),exchange(optional),timeframe(default1m),since(optional, ms epoch),limit(default 100) - Returns OHLCV list (see
OHLCVModel).
- Query params:
-
GET
/api/v1/orderbook- Query params:
symbol(required),exchange(optional),limit(default 50) - Returns order book (see
OrderBookModel).
- Query params:
-
GET
/api/v1/trades- Query params:
symbol(required),exchange(optional),limit(default 50) - Returns recent trades (see
TradeModel/TradesModel).
- Query params:
Example curl (ticker):
curl 'http://localhost:8000/api/v1/ticker?symbol=BTC%2FUSDT&exchange=binance'
Error behavior
- If the service layer raises an exception, endpoints return HTTP 502 with the exception message in
detail. - The API is synchronous from the client's point-of-view but implemented with async handlers.
Schemas
Pydantic models are declared in app/schemas.py. Key models include:
TickerModel— fields like symbol, timestamp, last, bid, ask, baseVolume, etc.OHLCVModel— list of OHLCV arrays:[timestamp, open, high, low, close, volume].OrderBookModel—bids,asks, timestamp.TradeModel/TradesModel— individual trades and lists.
These schemas are used to standardize API outputs and appear in OpenAPI docs available at /docs when the app runs.
Configuration (env vars)
Configuration lives in app/config.py (Pydantic Settings). Important env vars and defaults:
REDIS_HOST(default:localhost)REDIS_PORT(default:6379)REDIS_DB(default:0)REDIS_URL(default:redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB})DEFAULT_EXCHANGE(default:binance) — used when theexchangequery param is omitted.
Set them in your shell or in your container orchestration before running the server.
Requirements and compatibility
Project dependencies are in requirements.txt. Key ones:
- fastapi
- uvicorn[standard]
- ccxt
- redis (redis-py) — used via
redis.asyncio - aioredis (historical; the code uses
redis.asyncio) - tenacity
- httpx
- pytest, pytest-asyncio (tests)
Compatibility note (important):
- Tests in this repo use
httpx.AsyncClient(app=app, ...)which relies on older httpx API behavior. Newer httpx releases (0.28+) removed theapp=kwarg. If you run tests and see failures like:TypeError: AsyncClient.__init__() got an unexpected keyword argument 'app'then either pinhttpxto an older version (for examplehttpx==0.23.3) or update tests to use a modern ASGI testing approach.
Recommended quick install (project venv called menv in this repo):
# from repo root
python -m venv menv
source menv/bin/activate
python -m pip install -r requirements.txt
If you prefer to pin httpx to a compatible version, add httpx==0.23.3 to requirements.txt and reinstall.
Run locally (development)
- Start Redis (local) if you don't have one already:
docker run -p 6379:6379 -d --name redis redis:7
- Start the app using the convenience script or uvicorn:
./run_server.sh
# or
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Open http://localhost:8000/docs for the interactive OpenAPI UI.
Tests
Run unit tests from project root so app is importable:
# ensure venv is activated and deps installed
python -m pytest -q tests/unit
If you hit the AsyncClient(..., app=app) TypeError, either pin httpx to a compatible version as noted above or update tests to use an ASGI transport / Lifespan manager.
Docker
This repo contains a Dockerfile and docker-compose.yml. Typical local compose usage:
docker-compose up --build
Ensure the compose file wires a Redis service and sets any required env vars (or use external Redis and set REDIS_URL).
Troubleshooting
- ModuleNotFoundError: No module named 'redis' — install requirements in the same Python environment used to run uvicorn.
- Pydantic model errors — ensure attributes in
app/config.pyare properly typed (non-field attributes should be annotated withClassVar). - IndentationError / SyntaxError — run
python -m py_compile <file>to find the syntax issue. - Httpx AsyncClient TypeError — see compatibility note above.
Assumptions and design notes
MarketServicemethods are async and return exchange-normalized data. The service orchestrates fetching data from theCCXTAdapter, caching in Redis, and returning structured responses.- Redis is used for short-term caching of responses (JSON serialized) to reduce external exchange calls.
- OpenAPI schemas are provided via
app/schemas.pyto document response shapes. - The project is primarily a developer-facing service; production hardening (authentication, rate limiting, connection pooling, monitoring) is out-of-scope for this repository.
Where to look next
app/services/market_service.py— caching and orchestration logic.app/adapters/ccxt_adapter.py— exchange-layer implementation.app/cache/redis_cache.py— Redis client helpers (init/get/set/close).tests/unit/— examples of how the endpoints and adapters are exercised in tests.