Agentic refactoring and full MCP support#1502
Open
gustavo-grieco wants to merge 65 commits into
Open
Conversation
This was referenced Dec 18, 2025
datradito
added a commit
to datradito/echidna-mcp
that referenced
this pull request
Mar 18, 2026
The clean PR branch is based on upstream/dev-agents (PR crytic#1502) which uses the '--server' flag name. Documentation was written for the development branch which used '--mcp-port', causing inconsistency. Changes: - AGENT_TESTING_GUIDE.md: Update all command examples - test-mcp-client.py: Fix error message - examples/README.md: Update all 3 command examples - examples/simple_agent.py: Fix error message - examples/langgraph_agent.py: Fix error message - tests/mcp/conftest.py: Fix pytest fixture command - .gitignore: Add Python cache patterns This ensures documentation matches the actual upstream implementation.
datradito
added a commit
to datradito/echidna-mcp
that referenced
this pull request
Mar 18, 2026
- Update examples/README.md to list correct 7 tools - Fix mcp_client_wrapper.py to use upstream tool names: * inject_fuzz_transactions (not inject_transaction) * clear_fuzz_priorities (not clear_priorities) * status, target, show_coverage, reload_corpus, dump_lcov - Mark old test files as skipped (use old tool names): * test_corpus.py - get_corpus_size, inspect_corpus, find_transaction * test_injection.py - inject_transaction (old signature) * test_prioritization.py - prioritize_function * test_read_logs.py - read_logs (commented out in upstream) - Update docstring: 7 active tools (not 9) These tests are preserved for reference but skipped until updated to match upstream API from PR crytic#1502.
datradito
added a commit
to datradito/echidna-mcp
that referenced
this pull request
Mar 18, 2026
The clean PR branch is based on upstream/dev-agents (PR crytic#1502) which uses the '--server' flag name. Documentation was written for the development branch which used '--mcp-port', causing inconsistency. Changes: - AGENT_TESTING_GUIDE.md: Update all command examples - test-mcp-client.py: Fix error message - examples/README.md: Update all 3 command examples - examples/simple_agent.py: Fix error message - examples/langgraph_agent.py: Fix error message - tests/mcp/conftest.py: Fix pytest fixture command - .gitignore: Add Python cache patterns This ensures documentation matches the actual upstream implementation.
datradito
added a commit
to datradito/echidna-mcp
that referenced
this pull request
Mar 18, 2026
- Update examples/README.md to list correct 7 tools - Fix mcp_client_wrapper.py to use upstream tool names: * inject_fuzz_transactions (not inject_transaction) * clear_fuzz_priorities (not clear_priorities) * status, target, show_coverage, reload_corpus, dump_lcov - Mark old test files as skipped (use old tool names): * test_corpus.py - get_corpus_size, inspect_corpus, find_transaction * test_injection.py - inject_transaction (old signature) * test_prioritization.py - prioritize_function * test_read_logs.py - read_logs (commented out in upstream) - Update docstring: 7 active tools (not 9) These tests are preserved for reference but skipped until updated to match upstream API from PR crytic#1502.
Vendors the out-of-process MCP test harness, example LangGraph/Claude agent, test contracts, and CI workflow authored by Dani Tradito (@datradito) in #1509, as the base for a robust external MCP testing strategy on this branch (protocol-conformance + Claude/Codex client simulation are layered on top in follow-up commits). Source: #1509 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Layers an out-of-process protocol-conformance and client-compatibility suite on top of the integration scaffolding vendored from #1509: - conftest.py: one session-scoped Echidna+MCP server shared by all modules (honors ECHIDNA_MCP_URL to target an already-running server) - _mcp_client.py: dependency-light wire-level JSON-RPC/HTTP helpers - test_mcp_conformance.py: asserts the transport guarantees strict clients need (notification -> 202 empty body, GET SSE -> 405, handshake, error codes) - test_mcp_codex.py: replays Codex's strict rmcp handshake - test_mcp_claude.py: drives the server with the official `mcp` SDK (Claude) - test_mcp.py: refactored to share the conftest fixture (originally @datradito) - mcp-tests.yml: CI runs the full suite (tools + conformance + Claude + Codex) Verified end-to-end: 12/12 pass against the current (fixed) server; against the pre-fix haskell-mcp-server (9fd60af) the conformance + Codex tests fail on the `200 {}` notification (the bug that broke Codex) while the lenient Claude SDK passes -- which is exactly why the strict conformance/Codex layer is needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses the CodeQL 'workflow does not contain permissions' alert on #1502: the job only checks out the repo and runs tests, so restrict GITHUB_TOKEN to contents: read. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The MCP job was building echidna from source (cold 'nix build .#echidna', no cache), taking 30-60 min and never reaching the test steps. Mirror the repo's other Nix jobs: install via DeterminateSystems and pull prebuilt closures from the trailofbits Cachix, so the build takes minutes. Add a concurrency group so a new push cancels the previous in-flight run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The job had the echidna binary and Python but not crytic-compile/solc, so
echidna exited immediately ('crytic-compile not installed') and every MCP test
errored in the fixture. Install crytic-compile + solc-select and select solc
0.8.25 for the test contract.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The nix build pinned the pre-fix haskell-mcp-server (9fd60af), so the nix-built echidna (CI, docker, releases) shipped the codex-incompatible MCP transport even though stack.yaml was updated. Point the flake at the fixed commit too. sha256 placeholder is corrected in the follow-up once CI reports it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branch contains a rewrite of some core features of Echidna to transform workers into agents, which can receive commands and collaborate with each other. It also allows to easily add MCP commands to query and guide the fuzzing campaign.
Commands
This code is still a work in progress but it can already tested with the few command implemented:
status(): Show fuzzing campaign statustarget(): Show the name and the ABI of the target contractreload_corpus(): Reload the transactions from the corpus, but without replay themdump_lcov(): Dump coverage in LCOV format"inject_fuzz_transactions(string): Inject a sequence of transaction to fuzz with optional concrete arguments (e.g.f(1, ?, 3) ; g(?, -1))inject_symb_transaction(string): Inject a single of transaction to explore using symbolic execution with optional concrete arguments (e.g.f(1, ?, 3))clear_fuzz_priorities(): Clear the function prioritization list used in fuzzingread_logs(): Read the last 100 log messages [disabled in the current code, perhaps not necessary]show_coverage(string): Show coverage report for a particular contractavoid_function(string): Exclude a transaction from the list of randomly generated transactionsAll these commands are subject to change, and there will be an experimentation phase where we will challenge the agents to increase the coverage (or break properties) using different commands
There are some additional changes in the logs to convey useful information for the agent, in particular, when new coverage is found:
How to test this PR
echidnaexecutable from our CI tests.--format text) for this test. Append the--server 3000to your command line to start the MCP server in the port 3000..vscode/mcp.jsonfile with the following content:{ "servers": { "Echidna fuzzing campaign": { "type": "http", "url": "http://localhost:3000/mcp" } } }Once you save the file, you will be able to click on the "Run" button next the server name to make sure the it is detected by Copilot. It should list the number of commands available (currently 7).
5. Everything should be ready to go, open the Chat window (Cmd + Shift + P and write
/chat) and start prompting. My recommended option to quickly start: