daylilyg/Ethereum-Trading-MCP-Server
If you are the rightful owner of Ethereum-Trading-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 henry@mcphub.com.
The Ethereum Trading MCP Server is a Model Context Protocol server that facilitates AI agents' interaction with the Ethereum blockchain, enabling balance queries, token price retrievals, and Uniswap V2 token swap simulations.
Ethereum Trading MCP Server
A Model Context Protocol (MCP) server that enables AI agents to interact with the Ethereum blockchain. Query balances, get token prices, and simulate Uniswap V2 token swaps.
Features
- get_balance: Query ETH and ERC20 token balances for any address
- get_token_price: Get current token prices in USD and ETH from CoinGecko
- swap_tokens: Simulate Uniswap V2 token swaps with gas estimation (simulation only, not executed on-chain)
Prerequisites
- Rust 1.70+ (install from rustup.rs)
- An Infura API key (get free at infura.io)
- Internet connection for blockchain and price API access
Setup Instructions
1. Clone and Navigate
git clone <your-repo-url>
cd eth_mcp
2. Configure Environment Variables
Copy the example environment file and configure it:
cp .env.example .env
Edit .env and add your Infura API key:
INFURA_API_KEY=your_infura_api_key_here
ETHEREUM_RPC_URL=https://mainnet.infura.io/v3/your_infura_api_key_here
RUST_LOG=info
Note: For testing, you can use public endpoints without an API key, but they may be rate-limited.
3. Build the Project
cargo build --release
4. Run the Server
cargo run --release
The server will start and listen for MCP protocol requests on stdin/stdout.
Usage Examples
Example 1: Get ETH Balance
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_balance",
"arguments": {
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
}
}
}
Response:
{
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"token": null,
"balance": "1234567890123456789",
"decimals": 18,
"symbol": "ETH",
"formatted_balance": "1.234567890123456789"
}
Example 2: Get Token Balance
Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_balance",
"arguments": {
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"token_address": "USDC"
}
}
}
Response:
{
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"balance": "1000000000",
"decimals": 6,
"symbol": "USDC",
"formatted_balance": "1000"
}
Example 3: Get Token Price
Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_token_price",
"arguments": {
"token": "WETH"
}
}
}
Response:
{
"token": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"symbol": "WETH",
"price_usd": "2450.32",
"price_eth": "1"
}
Example 4: Simulate Token Swap
Request:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "swap_tokens",
"arguments": {
"from_token": "WETH",
"to_token": "USDC",
"amount": "1",
"slippage_tolerance": 0.5
}
}
}
Response:
{
"from_token": "WETH",
"to_token": "USDC",
"input_amount": "1",
"estimated_output": "2450.123456",
"minimum_output": "2437.872839",
"price_impact": "< 1%",
"estimated_gas": "0.003",
"route": [
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
]
}
Supported Tokens
The server supports common Ethereum tokens by symbol:
- ETH / WETH: Wrapped Ether
- USDC: USD Coin
- USDT: Tether USD
- DAI: Dai Stablecoin
- WBTC: Wrapped Bitcoin
You can also use any ERC20 token by providing its contract address.
Testing
Run the test suite:
# Run all tests
cargo test
# Run tests including network-dependent ones (requires RPC connection)
cargo test -- --ignored --test-threads=1
Note: Network-dependent tests are marked with #[ignore] and require a valid RPC connection.
Design Decisions
This implementation prioritizes modularity and maintainability by separating concerns into distinct modules: Ethereum client operations, price fetching, Uniswap integration, and MCP server handling. The use of async/await with Tokio ensures efficient handling of I/O-bound operations like RPC calls and HTTP requests. Financial precision is managed using rust_decimal and carefully handling token decimals throughout the system. For swap simulation, the server constructs real Uniswap V2 transactions and uses eth_call simulation to provide accurate output estimates and gas costs without executing on-chain. The price fetching leverages CoinGecko's free API to avoid requiring additional API keys while providing reliable price data for common tokens.
Architecture
┌─────────────────────────────────────┐
│ MCP Server Layer │
│ (Protocol handling, JSON-RPC) │
└────────────┬────────────────────────┘
│
┌────────┴───────┬─────────────┬──────────┐
│ │ │ │
┌───▼──────┐ ┌──────▼────┐ ┌─────▼───┐ ┌────▼────┐
│Ethereum │ │ Price │ │Uniswap │ │ Types │
│ Client │ │ Fetcher │ │ Client │ │& Errors │
└────┬─────┘ └─────┬─────┘ └────┬────┘ └─────────┘
│ │ │
│ ┌────▼─────┐ │
└─────────► ethers ◄───────┘
│ RPC │
└──────────┘
│
┌────▼────┐
│ Infura │
│Ethereum │
│ Node │
└─────────┘
Known Limitations and Assumptions
-
Price Data: Currently limited to popular tokens supported by CoinGecko's free API (ETH, WETH, USDC, USDT, DAI, WBTC). Other tokens require manual contract address input.
-
Uniswap V2 Only: The swap simulation is designed for Uniswap V2. V3 pools with concentrated liquidity are not supported.
-
Gas Estimation: Gas estimates may be approximate for swaps as they don't account for user-specific token approvals or balances. Default values are used when estimation fails.
-
Price Impact: Price impact calculation is simplified and shows "< 1%" as a placeholder. Production systems should query pool reserves for accurate calculations.
-
No Transaction Execution: The
swap_tokenstool only simulates swaps. Actual on-chain execution would require private key management and transaction signing. -
Network Dependency: All functionality requires a working Ethereum RPC connection. Rate limits on public endpoints may affect availability.
-
Decimal Precision: While we use
rust_decimalfor calculations, extremely large numbers may lose precision when converting to/from U256.
Security Considerations
- Never commit your
.envfile or expose API keys - The server does not require or handle private keys for balance queries and price lookups
- Swap simulations are read-only operations that don't execute transactions
- Always verify token addresses before interacting with unknown contracts
Contributing
Contributions are welcome! Please ensure:
- Code compiles without warnings:
cargo build - Tests pass:
cargo test - Code is formatted:
cargo fmt - Clippy is satisfied:
cargo clippy
License
MIT License - See LICENSE file for details