Skip to content

Commit 5d5a8ee

Browse files
authored
Merge pull request #24 from aaurelions/fix/critical-bugs-and-add-message-signing
Fix critical bugs, add message signing capabilities and multicall tool
2 parents 4c11ddc + dd3c354 commit 5d5a8ee

4 files changed

Lines changed: 446 additions & 78 deletions

File tree

README.md

Lines changed: 133 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ All services are exposed through a consistent interface of MCP tools, resources,
5656
### Token services
5757

5858
- **ERC20 Tokens**
59+
5960
- Get token metadata (name, symbol, decimals, supply)
6061
- Check token balances
6162
- Transfer tokens between addresses
6263
- Approve spending allowances
6364

6465
- **NFTs (ERC721)**
66+
6567
- Get collection and token metadata
6668
- Verify token ownership
6769
- Transfer NFTs between addresses
@@ -89,6 +91,14 @@ All services are exposed through a consistent interface of MCP tools, resources,
8991
- **Transaction status** and receipt information
9092
- **Error handling** with descriptive messages
9193

94+
### Message Signing Capabilities
95+
96+
- **Personal Message Signing** - Sign arbitrary messages for authentication and verification
97+
- **EIP-712 Typed Data Signing** - Sign structured data for gasless transactions and meta-transactions
98+
- **SIWE Support** - Enable Sign-In With Ethereum authentication flows
99+
- **Permit Signatures** - Create off-chain approvals for gasless token operations
100+
- **Meta-Transaction Support** - Sign transaction data for relay services and gasless transfers
101+
92102
### AI-Guided Workflows (Prompts)
93103

94104
- **Transaction preparation** - Guidance for planning and executing transfers
@@ -102,6 +112,7 @@ All services are exposed through a consistent interface of MCP tools, resources,
102112
## 🌐 Supported Networks
103113

104114
### Mainnets
115+
105116
- Ethereum (ETH)
106117
- Optimism (OP)
107118
- Arbitrum (ARB)
@@ -135,6 +146,7 @@ All services are exposed through a consistent interface of MCP tools, resources,
135146
- Lumia
136147

137148
### Testnets
149+
138150
- Sepolia
139151
- Optimism Sepolia
140152
- Arbitrum Sepolia
@@ -204,18 +216,23 @@ export EVM_ACCOUNT_INDEX="0" # Optional: Account index for HD wallet derivation
204216
```
205217

206218
The mnemonic option supports hierarchical deterministic (HD) wallet derivation:
219+
207220
- Uses BIP-39 standard mnemonic phrases (12 or 24 words)
208221
- Supports BIP-44 derivation path: `m/44'/60'/0'/0/{accountIndex}`
209222
- `EVM_ACCOUNT_INDEX` allows you to derive different accounts from the same mnemonic
210223
- Default account index is 0 (first account)
211224

212225
**Wallet is used for:**
226+
213227
- Transferring native tokens (`transfer_native` tool)
214228
- Transferring ERC20 tokens (`transfer_erc20` tool)
215229
- Approving token spending (`approve_token_spending` tool)
216230
- Writing to smart contracts (`write_contract` tool)
231+
- Signing messages for authentication (`sign_message` tool)
232+
- Signing structured data for gasless transactions (`sign_typed_data` tool)
233+
234+
⚠️ **Security**:
217235

