使用说明
以太坊交易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或公共端点)
- 用于交易签名的私钥(仅用于模拟)
安装
-
克隆存储库
-
复制示例环境文件:
cp .env.example .env
- 编辑
.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 为了安全起见,文件被忽略了。
- 构建项目:
cargo build --release
- 运行服务器:
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 MCP客户端 (
examples/python_mcp_client.py)-显示所有可用工具的全功能示例
运行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客户端和工具的最大兼容性。
已知限制和假设
-
小数假设: 掉期模拟假设输入金额为18位小数。生产代码应查询每个令牌的decimals()函数。
-
仅限Uniswap V2: 目前仅支持Uniswap V2。V3具有不同的机制(集中流动性),需要单独实施。
-
主网焦点: 配置针对以太坊主网进行了优化。其他网络(L2、测试网)需要不同的合约地址。
-
无交易执行: 这
swap_tokens该工具仅模拟掉期和估算天然气。它不执行真实的交易,为探索性使用提供了安全性。 -
Oracle价格: 代币价格使用Uniswap V2流动性池。对于低流动性代币,价格可能不准确。生产系统应整合多种价格来源。
-
错误处理: 虽然很全面,但一些边缘情况(网络故障、无效令牌)可能没有完美的面向用户的错误消息。
-
速率限制: RPC调用没有内置速率限制。大量使用可能会达到提供商的限制。