Skip to content

Commit de0a4fb

Browse files
committed
Initial release: Complete Python Etherscan MCP Server
Features: - 55 Etherscan API tools across 9 categories - Drop-in replacement for TypeScript etherscan-mcp - FastMCP integration with full compatibility - Comprehensive error handling and validation - Complete documentation and examples Tool Categories: - Account Tools (12): Balance, transactions, tokens, mining history - Block Tools (4): Rewards, countdown, timestamp lookups, tx counts - Contract Tools (4): Source code, ABI, verification status - Transaction Tools (2): Status and receipt validation - Token Tools (2): Supply and balance queries - Gas Tools (3): Price oracle, estimates, historical data - Statistics Tools (13): Network metrics, daily stats, ETH price - Logs Tools (3): Event log filtering and retrieval - RPC Tools (13): Full Ethereum RPC proxy support Production ready with comprehensive testing Compatible with Agno framework MCPTools Successfully integrated with web3_GAIA_test.py
0 parents  commit de0a4fb

File tree

17 files changed

+1917
-0
lines changed

17 files changed

+1917
-0
lines changed

.gitignore

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
MANIFEST
23+
24+
# PyInstaller
25+
*.manifest
26+
*.spec
27+
28+
# Unit test / coverage reports
29+
htmlcov/
30+
.tox/
31+
.nox/
32+
.coverage
33+
.coverage.*
34+
.cache
35+
nosetests.xml
36+
coverage.xml
37+
*.cover
38+
.hypothesis/
39+
.pytest_cache/
40+
41+
# Virtual environments
42+
.env
43+
.venv
44+
env/
45+
venv/
46+
ENV/
47+
env.bak/
48+
venv.bak/
49+
50+
# IDEs
51+
.vscode/
52+
.idea/
53+
*.swp
54+
*.swo
55+
*~
56+
57+
# OS
58+
.DS_Store
59+
.DS_Store?
60+
._*
61+
.Spotlight-V100
62+
.Trashes
63+
ehthumbs.db
64+
Thumbs.db
65+
66+
# API Keys (important!)
67+
.env
68+
*.key
69+
secrets.json
70+
71+
# Logs
72+
*.log
73+
logs/
74+
75+
# Temporary files
76+
*.tmp
77+
*.temp
78+
.cache/

