Ethereum-Trading-MCP-Server

daylilyg/Ethereum-Trading-MCP-Server

3.1

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

  1. 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.

  2. Uniswap V2 Only: The swap simulation is designed for Uniswap V2. V3 pools with concentrated liquidity are not supported.

  3. 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.

  4. Price Impact: Price impact calculation is simplified and shows "< 1%" as a placeholder. Production systems should query pool reserves for accurate calculations.

  5. No Transaction Execution: The swap_tokens tool only simulates swaps. Actual on-chain execution would require private key management and transaction signing.

  6. Network Dependency: All functionality requires a working Ethereum RPC connection. Rate limits on public endpoints may affect availability.

  7. Decimal Precision: While we use rust_decimal for calculations, extremely large numbers may lose precision when converting to/from U256.

Security Considerations

  • Never commit your .env file 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

Resources