evm-agent-toolkit
The EVM Agent Toolkit MCP server provides autonomous agents with deterministic, schema-validated tools for EVM smart contract development, turning noisy CLI output into clean, reliable JSON.
Security Scanning (
evm_scan_vulnerabilities): Run Slither static analysis to detect severity-rated vulnerabilities (High/Medium/Low/Informational) with code snippets, line numbers, and source file references. Supports filtering by severity.Gas Profiling (
evm_analyze_gas_profile): Runforge test --gas-reportto get structured per-contract and per-function gas consumption data including min, max, average, median, and call counts.Compiler Diagnostics (
evm_compile_and_diagnose): Runforge buildand receive structured diagnostics on failure — including file, line/column numbers, error messages, and code snippets.Transaction Simulation (
evm_simulate_transaction): Simulate read-onlyeth_calltransactions against an EVM node usingcast call, returning decoded return data or revert reasons without submitting a real transaction.Storage Layout Inspection (
evm_inspect_storage_layout): Inspect contract storage slot assignments (slot index, byte offset, type, size) — essential for proxy upgrade safety and storage collision checks.Call Tracing (
evm_trace_call): Execute a call withcast call --traceand get a full structured call tree with gas costs, call types (staticcall, delegatecall), emitted events, and revert frames.Calldata Decoding (
evm_decode_calldata): Decode hex calldata into function signatures and typed argument values — offline with a known signature, or via the 4byte selector database for unknown ones.Test Running (
evm_run_tests): Runforge testwith optional filters and get per-suite, per-test results including fuzz run counts, gas usage, and exact counterexample calldata for failing fuzz/invariant tests.Toolchain Version Check (
evm_toolchain_versions): Report installed status and exact versions ofslither,forge, andcast— useful for verifying prerequisites before an analysis session.Skill Workflows (Prompts): Execute pre-defined workflows for contract auditing, gas optimization, and arbitrage analysis.
EVM MCP Server
An MCP (Model Context Protocol) server that gives autonomous coding agents deterministic, schema-validated tools for EVM smart contract development — security scanning, gas profiling, compiler diagnostics, and transaction simulation.
Why This Exists
Raw CLI output from tools like Slither and Foundry is noisy, non-deterministic, and often causes LLMs to hallucinate. This server intercepts the output, validates it through Zod schemas, and returns clean JSON that any agent can reliably parse.
Related MCP server: EVM Proxy MCP
Tools
Tool | Annotations | Description |
|
| Run Slither analysis. Returns severity-rated findings with extracted code snippets. Supports |
|
| Run |
|
| Run |
|
| Run |
|
| Run |
|
| Run |
|
| Decode hex calldata via |
|
| Run |
|
| Report installed/missing status and exact versions of |
Resources
URI | Description |
| Security vulnerability pattern library |
| Gas optimization pattern library |
| Arbitrage strategy reference |
Prompts
Skill workflows exposed as MCP prompts for clients without native skill support. Each embeds the full SKILL.md workflow.
Prompt | Args | Description |
|
| Severity-rated security audit (vulnerability-scanning workflow) |
|
| Measured gas-optimization pass (gas-optimization workflow) |
|
| Opportunity ledger net of fees/gas/slippage (arbitrage-analysis workflow) |
Architecture
evm-agent-toolkit/
├── src/
│ ├── mcp/ # MCP server entry point (stdio transport)
│ ├── tools/ # Zod-validated CLI output parsers
│ │ ├── slither.ts # Slither JSON → SanitizedFinding[]
│ │ ├── forge.ts # Forge gas tables → ContractGas[]
│ │ ├── compiler.ts # Forge build errors → CompilerDiagnostic[]
│ │ ├── simulator.ts# Cast call output → SimulatorDiagnostic
│ │ ├── storage.ts # Forge storage layout → StorageEntry[]
│ │ ├── trace.ts # Cast call traces → TraceEvent[]
│ │ ├── decoder.ts # Cast calldata decode → DecodedCalldata
│ │ ├── testrunner.ts # Forge test output → TestSuite[]
│ │ └── versions.ts # Toolchain --version output → ToolVersion
│ ├── rules/ # Agent system prompt injections
│ └── hooks/ # Lifecycle hooks (UserPromptSubmit, Statusline)
├── tests/ # Vitest unit tests for all parsers
├── bench/ # Performance benchmarks
├── evals/ # Agent evaluation framework (vulnerable contracts + eval XML)
├── skills/ # Markdown reference libraries
├── .claude-plugin/ # Claude Code plugin manifest
└── gemini-extension.json # Antigravity plugin manifestSetup
npm install
npm run buildAgent Configuration
This is a stdio MCP server. It is spawned by the MCP client, not started manually.
Claude Desktop / Cursor:
{
"mcpServers": {
"evm-agent-toolkit": {
"command": "npx",
"args": ["-y", "@0xendale/evm-agent-toolkit"]
}
}
}Prerequisites: slither, forge, and cast must be installed on the host machine.
Development
npm run dev # Watch mode with tsx
npm run test # Run all unit tests
npm run bench # Run parser benchmarks
npm run build # Compile TypeScript → build/Performance
Parser throughput (measured on Apple Silicon):
Parser | Iterations | Time | Per-call |
Slither (100 detectors) | 1,000 | ~109ms | ~0.1ms |
Forge Gas Table | 10,000 | ~32ms | ~0.003ms |
License
MIT
Available Tools
9 toolsevm_analyze_gas_profileAnalyze EVM Gas ProfileARead-onlyIdempotent
Run forge test --gas-report and return structured gas consumption data per contract and function.
Args:
projectPath (string): Absolute path to a Foundry project (must contain foundry.toml)
Returns: JSON object: { "contracts": [ { "name": string, // e.g. "src/Token.sol:Token" "deploymentCost": number, // Gas used for deployment "deploymentSize": number, // Bytecode size in bytes "functions": [ { "name": string, // Function name "min": number, // Minimum gas "avg": number, // Average gas "median": number, // Median gas "max": number, // Maximum gas "calls": number // Number of calls in tests } ] } ] }
Examples:
"Show gas usage for my project" → projectPath = "/path/to/foundry-project"
Do NOT use for security auditing (use evm_scan_vulnerabilities instead)
Error Handling:
Returns isError=true if Foundry is not installed or tests fail to compile
Inputs: projectPath (required). Returns: contracts
evm_compile_and_diagnoseCompile & Diagnose SolidityARead-onlyIdempotent
Run forge build and return structured compiler diagnostics.
If compilation succeeds, returns { "success": true, "diagnostics": [] }. If compilation fails, parses the error output into a JSON array of diagnostics.
Args:
projectPath (string): Absolute path to the Foundry project
Returns: { "success": boolean, // true if the project compiled cleanly "diagnostics": [ { "file": string, // e.g. "src/Token.sol" "line": number, // Line number (1-indexed) "column": number, // Column number (1-indexed) "message": string, // Compiler error message "snippet": string // Code snippet around the error } ] }
Examples:
"Check if my contracts compile" → projectPath = "/path/to/project"
"Fix the compilation error" → call this tool, read the diagnostics, fix the file
Error Handling:
Returns isError=true if forge is not installed
Inputs: projectPath (required). Returns: success, diagnostics
evm_decode_calldataDecode EVM CalldataARead-onlyIdempotent
Decode hex calldata into a function signature and typed argument values using Foundry cast.
If you know the function signature, pass it for a fully offline, deterministic decode (cast calldata-decode). Without a signature, the 4-byte selector is resolved via the openchain.xyz signature database (cast 4byte-decode) — requires network access.
Args:
calldata (string): Hex-encoded calldata (0x-prefixed, at least the 4-byte selector)
signature (string, optional): Known function signature, e.g. "transfer(address,uint256)"
Returns: JSON object: { "success": boolean, "signature": string, // Resolved or provided function signature "values": string[] // Decoded argument values, one per parameter }
Examples:
"What does this pending tx do?" → calldata = "0xa9059cbb000...", no signature
"Decode this transfer call" → calldata + signature = "transfer(address,uint256)"
Error Handling:
Returns isError=true if cast is not installed, the calldata is malformed, or the selector is unknown
Inputs: calldata (required), signature. Returns: values, success, signature
evm_inspect_storage_layoutInspect Contract Storage LayoutARead-onlyIdempotent
Run forge inspect storage-layout and return the resolved storage slot assignment for every state variable.
Essential for proxy-upgrade safety checks (storage-layout collisions) and storage-packing gas analysis.
Args:
projectPath (string): Absolute path to the Foundry project root
contractName (string): Contract name (e.g. "Token") or fully qualified name (e.g. "src/Token.sol:Token")
Returns: JSON object: { "entries": [ { "label": string, // State variable name "slot": number, // Storage slot index "offset": number, // Byte offset within the slot "type": string, // Human-readable type (e.g. "address", "mapping(address => uint256)") "bytes": number // Size of the variable in bytes } ] }
Examples:
"Check storage layout of my proxy implementation" → contractName = "TokenV2"
"Will upgrading V1 to V2 corrupt storage?" → call once per contract, compare entries
Error Handling:
Returns isError=true if forge is not installed, the project path is invalid, or the contract is not found
Inputs: projectPath (required), contractName (required). Returns: entries
evm_run_testsRun Foundry TestsARead-only
Run forge test and return structured per-suite, per-test results — including fuzz runs and the exact counterexample calldata for failing fuzz/invariant tests.
Use this to verify behavior equivalence after a rewrite, run invariant suites, or drive a Generate-Repair-Execute proof-of-concept loop.
Args:
projectPath (string): Absolute path to the Foundry project root
matchTest (string, optional): Only run test functions matching this regex (forge --match-test)
matchPath (string, optional): Only run test files matching this glob (forge --match-path)
Returns: JSON object: { "allPassed": boolean, "totalPassed": number, "totalFailed": number, "totalSkipped": number, "suites": [ { "name": string, // e.g. "test/Vault.t.sol:VaultTest" "passed": number, "failed": number, "skipped": number, "tests": [ { "name": string, // e.g. "testFuzz_withdraw(uint256)" "status": string, // "pass" | "fail" | "skip" "reason": string, // Failure reason (on fail) "counterexample": string, // Fuzz counterexample calldata + args (on fuzz fail) "gas": number, // Gas for unit tests "fuzzRuns": number, // Runs for fuzz/invariant tests "medianGas": number // Median gas for fuzz tests } ] } ] }
Examples:
"Do my invariant tests still hold?" → matchTest = "invariant"
"Verify the refactor didn't break Vault" → matchPath = "test/Vault.t.sol"
Error Handling:
Returns isError=true if forge is not installed, the path is invalid, or compilation fails (use evm_compile_and_diagnose for compiler errors)
Inputs: projectPath (required), matchPath, matchTest. Returns: suites, allPassed, totalFailed, totalPassed, +1 more
evm_scan_vulnerabilitiesScan EVM VulnerabilitiesARead-onlyIdempotent
Run Slither static analysis on a Solidity contract and return schema-validated vulnerability findings.
Each finding includes the detector name, severity, description, source file, line numbers, and the actual code snippet extracted from the file system.
Args:
contractPath (string): Absolute path to the Solidity file or Foundry project root
severityFilter (string[], optional): Only return findings at these severities ("High" | "Medium" | "Low" | "Informational")
maxFindings (number, optional): Cap the number of findings returned (default: all)
detectors (string[], optional): Run only these Slither detector ids (e.g. ["reentrancy-eth", "arbitrary-send-eth"]) for a focused scan
Returns: JSON object: { "findings": [ { "check": string, // Slither detector id (e.g. "reentrancy-eth") "severity": string, // "High" | "Medium" | "Low" | "Informational" "description": string, // Human-readable explanation "file": string, // Relative path to the source file "lines": number[], // Affected line numbers (1-indexed) "code_snippet": string // Extracted source code from the file } ], "totalFindings": number, // Total before truncation/capping "truncated": boolean // true if findings were dropped to fit the response limit }
Examples:
"Audit src/Vault.sol for reentrancy" → contractPath = "/path/to/src/Vault.sol"
"Run security scan on my Foundry project" → contractPath = "/path/to/project"
"Only high-severity issues" → severityFilter = ["High"]
Do NOT use for gas analysis (use evm_analyze_gas_profile instead)
Error Handling:
Returns isError=true if the path does not exist or Slither is not installed/crashes
Returns empty findings array if no vulnerabilities found
Inputs: contractPath (required), detectors, maxFindings, severityFilter. Returns: findings, truncated, totalFindings
evm_simulate_transactionSimulate EVM TransactionARead-onlyIdempotent
Execute a read-only call against an EVM node using Foundry cast and return decoded results or revert reasons.
This tool does NOT submit a real transaction; it simulates via eth_call.
Args:
target (string): Target contract address (0x-prefixed, 42 chars)
signature (string): Function signature, e.g. "balanceOf(address)"
args (string, optional): Space-separated arguments for the function call
rpcUrl (string): JSON-RPC endpoint URL (e.g. http://localhost:8545)
Returns: { "success": boolean, "returnData": string, // Hex-encoded return data (on success) "revertReason": string, // Decoded revert string (on failure) "error": string // Raw error message (on execution failure) }
Examples:
"Check the balance of 0xabc..." → target=contract, signature="balanceOf(address)", args="0xabc..."
"Call the owner() function" → target=contract, signature="owner()", rpcUrl="http://localhost:8545"
Error Handling:
Returns { success: false, revertReason } if the call reverts
Returns { success: false, error } if cast is not installed or RPC is unreachable
Inputs: rpcUrl (required), target (required), signature (required), args. Returns: error, success, returnData, revertReason
evm_toolchain_versionsEVM Toolchain VersionsARead-onlyIdempotent
Report which host toolchain binaries (slither, forge, cast) are installed and their exact versions.
Call this once before an analysis session to (a) verify prerequisites and (b) record versions so findings are reproducible — Slither detector sets and forge gas accounting change between releases.
Args: none
Returns: JSON object: { "tools": [ { "tool": string, // "slither" | "forge" | "cast" "installed": boolean, "version": string // First line of --version output (when installed) } ] }
Error Handling:
Never errors; missing binaries are reported as installed: false
Inputs: no named parameters. Returns: tools
evm_trace_callTrace EVM CallARead-onlyIdempotent
Execute a read-only call with cast call --trace and return the structured call tree: every internal call, its gas cost, call type, return values, emitted events, and revert frames.
Use this to verify exploit reachability, inspect cross-contract call flows, or debug unexpected reverts. This tool does NOT submit a real transaction.
Args:
target (string): Target contract address (0x-prefixed, 42 chars)
signature (string): Function signature, e.g. "withdraw(uint256)"
args (string, optional): Space-separated arguments for the function call
rpcUrl (string): JSON-RPC endpoint URL (e.g. http://localhost:8545)
Returns: JSON object: { "reverted": boolean, // true if any frame reverted "gasUsed": number, // Total gas used (when reported) "events": [ { "depth": number, // Nesting depth in the call tree (0 = top frame) "kind": string, // "call" | "return" | "stop" | "revert" | "emit" "gas": number, // Gas for call frames "target": string, // Callee address or label "call": string, // Function + arguments "callType": string, // "staticcall" | "delegatecall" | undefined (regular call) "value": string // Return data, revert reason, or event payload } ] }
Examples:
"Why does withdraw() revert?" → trace it, read the deepest revert frame
"Does transfer() call an external contract?" → look for depth > 0 call events
Error Handling:
Returns isError=true if cast is not installed, the RPC is unreachable, or no trace was produced
Inputs: rpcUrl (required), target (required), signature (required), args. Returns: events, gasUsed, reverted
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
All 9 tools have clearly distinct purposes: gas analysis, compilation, calldata decoding, storage layout, testing, vulnerability scanning, simulation, toolchain versions, and tracing. No two tools overlap in functionality.
All tools follow a consistent 'evm_verb_noun' pattern (e.g., evm_analyze_gas_profile, evm_compile_and_diagnose). The naming is uniform and predictable, with no mixing of conventions.
With 9 tools, the set is well-scoped for an EVM development and security toolkit. Each tool addresses a specific, essential task without being too few or too many.
The tool set covers the full lifecycle of EVM contract analysis: compilation, testing, gas profiling, security scanning, simulation, tracing, calldata decoding, storage inspection, and version checking. No obvious gaps for its intended purpose.
Maintenance
Related MCP Connectors
Self-hosted MCP server: 26 deterministic dev, security, and EVM tools.
The OpenZeppelin Solidity Contracts MCP server integrates OpenZeppelin's security and style rules into AI-driven development workflows, enabling AI assistants to generate safe, correct, and production-ready smart contracts. It automatically validates generated code against OpenZeppelin standards (including imports, modifiers, naming conventions, and security checks) and supports various contract types including ERC-20, ERC-721, ERC-1155, Stablecoins, RWA, Governor, and Account contracts through prompt-driven workflows.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server providing 80+ tools for Foundry Ethereum development, enabling AI assistants to compile, test, deploy smart contracts, interact with EVM chains, and manage local nodes via Forge, Cast, Anvil, and Chisel.7 npm2MIT
- AlicenseNot gradedqualityDmaintenanceMCP server providing AI assistants with tools for advanced EVM smart contract analysis, including proxy detection, implementation resolution, and security analysis.1MIT
- AlicenseCqualityDmaintenanceA security-first MCP server that provides LLMs with structured tools for filesystem, process, search, build/test/lint, IDE integration, and more.402PolyForm Noncommercial 1.0.0
- AlicenseNot gradedqualityCmaintenanceLocal-first MCP server that provides project context, verification gates, and structured tools for coding agents to discover knowledge, run diagnostics, and execute allowlisted commands within a repository.41 npmMIT