Uniswap MCP Server — Giving AI Agents Direct Access to On-Chain Data
I built a Model Context Protocol (MCP) server that connects any MCP-compatible AI client directly to Uniswap. Once it's running, a model can query token prices, inspect liquidity pools, get swap quotes, and even execute trades — without any custom integration code on the client side.
The Problem
AI agents live in a closed world. To answer questions about Uniswap — "what's the current price of WETH?" or "is there more liquidity in the 0.05% or 0.3% WETH/USDC pool?" — a model needs data. The usual answer is a hand-rolled RAG pipeline or a custom API wrapper that goes stale.
The Model Context Protocol is a standardized way to give models exactly the tools they need. This server implements it using the FastMCP framework, so any MCP client (Claude Desktop, Cursor, or a custom agent) picks up the tools instantly from a single config line.
Two Modes
The server runs in two modes:
- Read-only — query token info, pool data, and swap quotes. No private key required.
- Read-write — everything above, plus on-chain swap execution. Requires a funded wallet private key.
The network is detected automatically from the chain_id the RPC endpoint reports. Point it at Ethereum, Polygon, Optimism, or Arbitrum — all V2 and V3 contract addresses are hardcoded per network and validated at startup.
The Tools
The model gets seven callable tools:
| Tool | What it does |
|---|---|
get_token_info | ERC-20 metadata (name, symbol, decimals, supply) |
get_token_price | Real-time USD price derived from on-chain V3 pool data |
get_v3_pool | Full V3 pool state — liquidity, sqrt price, current tick |
get_v2_pair | V2 reserves and implied price |
get_pool_by_address | V3 pool state by address directly |
get_swap_quote | Simulated quote via the on-chain Quoter — no transaction |
execute_swap | Executes a real swap through the V3 router |
The pricing logic is the interesting part. get_token_price doesn't call any off-chain price oracle. It walks the token's actual V3 pools against USDC, USDT, and WETH across the three fee tiers (500, 3000, 10000 bps) and returns the first valid price it finds:
# walks USDC, USDT, WETH quote pools across fee tiers
# and returns the first valid USD price for a token
Resources and Prompts
Beyond tools, the server exposes MCP resources — read-only data a model can fetch mid-conversation:
protocol://addresses— canonical V2/V3 factory, quoter, router, WETH, USDC, and USDT addresses for the connected chainnetwork://status— chain ID and latest block
And two prompts that guide the model through multi-step workflows:
analyze_token— fetches addresses, reads the USD price, inspects the V3 pool, and synthesizes a reportexecute_trade— a confirmation-gated swap flow: quote first, present it to the user, and only execute after explicit approval
The execute_trade prompt is a deliberate safety design. The model can't fire a swap on its own — it must show the quote and get confirmation, which keeps live trading human-gated.
Swap Execution
execute_swap sends a real transaction through the V3 router. Details that matter in production:
- The router is auto-approved — if the current token allowance is insufficient, it grants one and proceeds
- Slippage defaults to 50 bps (0.5%) and is configurable per call
- A deadline in minutes from now protects against long-mempool transactions
- If no private key is configured, the tool returns a clear error instead of failing silently
Testing
The suite runs fully offline — every blockchain call is mocked. It covers 204 tests across configuration, address validation, ABI loading, every contract wrapper, the UniswapClient, and each tool, resource, and prompt:
uv run pytest tests/
Setup
Install with uv and point it at any Ethereum-compatible RPC:
uv sync
uv run python server.py
For Claude Desktop, add it as an MCP server and the tools appear in the next conversation:
{
"mcpServers": {
"uniswap": {
"command": "uv",
"args": ["run", "python", "server.py"],
"env": { "RPC_URL": "https://mainnet.infura.io/v3/YOUR_PROJECT_ID" }
}
}
}
Reflections
The cleanest part of this design is how little glue there is. Because MCP standardizes the interface, I didn't have to build any client integration — one config block and the model has live, on-chain Uniswap data. The tool surface stays small and typed, and the test suite runs without a network, so it's easy to iterate on.
Check it out on GitHub: rakibhossain72/uniswap-mcp-server