uniswap_prices
# uniswap_prices
MCP server based on [FastMCP](https://github.com/modelcontextprotocol/python-sdk). Runs over
stdio by default, or as a local HTTP service (see [Running over HTTP (Docker)](#running-over-http-docker)).
Reads Uniswap V1/V2/V3 reserves directly on-chain via a public, unauthenticated Ethereum
RPC endpoint — no API key required.
## Scope
This server does exactly one thing: read Uniswap pool reserves straight from the chain.
- **Genuinely zero-auth.** No API key, no account, no sign-up — not even for the underlying
data source. Most "crypto price" MCP servers are thin wrappers around a paid/rate-limited
pricing API (CoinGecko, 1inch, etc.) that still needs a key. This one talks directly to a
public Ethereum RPC endpoint and reads the pool contracts' own storage — there's no
intermediary to authenticate to, and nothing to keep secret.
- **Uniswap only, on purpose.** It doesn't try to be a universal multi-DEX or multi-chain price
server. It knows Uniswap V1/V2/V3 and nothing else. If you need broader coverage, compose it
with other narrow, single-purpose MCP servers instead.
## Tools
- `get_v1_reserves(token)` — ETH/token reserves of a token's Uniswap V1 exchange
(V1 pairs are always ETH<->token).
- `get_v2_reserves(token_a, token_b)` — reserves of a Uniswap V2 pair via `getReserves()`.
- `get_v3_reserves(token_a, token_b, fee=None)` — on-chain reserves (pool token balances)
of Uniswap V3 pool(s); if `fee` is omitted, all standard fee tiers are checked.
`token`/`token_a`/`token_b` accept either a mainnet ERC20 contract address or a known
symbol (`ETH`, `WETH`, `USDC`, `USDT`, `DAI`, `WBTC`).
By default the server talks to `https://ethereum-rpc.publicnode.com`; override with the
`UNISWAP_PRICES_RPC_URL` env var.
## Setup
```bash
git clone <this-repo-url>
cd uniswap_prices
conda create -n uniswap_prices python=3.12 -y
conda activate uniswap_prices
pip install -e .
```
## Run
```bash
python -m uniswap_prices.server
```
or, if configured as an entry point in an MCP client:
```json
{
"command": "python",
"args": ["-m", "uniswap_prices.server"]
}
```
## Running over HTTP (Docker)
The server can also run as a local HTTP service (streamable-http transport) instead
of stdio — useful for MCP clients that connect over HTTP, or for running the server
as a standalone daemon.
Without Docker:
```bash
UNISWAP_PRICES_TRANSPORT=http UNISWAP_PRICES_HTTP_HOST=127.0.0.1 UNISWAP_PRICES_HTTP_PORT=8000 \
python -m uniswap_prices.server
```
The MCP endpoint is then available at `http://127.0.0.1:8000/mcp`.
With Docker:
```bash
docker compose up --build
# or, to bind a different host port (e.g. if 8000 is already taken):
UNISWAP_PRICES_HOST_PORT=8001 docker compose up --build
```
or plain Docker, picking any free host port yourself:
```bash
docker build -t uniswap_prices .
docker run -p 8000:8000 uniswap_prices
```
Env vars (all optional):
- `UNISWAP_PRICES_TRANSPORT` — `stdio` (default) or `http`.
- `UNISWAP_PRICES_HTTP_HOST` — bind host for HTTP mode (default `127.0.0.1`;
the Docker image sets this to `0.0.0.0`).
- `UNISWAP_PRICES_HTTP_PORT` — bind port for HTTP mode (default `8000`).
- `UNISWAP_PRICES_RPC_URL` — override the Ethereum RPC endpoint.
## Development
- Tools are defined in `src/uniswap_prices/tools/`.
- Each tool's logic is kept separate from the `@mcp.tool()` decorator so it can be unit tested.
- Do not use `print()` for debugging: it breaks the stdio protocol. Use `logging` or `sys.stderr` instead.
## Tests
```bash
pip install -e ".[dev]"
pytest
```
## License
[MIT](LICENSE)
TDQS
Scored across 3 tools
Each tool targets a distinct Uniswap version with explicit version-specific parameters (V1 token, V2 token_a/token_b, V3 fee tiers), so there is no ambiguity. Names and descriptions clearly signal which contract type is accessed.
All three tools follow an identical get_v{version}_reserves pattern, making the API predictable and easy to navigate. No mixed casing or inconsistent verbs are present.
Three tools map cleanly to the three major Uniswap versions, and each serves a distinct endpoint type. The count is well-scoped for a narrow read-only reserves server.
The set covers all three Uniswap versions but only exposes raw reserves; V1/V2 reserves are sufficient to compute prices, while V3 prices require sqrtPriceX96 which is not provided. A direct current-price or quote tool would close this notable gap.