218-
⚠️ **Security**:
219236
- Never commit your private key or mnemonic to version control
220237
- Use environment variables or a secure key management system
221238
- Store mnemonics securely - they provide access to all derived accounts
@@ -228,11 +245,13 @@ export ETHERSCAN_API_KEY="your-api-key-here"
228245
```
229246

230247
This API key is optional but required for:
248+
231249
- Automatic ABI fetching from block explorers (`get_contract_abi` tool)
232250
- Auto-fetching ABIs when reading contracts (`read_contract` tool with `abiJson` parameter)
233251
- The `fetch_and_analyze_abi` prompt
234252

235253
Get your free API key from:
254+
236255
- [Etherscan](https://etherscan.io/apis) - For Ethereum and compatible chains
237256
- The same key works across all 60+ EVM networks via the Etherscan v2 API
238257

@@ -298,6 +317,7 @@ To connect to the MCP server from Cursor:
298317
3. Scroll down to "MCP Servers" section
299318
4. Click "Add new MCP server"
300319
5. Enter the following details:
320+
301321
- Server name: `evm-mcp-server`
302322
- Type: `command`
303323
- Command: `npx @mcpdotdirect/evm-mcp-server`
@@ -315,18 +335,11 @@ For a more portable configuration that you can share with your team or use acros
315335
"mcpServers": {
316336
"evm-mcp-server": {
317337
"command": "npx",
318-
"args": [
319-
"-y",
320-
"@mcpdotdirect/evm-mcp-server"
321-
]
338+
"args": ["-y", "@mcpdotdirect/evm-mcp-server"]
322339
},
323340
"evm-mcp-http": {
324341
"command": "npx",
325-
"args": [
326-
"-y",
327-
"@mcpdotdirect/evm-mcp-server",
328-
"--http"
329-
]
342+
"args": ["-y", "@mcpdotdirect/evm-mcp-server", "--http"]
330343
}
331344
}
332345
}
@@ -353,11 +366,13 @@ If you're developing a web application and want to connect to the HTTP server wi
353366
```
354367

355368
This connects directly to the HTTP server's SSE endpoint, which is useful for:
369+
356370
- Web applications that need to connect to the MCP server from the browser
357371
- Environments where running local commands isn't ideal
358372
- Sharing a single MCP server instance among multiple users or applications
359373

