以太坊交易MCP服务器

一个基于Rust的Model Context Protocol (MCP)服务器,用于查询以太坊余额和执行代币交换。

  • by HONGJICAI
  • Rust
  • 本地部署
  • 更新于
在 GitHub 查看 HONGJICAI/Ethereum-Trading-MCP-Server

使用说明

以太坊交易MCP服务器

概述

这是Rust中的模型上下文协议(MCP)服务器,能够查询以太坊上的余额并执行代币交换。

特性

  • get_balance -通过适当的十进制处理查询ETH和ERC20代币余额
  • get_token_price -使用Uniswap V2获取美元或以太坊的当前代币价格
  • swap_tokens -在Uniswap V2上模拟代币交换(在不执行的情况下返回估计值)

设置

先决条件

  • 锈蚀1.70+(rustup 推荐)
  • Python 3.11+(如果自动测试mcp服务器)
  • 以太坊RPC端点(Infura、Alchemy或公共端点)
  • 用于交易签名的私钥(仅用于模拟)

安装

  1. 克隆存储库

  2. 复制示例环境文件:

cp .env.example .env
  1. 编辑 .env 使用您的配置,或使用以下测试配置:
# Using free public endpoint (may be slower than paid services)
ETH_RPC_URL=https://eth.llamarpc.com
PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001
CHAIN_ID=1

⚠️ 安全警告: 永远不要提交你真正的私钥!这 .env 为了安全起见,文件被忽略了。

  1. 构建项目:
cargo build --release
  1. 运行服务器:
cargo run --release

服务器从stdin读取JSON-RPC请求,并将响应写入stdout。

测试

单元测试

运行单元测试套件:

cargo test

集成测试

运行集成测试(需要互联网连接才能查询以太坊主网):

cargo test --test integration_tests -- --ignored --nocapture

这些测试验证了真实的区块链交互,包括:

  • 查询实际ETH/代币余额
  • 获取真正的Uniswap价格
  • 在主网上模拟交换

覆盖范围报告

生成代码覆盖率报告:

cargo tarpaulin --out Html --output-dir coverage --exclude-files "target/*"

客户示例

看 examples/ 演示如何使用MCP服务器的客户端实现目录:

运行Python示例:

cd examples
pip install -r ../requirements.txt
python python_mcp_client.py

看 examples/README.md 了解更多详情。

手动测试

您可以在控制台应用程序或web UI上进行测试。

控制台

检查下面的MCP tppl调用示例,然后将请求复制并粘贴到stdin,并检查MCP服务器的响应。

Web用户界面

需要先安装node.js。

npx @modelcontextprotocol/inspector cargo run --release

然后单击连接,列出工具,工具按钮进行测试。

MCP工具调用示例

在粘贴到stdin之前,您需要缩小json。

缩小的有用工具: JSON监视器

初始化

请求:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"example-client","version":"1.0.0"}}}

答复:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "serverInfo": {
      "name": "Ethereum Trading MCP Server",
      "version": "0.1.0"
    },
    "capabilities": {
      "tools": {}
    }
  }
}

已初始化通知

重要:收到初始化响应后,您必须发送此通知:

{"jsonrpc":"2.0","method":"notifications/initialized"}

此通知没有响应。它表示客户端已准备好开始正常操作。

列出工具

请求:

{"jsonrpc":"2.0","id":2,"method":"tools/list"}

答复:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "get_balance",
        "description": "Query ETH or ERC20 token balance for a given wallet address",
        "inputSchema": {
          "type": "object",
          "properties": {
            "address": {
              "type": "string",
              "description": "The wallet address to query"
            },
            "token_address": {
              "type": "string",
              "description": "Optional ERC20 token contract address. If omitted, returns ETH balance"
            }
          },
          "required": ["address"]
        }
      }
    ]
  }
}

调用get_balance

以太网扫描 网址

请求:

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_balance","arguments":{"address":"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"}}}

答复:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n  \"address\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n  \"balance\": \"3.7\",\n  \"symbol\": \"ETH\",\n  \"decimals\": 18\n}"
      }
    ]
  }
}

调用get_token_price

获取UNI代币的美元价格。

请求:

{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_token_price","arguments":{"token_address":"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984","quote_currency":"USD"}}}

答复:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n  \"token_address\": \"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984\",\n  \"price\": \"8.50\",\n  \"quote_currency\": \"USD\"\n}"
      }
    ]
  }
}

获取UNI代币的ETH价格。

请求:

{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"get_token_price","arguments":{"token_address":"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984","quote_currency":"ETH"}}}

答复:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n  \"token_address\": \"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984\",\n  \"price\": \"0.00243\",\n  \"quote_currency\": \"ETH\"\n}"
      }
    ]
  }
}

调用swap_tomates(模拟)

请求:

{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"swap_tokens","arguments":{"from_token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","to_token":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","amount":"1.0","slippage_tolerance":0.5}}}

答复:

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n  \"from_token\": \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n  \"to_token\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n  \"amount_in\": \"1.0\",\n  \"estimated_amount_out\": \"3500.0\",\n  \"minimum_amount_out\": \"3482.5\",\n  \"gas_estimate\": \"150000\",\n  \"gas_price_gwei\": \"30\",\n  \"estimated_gas_cost_eth\": \"0.0045\"\n}"
      }
    ]
  }
}

设计决策

架构: 该系统采用模块化架构构建,将关注点分为不同的模块:以太坊客户端操作、MCP服务器协议处理和单个工具实现。这使得代码库易于维护和测试。

以太坊库: 我们使用 ethers-rs 由于其成熟的生态系统、强大的类型安全性和全面的ABI编码/解码能力,以太坊交互非常适合。该库为合约交互和RPC操作提供了出色的支持。

Uniswap集成: 该实现使用Uniswap V2路由器进行价格查询和交换模拟。掉期交易是通过以下方式模拟的 getAmountsOut 用于价格估算和天然气估算,而无需在链上执行交易。这提供了安全的只读操作。

财务精确度: 所有财务计算均使用 rust_decimal 以避免浮点精度问题。代币金额在人类可读的小数和区块链wei/Token单位之间正确转换。

MCP协议: 服务器通过stdin/stdout手动实现MCP协议的JSON-RPC 2.0规范。这提供了与MCP客户端和工具的最大兼容性。

已知限制和假设

  1. 小数假设: 掉期模拟假设输入金额为18位小数。生产代码应查询每个令牌的decimals()函数。

  2. 仅限Uniswap V2: 目前仅支持Uniswap V2。V3具有不同的机制(集中流动性),需要单独实施。

  3. 主网焦点: 配置针对以太坊主网进行了优化。其他网络(L2、测试网)需要不同的合约地址。

  4. 无交易执行: 这 swap_tokens 该工具仅模拟掉期和估算天然气。它不执行真实的交易,为探索性使用提供了安全性。

  5. Oracle价格: 代币价格使用Uniswap V2流动性池。对于低流动性代币,价格可能不准确。生产系统应整合多种价格来源。

  6. 错误处理: 虽然很全面,但一些边缘情况(网络故障、无效令牌)可能没有完美的面向用户的错误消息。

  7. 速率限制: RPC调用没有内置速率限制。大量使用可能会达到提供商的限制。