以太坊交易MCP服务器
一个内置于Rust中的MCP服务器,用于与以太坊区块链进行交互。
特性
get_balance:使用正确的十进制格式查询ETH和ERC20代币余额。get_token_price:获取当前代币的美元价格。通过Chainlink支持ETH,通过Uniswap V3支持任意代币(小数正确)。swap_tokens:模拟Uniswap V3交换,计算滑动的最小输出,构造路由器调用数据,并执行只读eth_call在路由器上。
先决条件
- Rust(最新稳定版)
- 以太坊RPC URL(例如,来自Alchemy或Infura)
- 私钥(用于签署交易/模拟)
设置
- 克隆存储库。
- 复制
.env.example到.env:
cp .env.example .env- 编辑
.env并设置您的ETHEREUM_RPC_URL和PRIVATE_KEY.
用法
建筑
cargo build --release跑步
服务器使用Stdio进行MCP通信。
cargo runMCP工具调用示例
get_balance
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_balance",
"arguments": {
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"token_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
},
"id": 1
}get_token_price (任意令牌)
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_token_price",
"arguments": {
"token_symbol": "UNI",
"token_address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
}
},
"id": 2
}swap_tokens (模拟与构造)
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "swap_tokens",
"arguments": {
"from_token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"to_token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"amount": "1000000000000000000",
"slippage_tolerance": 0.5
}
},
"id": 3
}设计决策
- 客户选择:合金因其性能、强打字性和无重编码要求而被使用。
- 异步/运行时:Tokio+异步无处不在,以匹配RPC绑定的工作负载;工具是
Send + Sync用于并发处理。 - 精确度:
rust_decimal端到端用于价格/平衡数学,以避免浮动漂移;Q96是一个固定的十进制常数,用于防止溢出。 - Uniswap V3:被选中以有效覆盖大多数主网流动性和费用级别。
- 交换模拟:两步流程:QuoterV2
eth_call量/气体,后面是路由器eth_call通过真实的通话数据来解决审批/资金问题。 - 通话数据暴露:
swap_tokens返回路由器呼叫数据,以便代理可以签名/广播;模拟是只读的。 - 小数处理:ERC20
decimals()按价格/余额提取;使用decimal安全助手构建10^小数,以避免溢出。 - MCP形状:混合响应(
content对于严格的MCP,data用于结构化消费),以最大限度地提高兼容性和程序可用性。 - 错误透明度:路由器模拟错误再次出现
router_call_simulation而不是被吞下。 - 范围:专注于Uniswap V3和ERC20-到ERC20的互换。
局限性
- 天然气估算:返回的气体估计值用于模拟(Quoter),可能与实际掉期交易气体不同。
- 价格影响:价格工具根据以下公式计算现货价格
slot0并且没有考虑大型交易的价格影响(尽管swap_tokens模拟确实如此)。 - 批准/资金:路由器
eth_call如果签署人缺乏津贴或余额,则可以恢复;这会在响应中出现,但不会自动解决。 - 覆盖:只实现了Uniswap V3路径(没有V2),交换假设ERC20->ERC20(不包括ETH包装/解包)。
错误响应示例
路由器模拟恢复(缺少容差/平衡)
{
"jsonrpc": "2.0",
"result": {
"content": [{ "type": "text", "text": "{...}" }],
"data": {
"estimated_output": "123",
"minimum_output": "122",
"transaction": { "to": "0xE5924...", "data": "0x...", "value": "0" },
"router_call_simulation": {
"status": "error",
"message": "execution reverted: TransferHelper: TRANSFER_FROM_FAILED"
}
}
},
"id": 1
}没有地址的未知令牌符号
{
"jsonrpc": "2.0",
"error": {
"code": -32603,
"message": "Tool execution failed: Unknown token symbol. Please provide token_address."
},
"id": 2
}