360374
To use this configuration:
375+
361376
1. Create a `.cursor` directory in your project root if it doesn't exist
362377
2. Save the above JSON as `mcp.json` in the `.cursor` directory
363378
3. Restart Cursor or open your project
@@ -375,14 +390,14 @@ async function main() {
375390
try {
376391
// Get ETH balance for an address using ENS
377392
console.log("Getting ETH balance for vitalik.eth...");
378-
393+
379394
// When using with Cursor, you can simply ask Cursor to:
380395
// "Check the ETH balance of vitalik.eth on mainnet"
381396
// Or "Transfer 0.1 ETH from my wallet to vitalik.eth"
382-
383-
// Cursor will use the MCP server to execute these operations
397+
398+
// Cursor will use the MCP server to execute these operations
384399
// without requiring any additional code from you
385-
400+
386401
// This is the power of the MCP integration - your AI assistant
387402
// can directly interact with blockchain data and operations
388403
} catch (error) {
@@ -425,7 +440,7 @@ const mcp = new McpClient("http://localhost:3000");
425440
const result = await mcp.invokeTool("get-token-balance", {
426441
tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
427442
ownerAddress: "vitalik.eth", // ENS name instead of address
428-
network: "ethereum"
443+
network: "ethereum",
429444
});
430445

431446
console.log(result);
@@ -448,7 +463,7 @@ const mcp = new McpClient("http://localhost:3000");
448463

449464
const result = await mcp.invokeTool("resolve-ens", {
450465
ensName: "vitalik.eth",
451-
network: "ethereum"
466+
network: "ethereum",
452467
});
453468

454469
console.log(result);
@@ -460,100 +475,147 @@ console.log(result);
460475
// }
461476
```
462477

478+
### Example: Batch Multiple Calls with Multicall
479+
480+
```javascript
481+
// Example of using multicall to batch multiple contract reads in a single RPC call
482+
const mcp = new McpClient("http://localhost:3000");
483+
484+
const result = await mcp.invokeTool("multicall", {
485+
network: "ethereum",
486+
calls: [
487+
{
488+
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
489+
functionName: "balanceOf",
490+
args: ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"],
491+
},
492+
{
493+
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
494+
functionName: "symbol",
495+
},
496+
{
497+
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
498+
functionName: "decimals",
499+
},
500+
],
501+
});
502+
503+
console.log(result);
504+
// {
505+
// network: "ethereum",
506+
// totalCalls: 3,
507+
// successfulCalls: 3,
508+
// failedCalls: 0,
509+
// results: [
510+
// { contractAddress: "0xA0b...", functionName: "balanceOf", result: "1000000000", status: "success" },
511+
// { contractAddress: "0xA0b...", functionName: "symbol", result: "USDC", status: "success" },
512+
// { contractAddress: "0xA0b...", functionName: "decimals", result: "6", status: "success" }
513+
// ]
514+
// }
515+
```
516+
463517
## 📚 API Reference
464518

465519
### Tools
466520

467-
The server provides 22 focused MCP tools for agents. **All tools that accept address parameters support both Ethereum addresses and ENS names.**
521+
The server provides 25 focused MCP tools for agents. **All tools that accept address parameters support both Ethereum addresses and ENS names.**
468522

469523
#### Wallet Information
470524

471-
| Tool Name | Description | Key Parameters |
472-
|-----------|-------------|----------------|
473-
| `get_wallet_address` | Get the address of the configured wallet (from EVM_PRIVATE_KEY) | none |
525+
| Tool Name | Description | Key Parameters |
526+
| -------------------- | --------------------------------------------------------------- | -------------- |
527+
| `get_wallet_address` | Get the address of the configured wallet (from EVM_PRIVATE_KEY) | none |
474528

475529
#### Network Information
476530

477-
| Tool Name | Description | Key Parameters |
478-
|-----------|-------------|----------------|
479-
| `get_chain_info` | Get network information | `network` |
480-
| `get_supported_networks` | List all supported EVM networks | none |
481-
| `get_gas_price` | Get current gas prices on a network | `network` |
531+
| Tool Name | Description | Key Parameters |
532+
| ------------------------ | ----------------------------------- | -------------- |
533+
| `get_chain_info` | Get network information | `network` |
534+
| `get_supported_networks` | List all supported EVM networks | none |
535+
| `get_gas_price` | Get current gas prices on a network | `network` |
482536

483537
#### ENS Services
484538

485-
| Tool Name | Description | Key Parameters |
486-
|-----------|-------------|----------------|
487-
| `resolve_ens_name` | Resolve ENS name to address | `ensName`, `network` |
539+
| Tool Name | Description | Key Parameters |
540+
| -------------------- | ---------------------------------- | -------------------- |
541+
| `resolve_ens_name` | Resolve ENS name to address | `ensName`, `network` |
488542
| `lookup_ens_address` | Reverse lookup address to ENS name | `address`, `network` |
489543

490544
#### Block & Transaction Information
491545

492-
| Tool Name | Description | Key Parameters |
493-
|-----------|-------------|----------------|
494-
| `get_block` | Get block data | `blockNumber` or `blockHash`, `network` |
495-
| `get_latest_block` | Get latest block data | `network` |
496-
| `get_transaction` | Get transaction details | `txHash`, `network` |
497-
| `get_transaction_receipt` | Get transaction receipt with logs | `txHash`, `network` |
498-
| `wait_for_transaction` | Wait for transaction confirmation | `txHash`, `confirmations`, `network` |
546+
| Tool Name | Description | Key Parameters |
547+
| ------------------------- | --------------------------------- | --------------------------------------- |
548+
| `get_block` | Get block data | `blockNumber` or `blockHash`, `network` |
549+
| `get_latest_block` | Get latest block data | `network` |
550+
| `get_transaction` | Get transaction details | `txHash`, `network` |
551+
| `get_transaction_receipt` | Get transaction receipt with logs | `txHash`, `network` |
552+
| `wait_for_transaction` | Wait for transaction confirmation | `txHash`, `confirmations`, `network` |
499553

500554
#### Balance & Token Information
501555

502-
| Tool Name | Description | Key Parameters |
503-
|-----------|-------------|----------------|
504-
| `get_balance` | Get native token balance | `address` (address/ENS), `network` |
505-
| `get_token_balance` | Check ERC20 token balance | `tokenAddress` (address/ENS), `ownerAddress` (address/ENS), `network` |
506-
| `get_allowance` | Check token spending allowance | `tokenAddress` (address/ENS), `ownerAddress` (address/ENS), `spenderAddress` (address/ENS), `network` |
556+
| Tool Name | Description | Key Parameters |
557+
| ------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------- |
558+
| `get_balance` | Get native token balance | `address` (address/ENS), `network` |
559+
| `get_token_balance` | Check ERC20 token balance | `tokenAddress` (address/ENS), `ownerAddress` (address/ENS), `network` |
560+
| `get_allowance` | Check token spending allowance | `tokenAddress` (address/ENS), `ownerAddress` (address/ENS), `spenderAddress` (address/ENS), `network` |
507561

508562
#### Smart Contract Interactions
509563

510-
| Tool Name | Description | Key Parameters |
511-
|-----------|-------------|----------------|
512-
| `get_contract_abi` | Fetch contract ABI from block explorer (60+ networks) | `contractAddress` (address/ENS), `network` |
513-
| `read_contract` | Read smart contract state (auto-fetches ABI if needed) | `contractAddress`, `functionName`, `args[]`, `abiJson` (optional), `network` |
514-
| `write_contract` | Execute state-changing functions (auto-fetches ABI if needed) | `contractAddress`, `functionName`, `args[]`, `value` (optional), `abiJson` (optional), `network` |
564+
| Tool Name | Description | Key Parameters |
565+
| ------------------ | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
566+
| `get_contract_abi` | Fetch contract ABI from block explorer (60+ networks) | `contractAddress` (address/ENS), `network` |
567+
| `read_contract` | Read smart contract state (auto-fetches ABI if needed) | `contractAddress`, `functionName`, `args[]`, `abiJson` (optional), `network` |
568+
| `write_contract` | Execute state-changing functions (auto-fetches ABI if needed) | `contractAddress`, `functionName`, `args[]`, `value` (optional), `abiJson` (optional), `network` |
569+
| `multicall` | Batch multiple read calls into a single RPC request (uses Multicall3) | `calls[]` (array of contract calls), `allowFailure` (optional), `network` |
515570

516571
#### Token Transfers
517572

518-
| Tool Name | Description | Key Parameters |
519-
|-----------|-------------|----------------|
520-
| `transfer_native` | Send native tokens (ETH, etc.) | `to` (address/ENS), `amount`, `network` |
521-
| `transfer_erc20` | Transfer ERC20 tokens | `tokenAddress` (address/ENS), `to` (address/ENS), `amount`, `network` |
522-
| `approve_token_spending` | Approve token allowances | `tokenAddress` (address/ENS), `spenderAddress` (address/ENS), `amount`, `network` |
573+
| Tool Name | Description | Key Parameters |
574+
| ------------------------ | ------------------------------ | --------------------------------------------------------------------------------- |
575+
| `transfer_native` | Send native tokens (ETH, etc.) | `to` (address/ENS), `amount`, `network` |
576+
| `transfer_erc20` | Transfer ERC20 tokens | `tokenAddress` (address/ENS), `to` (address/ENS), `amount`, `network` |
577+
| `approve_token_spending` | Approve token allowances | `tokenAddress` (address/ENS), `spenderAddress` (address/ENS), `amount`, `network` |
523578

524579
#### NFT Services
525580

526-
| Tool Name | Description | Key Parameters |
527-
|-----------|-------------|----------------|
528-
| `get_nft_info` | Get NFT (ERC721) metadata | `tokenAddress` (address/ENS), `tokenId`, `network` |
529-
| `get_erc1155_balance` | Check ERC1155 balance | `tokenAddress` (address/ENS), `tokenId`, `ownerAddress` (address/ENS), `network` |
581+
| Tool Name | Description | Key Parameters |
582+
| --------------------- | ------------------------- | -------------------------------------------------------------------------------- |
583+
| `get_nft_info` | Get NFT (ERC721) metadata | `tokenAddress` (address/ENS), `tokenId`, `network` |
584+
| `get_erc1155_balance` | Check ERC1155 balance | `tokenAddress` (address/ENS), `tokenId`, `ownerAddress` (address/ENS), `network` |
585+
586+
#### Message Signing
587+
588+
| Tool Name | Description | Key Parameters |
589+
| ----------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------- |
590+
| `sign_message` | Sign arbitrary messages for authentication and verification (SIWE, off-chain signatures) | `message` |
591+
| `sign_typed_data` | Sign EIP-712 structured data for gasless transactions, permits, and meta-transactions | `domainJson`, `typesJson`, `primaryType`, `messageJson` |
530592

531593
### Resources
532594

533595
The server exposes blockchain data through the following MCP resource URIs. All resource URIs that accept addresses also support ENS names, which are automatically resolved to addresses.
534596

535597
#### Blockchain Resources
536598

537-
| Resource URI Pattern | Description |
538-
|-----------|-------------|
539-
| `evm://{network}/chain` | Chain information for a specific network |
540-
| `evm://chain` | Ethereum mainnet chain information |
541-
| `evm://{network}/block/{blockNumber}` | Block data by number |
542-
| `evm://{network}/block/latest` | Latest block data |
543-
| `evm://{network}/address/{address}/balance` | Native token balance |
544-
| `evm://{network}/tx/{txHash}` | Transaction details |
545-
| `evm://{network}/tx/{txHash}/receipt` | Transaction receipt with logs |
599+
| Resource URI Pattern | Description |
600+
| ------------------------------------------- | ---------------------------------------- |
601+
| `evm://{network}/chain` | Chain information for a specific network |
602+
| `evm://chain` | Ethereum mainnet chain information |
603+
| `evm://{network}/block/{blockNumber}` | Block data by number |
604+
| `evm://{network}/block/latest` | Latest block data |
605+
| `evm://{network}/address/{address}/balance` | Native token balance |
606+
| `evm://{network}/tx/{txHash}` | Transaction details |
607+
| `evm://{network}/tx/{txHash}/receipt` | Transaction receipt with logs |
546608

547609
#### Token Resources
548610

549-
| Resource URI Pattern | Description |
550-
|-----------|-------------|
551-
| `evm://{network}/token/{tokenAddress}` | ERC20 token information |
552-
| `evm://{network}/token/{tokenAddress}/balanceOf/{address}` | ERC20 token balance |
553-
| `evm://{network}/nft/{tokenAddress}/{tokenId}` | NFT (ERC721) token information |
554-
| `evm://{network}/nft/{tokenAddress}/{tokenId}/isOwnedBy/{address}` | NFT ownership verification |
555-
| `evm://{network}/erc1155/{tokenAddress}/{tokenId}/uri` | ERC1155 token URI |
556-
| `evm://{network}/erc1155/{tokenAddress}/{tokenId}/balanceOf/{address}` | ERC1155 token balance |
611+
| Resource URI Pattern | Description |
612+
| ---------------------------------------------------------------------- | ------------------------------ |
613+
| `evm://{network}/token/{tokenAddress}` | ERC20 token information |
614+
| `evm://{network}/token/{tokenAddress}/balanceOf/{address}` | ERC20 token balance |
615+
| `evm://{network}/nft/{tokenAddress}/{tokenId}` | NFT (ERC721) token information |
616+
| `evm://{network}/nft/{tokenAddress}/{tokenId}/isOwnedBy/{address}` | NFT ownership verification |
617+
| `evm://{network}/erc1155/{tokenAddress}/{tokenId}/uri` | ERC1155 token URI |
618+
| `evm://{network}/erc1155/{tokenAddress}/{tokenId}/balanceOf/{address}` | ERC1155 token balance |
557619

558620
## 🔒 Security Considerations
559621

0 commit comments

Comments
 (0)