README.md

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
# Etherscan MCP Python Server
2+
3+
A complete Python implementation of the Etherscan Model Context Protocol (MCP) server, providing comprehensive access to Ethereum blockchain data through the Etherscan API.
4+
5+
## Overview
6+
7+
This server provides 53+ tools for accessing Ethereum blockchain data, including:
8+
9+
- **Account Tools**: Balance checking, transaction history, internal transactions
10+
- **Block Tools**: Block data, rewards, timing information
11+
- **Contract Tools**: Source code, ABI, verification status
12+
- **Transaction Tools**: Transaction details, receipts, status
13+
- **Token Tools**: Transfers, balances, supply information
14+
- **Gas Tools**: Gas prices, estimates, oracle data
15+
- **Statistics Tools**: Network metrics, supply data
16+
- **RPC Tools**: Ethereum RPC proxy methods
17+
- **Logs Tools**: Event logs and filtering
18+
19+
## Requirements
20+
21+
- Python 3.8+
22+
- Etherscan API Key
23+
24+
## Installation
25+
26+
```bash
27+
cd etherscan-mcp-python
28+
pip install -e .
29+
```
30+
31+
## Configuration
32+
33+
Set your Etherscan API key as an environment variable:
34+
35+
```bash
36+
export ETHERSCAN_API_KEY="your_api_key_here"
37+
```
38+
39+
## Usage
40+
41+
### Standalone Server
42+
```bash
43+
python server.py
44+
```
45+
46+
### With MCP Tools (Agno Framework)
47+
```python
48+
from agno.tools.mcp import MCPTools
49+
50+
etherscan_mcp = MCPTools(
51+
command="python etherscan-mcp-python/server.py",
52+
env={"ETHERSCAN_API_KEY": "your_api_key"},
53+
timeout_seconds=120
54+
)
55+
```
56+
57+
## Complete Tool Reference
58+
59+
### 🏦 Account Tools (12 tools)
60+
| Tool Name | Description | Key Parameters |
61+
|-----------|-------------|----------------|
62+
| `account_balance` | Get ETH balance for single address | `address`, `chainid` |
63+
| `account_balancemulti` | Get ETH balance for multiple addresses (up to 20) | `address` (comma-separated), `chainid` |
64+
| `account_txlist` | Get normal transactions by address | `address`, `startblock`, `endblock`, `page`, `offset` |
65+
| `account_txlistinternal` | Get internal transactions by address | `address`, `startblock`, `endblock`, `page`, `offset` |
66+
| `account_txlistinternal_byhash` | Get internal transactions by transaction hash | `txhash`, `chainid` |
67+
| `account_txlistinternal_byblock` | Get internal transactions by block range | `startblock`, `endblock`, `page`, `offset` |
68+
| `account_tokentx` | Get ERC20 token transfer events | `address`, `contractaddress`, `startblock`, `endblock` |
69+
| `account_tokennfttx` | Get ERC721 (NFT) token transfer events | `address`, `contractaddress`, `startblock`, `endblock` |
70+
| `account_token1155tx` | Get ERC1155 token transfer events | `address`, `contractaddress`, `startblock`, `endblock` |
71+
| `account_fundedby` | Get address funding source and age | `address`, `chainid` |
72+
| `account_getminedblocks` | Get blocks validated by address | `address`, `blocktype`, `page`, `offset` |
73+
| `account_txsBeaconWithdrawal` | Get beacon chain withdrawals | `address`, `startblock`, `endblock`, `page`, `offset` |
74+
75+
### 🧱 Block Tools (4 tools)
76+
| Tool Name | Description | Key Parameters |
77+
|-----------|-------------|----------------|
78+
| `block_getblockreward` | Get block mining reward and uncle rewards | `blockno`, `chainid` |
79+
| `block_getblockcountdown` | Get estimated time until block is mined | `blockno`, `chainid` |
80+
| `block_getblocknobytime` | Get block number by timestamp | `timestamp`, `closest`, `chainid` |
81+
| `block_getblocktxnscount` | Get number of transactions in block | `blockno`, `chainid` |
82+
83+
### 📄 Contract Tools (4 tools)
84+
| Tool Name | Description | Key Parameters |
85+
|-----------|-------------|----------------|
86+
| `contract_getabi` | Get contract ABI for verified contracts | `address`, `chainid` |
87+
| `contract_getsourcecode` | Get verified contract source code | `address`, `chainid` |
88+
| `contract_getcontractcreation` | Get contract creator and creation tx hash | `contractaddresses`, `chainid` |
89+
| `contract_checkverifystatus` | Check contract verification status | `guid`, `chainid` |
90+
91+
### 🔄 Transaction Tools (2 tools)
92+
| Tool Name | Description | Key Parameters |
93+
|-----------|-------------|----------------|
94+
| `transaction_getstatus` | Get contract execution status | `txhash`, `chainid` |
95+
| `transaction_gettxreceiptstatus` | Get transaction receipt status | `txhash`, `chainid` |
96+
97+
### 🪙 Token Tools (2 tools)
98+
| Tool Name | Description | Key Parameters |
99+
|-----------|-------------|----------------|
100+
| `stats_tokensupply` | Get ERC20 token total supply | `contractaddress`, `chainid` |
101+
| `account_tokenbalance` | Get ERC20 token balance of address | `contractaddress`, `address`, `chainid` |
102+
103+
### ⛽ Gas Tools (3 tools)
104+
| Tool Name | Description | Key Parameters |
105+
|-----------|-------------|----------------|
106+
| `gas_gasestimate` | Get estimated confirmation time for gas price | `gasprice`, `chainid` |
107+
| `gas_gasoracle` | Get current safe/proposed/fast gas prices | `chainid` |
108+
| `stats_dailyavggaslimit` | Get historical daily average gas limit | `startdate`, `enddate`, `sort`, `chainid` |
109+
110+
### 📊 Statistics Tools (13 tools)
111+
| Tool Name | Description | Key Parameters |
112+
|-----------|-------------|----------------|
113+
| `stats_ethsupply` | Get total ETH supply (excluding staking/burnt) | `chainid` |
114+
| `stats_ethsupply2` | Get total ETH supply (including staking/burnt) | `chainid` |
115+
| `stats_ethprice` | Get current ETH price | `chainid` |
116+
| `stats_chainsize` | Get blockchain size over date range | `startdate`, `enddate`, `clienttype`, `syncmode` |
117+
| `stats_nodecount` | Get total discoverable nodes | `chainid` |
118+
| `stats_dailytxnfee` | Get daily transaction fees paid to miners | `startdate`, `enddate`, `sort` |
119+
| `stats_dailynewaddress` | Get daily new address count | `startdate`, `enddate`, `sort` |
120+
| `stats_dailynetutilization` | Get daily network utilization percentage | `startdate`, `enddate`, `sort` |
121+
| `stats_dailyavghashrate` | Get daily average network hash rate | `startdate`, `enddate`, `sort` |
122+
| `stats_dailytx` | Get daily transaction count | `startdate`, `enddate`, `sort` |
123+
| `stats_dailyavgnetdifficulty` | Get daily average mining difficulty | `startdate`, `enddate`, `sort` |
124+
| `stats_ethdailyprice` | Get historical ETH prices | `startdate`, `enddate`, `sort` |
125+
126+
### 📝 Logs Tools (3 tools)
127+
| Tool Name | Description | Key Parameters |
128+
|-----------|-------------|----------------|
129+
| `logs_getLogsByAddress` | Get event logs from address with block range | `address`, `fromBlock`, `toBlock`, `page`, `offset` |
130+
| `logs_getLogsByTopics` | Get event logs filtered by topics | `fromBlock`, `toBlock`, `topic0-3`, operators |
131+
| `logs_getLogsByAddressAndTopics` | Get event logs from address filtered by topics | `address`, `fromBlock`, `toBlock`, `topic0-3` |
132+
133+
### 🔗 RPC Proxy Tools (13 tools)
134+
| Tool Name | Description | Key Parameters |
135+
|-----------|-------------|----------------|
136+
| `proxy_eth_blockNumber` | Get latest block number | `chainid` |
137+
| `proxy_eth_getBlockByNumber` | Get block information by number | `tag`, `boolean`, `chainid` |
138+
| `proxy_eth_getUncleByBlockNumberAndIndex` | Get uncle block by number and index | `tag`, `index`, `chainid` |
139+
| `proxy_eth_getBlockTransactionCountByNumber` | Get transaction count in block | `tag`, `chainid` |
140+
| `proxy_eth_getTransactionByHash` | Get transaction by hash | `txhash`, `chainid` |
141+
| `proxy_eth_getTransactionByBlockNumberAndIndex` | Get transaction by block and index | `tag`, `index`, `chainid` |
142+
| `proxy_eth_getTransactionCount` | Get transaction count by address | `address`, `tag`, `chainid` |
143+
| `proxy_eth_getTransactionReceipt` | Get transaction receipt | `txhash`, `chainid` |
144+
| `proxy_eth_call` | Execute message call without transaction | `to`, `data`, `tag`, `chainid` |
145+
| `proxy_eth_getCode` | Get code at address | `address`, `tag`, `chainid` |
146+
| `proxy_eth_getStorageAt` | Get storage value at position | `address`, `position`, `tag`, `chainid` |
147+
| `proxy_eth_gasPrice` | Get current gas price | `chainid` |
148+
| `proxy_eth_estimateGas` | Estimate gas for transaction | `data`, `to`, `value`, `gas`, `gasPrice` |
149+
150+
## 🎯 Use Cases & Examples
151+
152+
### Basic Balance Check
153+
```python
154+
# Get ETH balance for single address
155+
account_balance(address="0x...", chainid="1")
156+
157+
# Get balances for multiple addresses (up to 20)
158+
account_balancemulti(address="0x...,0x...,0x...", chainid="1")
159+
```
160+
161+
### Transaction Analysis
162+
```python
163+
# Get transaction history for address
164+
account_txlist(address="0x...", startblock="0", endblock="99999999")
165+
166+
# Get internal transactions (contract interactions)
167+
account_txlistinternal(address="0x...", page="1", offset="100")
168+
```
169+
170+
### Block Information
171+
```python
172+
# Get transaction count in specific block (like the web3_GAIA_test.py example)
173+
block_getblocktxnscount(blockno="17000000", chainid="1")
174+
175+
# Get block mining rewards
176+
block_getblockreward(blockno="17000000", chainid="1")
177+
```
178+
179+
### Market Data
180+
```python
181+
# Get current ETH price
182+
stats_ethprice(chainid="1")
183+
184+
# Get current gas prices
185+
gas_gasoracle(chainid="1")
186+
```
187+
188+
### Smart Contract Analysis
189+
```python
190+
# Get contract source code (if verified)
191+
contract_getsourcecode(address="0x...", chainid="1")
192+
193+
# Get contract ABI
194+
contract_getabi(address="0x...", chainid="1")
195+
```
196+
197+
## 🔧 Advanced Configuration
198+
199+
### Multi-Chain Support
200+
The server supports multiple Ethereum networks via the `chainid` parameter:
201+
- `"1"` - Ethereum Mainnet (default)
202+
- `"5"` - Goerli Testnet
203+
- `"11155111"` - Sepolia Testnet
204+
- And other supported networks
205+
206+
### Error Handling
207+
The server includes comprehensive error handling for:
208+
- ❌ Missing API keys
209+
- ❌ Invalid parameters
210+
- ❌ API rate limits
211+
- ❌ Network timeouts
212+
- ❌ Malformed responses
213+
214+
### Performance Optimization
215+
- ✅ Synchronous HTTP client for MCP compatibility
216+
- ✅ Efficient JSON parsing and response formatting
217+
- ✅ Proper timeout handling (120 seconds default)
218+
- ✅ Memory-efficient tool registration
219+
220+
## 🔐 Security & Best Practices
221+
222+
### API Key Management
223+
- Store `ETHERSCAN_API_KEY` in environment variables
224+
- Never commit API keys to version control
225+
- Use `.env` files for local development
226+
- Rotate API keys regularly
227+
228+
### Rate Limiting
229+
- Etherscan API has rate limits (free tier: 5 calls/sec)
230+
- The server respects these limits
231+
- Consider upgrading to Etherscan Pro for higher limits
232+
233+
### Data Validation
234+
- All input parameters are validated
235+
- API responses are checked for errors
236+
- Malformed data is handled gracefully
237+
238+
## 🆘 Troubleshooting
239+
240+
### Common Issues
241+
242+
**❌ "ETHERSCAN_API_KEY not set"**
243+
- Solution: Set the environment variable `export ETHERSCAN_API_KEY="your_key"`
244+
245+
**❌ "Connection closed" or "Runtime error"**
246+
- Solution: Ensure you're not running in nested async context
247+
- Check that the server.py uses synchronous `main()` function
248+
249+
**❌ "Tool not found"**
250+
- Solution: Verify tool names use underscores (`account_balance` not `account/balance`)
251+
- Check that tool renaming for Gemini compatibility is applied
252+
253+
**❌ "Timeout after 120 seconds"**
254+
- Solution: Check internet connectivity and API key validity
255+
- Verify Etherscan API is not experiencing outages
256+
257+
### Debug Mode
258+
For debugging, you can modify the server to add verbose logging:
259+
```python
260+
import logging
261+
logging.basicConfig(level=logging.DEBUG)
262+
```
263+
264+
## 🤝 Contributing
265+
266+
### Adding New Tools
267+
1. Choose appropriate tool category file (`src/tools/`)
268+
2. Follow existing patterns for parameter validation
269+
3. Add comprehensive docstrings
270+
4. Test with actual API calls
271+
5. Update this README with new tool documentation

0 commit comments

Comments
 (0)