Skip to main content
Glama
main.py4.18 kB
""" Contract Inspector MCP Server - 使用 FastMCP 根据官方规范编写的 EVM 合约信息查询工具 """ from mcp.server.fastmcp import FastMCP from dotenv import load_dotenv import json import os import asyncio from .contract_analyzer import ContractAnalyzer from .config import config # 加载环境变量 load_dotenv() # 创建 FastMCP 实例 mcp = FastMCP("contract-inspector") # 初始化合约分析器 analyzer = ContractAnalyzer() @mcp.tool() async def contract_info(contract_address: str): """ 获取 EVM 合约的完整链上信息,包括调用所有无参数的 view 函数 Args: contract_address: EVM 合约地址 (0x开头的42位十六进制字符串) Returns: 合约的详细信息,包括基础信息和所有view函数的调用结果 """ # 验证合约地址格式 if not contract_address or not isinstance(contract_address, str): raise ValueError("合约地址不能为空且必须是字符串") if not contract_address.startswith("0x") or len(contract_address) != 42: raise ValueError("合约地址格式无效,必须是0x开头的42位十六进制字符串") try: print(f"🔍 开始分析合约: {contract_address}") # 执行合约分析 result = await analyzer.analyze_contract(contract_address) # 格式化输出 formatted_result = json.dumps(result, ensure_ascii=False, indent=2) print(f"✅ 合约分析完成: {contract_address}") return formatted_result except Exception as e: error_msg = f"合约分析失败: {str(e)}" print(f"❌ {error_msg}") error_response = { "status": "error", "error": error_msg, "contract_address": contract_address, "tool": "contract_info" } return json.dumps(error_response, ensure_ascii=False, indent=2) @mcp.tool() async def contract_summary(contract_address: str): """ 获取合约基本摘要信息,不调用合约函数,快速获取合约概况 Args: contract_address: EVM 合约地址 (0x开头的42位十六进制字符串) Returns: 合约的基本摘要信息 """ # 验证合约地址格式 if not contract_address or not isinstance(contract_address, str): raise ValueError("合约地址不能为空且必须是字符串") if not contract_address.startswith("0x") or len(contract_address) != 42: raise ValueError("合约地址格式无效,必须是0x开头的42位十六进制字符串") try: print(f"📋 获取合约摘要: {contract_address}") # 获取合约摘要 result = await analyzer.get_contract_summary(contract_address) # 格式化输出 formatted_result = json.dumps(result, ensure_ascii=False, indent=2) print(f"✅ 合约摘要获取完成: {contract_address}") return formatted_result except Exception as e: error_msg = f"获取合约摘要失败: {str(e)}" print(f"❌ {error_msg}") error_response = { "status": "error", "error": error_msg, "contract_address": contract_address, "tool": "contract_summary" } return json.dumps(error_response, ensure_ascii=False, indent=2) def main(): """主入口函数""" print("🚀 启动 Contract Inspector MCP 服务器 (FastMCP)...") print(f"📡 RPC URL: {config.rpc_url}") print(f"🔑 Etherscan API: {config.etherscan_base_url}") print(f"⛓️ Chain ID: {config.chain_id}") print("=" * 50) try: # 验证配置 config.validate() print("✅ 配置验证通过") # 运行 FastMCP 服务器 mcp.run(transport="stdio") except KeyboardInterrupt: print("\n👋 服务器已停止") except Exception as e: print(f"❌ 服务器启动失败: {e}") import sys sys.exit(1) if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ACaiSec/ContractInfoMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server