ethui agentic wallet

ethui, the first developer wallet and toolkit agents can safely drive

ethui agentic wallet

Created At

ETHGlobal Lisbon 2026

Project Description

ethui is an open-source, desktop-native Ethereum developer toolkit built in Rust and Tauri. It is a full developer wallet: it manages real keys (HD/mnemonic, keystore files, Ledger, and impersonated accounts), keeps anvil-aware state syncing that survives chain restarts and reverts, picks up Foundry and Hardhat build artifacts from the filesystem and matches them against on-chain bytecode, decodes contracts in a built-in explorer, and simulates transactions before they are sent. ethui Stacks is the companion cloud service: private, persistent Anvil testnets in one click, each with its own chain ID and authenticated RPC URL, shareable with a team and requiring nothing to run locally.

At this hackathon we built MCP (Model Context Protocol) servers for both, so any AI agent (Claude, Codex, Cursor, or any MCP client) can drive them programmatically.

The problem: to test a dApp end to end, an agent needs a wallet it can operate. Today's options either mock the wallet, which fakes signatures and does not reflect what the chain would actually do, or drive a browser-extension harness, which is brittle and has no agent loop. There is no real wallet an agent can drive. Because ethui is already a full wallet, exposing it over MCP means the agent operates the real wallet against a real chain, producing real signatures, the same wallet the developer already uses.

ethui-mcp (desktop) is a Rust stdio server that connects an agent to the running ethui desktop app over the same WebSocket JSON-RPC channel the browser extension uses. Through it, an agent can read chain state, accounts, balances, transactions and contract ABIs, run eth_call, create and switch wallets and networks, and submit write transactions via a generic RPC passthrough. The server holds no keys and never signs; every write goes through ethui's normal handler, with the agent showing up as the request origin, so the human stays in the loop exactly where they already are. Paired with a browser the agent drives itself, this closes the end-to-end loop: connect the wallet, trigger a transaction, then approve, reject, or resend it.

ethui-stacks-mcp (hosted) exposes Stacks over MCP. An agent can create, list and delete testnets, mine blocks, take snapshots and revert them, set balances and block timestamps, impersonate accounts, read blocks, logs and transactions, and simulate calls, entirely in the cloud with no local setup.

By allowing both the wallet and stacks to be connected over MCP, we enable use cases such as testing an entire deposit flow end to end, from the actual UI by simulating precisely the flow a user takes. The agent opens the dApp in a browser, connects ethui, triggers the deposit and reads the simulated balance against a local anvil node.

We also enable AI assisted debugging where we can ask to reproduce a bug entirely from mainnet. The agent spins up a stacks from a forked mainnet, impersonates the account, replays the failing transaction and reports the revert reason, without having a human in the loop.

This is also useful to figure out what an undocumented contract does. The agent pulls the ABI through ethui, calls read functions, sends probe transactions on a throwaway stack, and returns a summary.

The result is ethui becomes a developer wallet an agent can actually drive, locally or in the cloud. dApp end-to-end testing stops being a mock and becomes an agent operating a real wallet against a real chain.

How it's Made

Two MCP servers, deliberately opposite in architecture, because the two things they wrap are opposite.

DESKTOP: ethui-mcp (Rust, stdio, local)

A new Rust crate inside the ethui workspace (crates/mcp), shipping a ethui-mcp stdio binary. Built on rmcp (the official Rust MCP SDK) with the server, macros and transport-io features, plus schemars for tool argument schemas. rmcp is pinned to an exact version — it is pre-release and its API moves between betas.

The key design decision was to add no new privileged surface to ethui. The server talks to the running desktop app over the WebSocket JSON-RPC port the browser extension already uses (9102 on dev builds, 9002 on release, overridable via ETHUI_WS_PORT), connecting as a peer identified mcp://claude with origin claude-mcp. That means the agent is just another dApp as far as ethui is concerned: every write goes through ethui's normal handler and opens the same approval dialog, with the agent's origin shown on it. The MCP server holds no keys and never signs. Approvals are bypassed only under Fast Mode, which requires a dev wallet on a dev network and the setting explicitly enabled.

The transport layer (ws.rs, ~850 lines with tests) is tokio-tungstenite with JSON-RPC id correlation:

The pending-request map belongs to the connection, not the backend. A reconnect therefore cannot disturb requests issued on the new socket — each socket only ever fails the requests it owns.

Registration and cleanup are joined in one Drop impl (PendingGuard), so normal completion, send failure, internal timeout and caller cancellation (an outer select!, timeout, or task abort) all deregister through the same path. No pending-request leaks.

Timeouts are sized for a human, not a machine: 120s response timeout, because the thing on the other end of a write is a person reading an approval dialog. Connect timeout is a separate 5s, so one hung connect attempt can't block every concurrent tool call for the full two minutes.

Uncorrelatable frames are logged, not silently dropped — ethui's event notifications and its "id": null parse-error response both arrive on the same socket, and a wedged call that times out because ethui actually answered instantly is much easier to debug with a trace left behind.

The local auth token is read on every connect, not at construction. An MCP client starts this process whenever it likes — quite possibly before ethui is running — and a token read once at startup would be missing forever. Reading per connect means the first reconnect after the app starts picks it up. Without a token it still works; it just sees the method surface a web page would.

The tool surface is a curated set of typed tools over the raw RPC: reads that nevhain, get_accounts, get_balance, get_transaction, call, get_contract_abi,resolve_alias), state changes (switch_network, create_wallet, list_wallets, set_current_wallet, set_current_path, set_fast_mode), and rpc_call as a generic passthrough escape hatch for anything else the app serves, including eth_sendTransaction and the signing metho For discovery we added a new ethui_rpcMethods method to the ethui-rpc crate, retustry from the running app. list_rpc_methods joins those live names against astatic catalog of parameter shapes and read/write labels, so the agent sees what this instance actually serves rather than what the docs assume — and when ethui is unreachable it falls backto the catalog and says explicitly that it did. A theme worth calling out: some amount of the work went into tool descriptions beius, because an agent reads them as its only source of truth. switch_networkstates that it is not confined to the MCP session. set_current_wallet states that it changes the signer for the desktop app and every connected dApp. create_wallet states that key material for plaintext/HD/privateKey/keystore wallets passes through the conversation, andr or Ledger unless a real signer is needed. set_fast_mode states that enabling itremoves the human confirmation step, and to confirm with the human first.

STACKS: ethui-stacks (Elixir, streamable HTTP, hosted)
Stacks is a Phoenix/Elixir app that supervises anvil processes. We started the MCP server as a separate TypeScript stdio package hitting the REST API, then threw iinside the Phoenix server — the stack registry, ownership model and auth already very agent to run a local sidecar just to reach a hosted service is backwards. The final version is a remote server: anubis_mcp (Anubis.Server with one component module per tool), served over streamable HTTP by forwarding /mcp on the api host to Anubis.Server.Transport.StreamableHTTP.Plug. Its router pipeline deliberately decMCP clients negotiate application/json and text/event-stream on the same path.

Auth reuses the REST API's bearer JWT, pulled off the headers carried on the MCP ed per tool call, and a stack the caller does not own reads back as "stack notfound" rather than "forbidden" — otherwise the error message leaks the existence of other users' slugs. Self-hosted instances running without ETHUI_STACKS_SAAS disable auth entirely, so the header can be dropped locally.

The chain client talks to the process-local anvil port rather than the public prolve no API key and no round trip back through the reverse proxy. It alsohand-decodes the standard Error(string) revert payload (selector 08c379a0) out of the JSON-RPC error data, so a failing call reports "execution reverted: insufficient balance" instead of an opaque error, with no contract ABI required.

Tools cover lifecycle (create_stack, list_stacks, delete_stack), chain reads (getet_address, get_logs), simulate_call and execute, and the anvil cheatcodes(impersonate, set_balance, mine, set_block_timestamp, snapshot, revert) over raw anvil_/evm_ RPC. create_stack takes fork_url and fork_block_number, so "fork mainnet at block N" is one call; it generates a mcp--prefixed random slug when none is given, surfaces per-us as readable messages, and deletes the row if the anvil boot fails, since the row is committed before the process starts and a failed boot would otherwise burn both a slug and a quota slot. execute takes raw calldata and an arbitrary from address, which it impersonates automatically via anvil_impersonateAccount — no private key anywhere in the flow pt and returns status, gas, logs and a link.

The nicest small detail: every tool that returns chain data also returns an ethuixplorer takes its target RPC url base64-encoded in the path, and the stack's APIkey is already inside that url — so the agent hands back a plain https link that the human can click and land on an authenticated explorer for that specific sandbox, with no setup. It is the cheapest possible handoff from agent output to human inspection.

Tests cover the tools, the transport end to end, the chain client (including revert decoding) and explorer linker builder

background image mobile

Join the mailing list

Get the latest news and updates

ethui agentic wallet | ETHGlobal