Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MUTX Documentation

MUTX is an authority layer for crypto wallets used by AI agents. It lets agents do real wallet work — check balances, send funds, swap, manage tokens — without giving them your private keys.

Authorization is granular and time-bounded: you approve a typed policy (a Short Lived Key) up front, and the agent then operates autonomously inside the bounds you set — per-capability scopes, per-tx caps, total budgets, recipient whitelists, rate limits, and an expiry — until the SLK expires, exhausts its budget, or you revoke it.

Supported chains

  • Solana (mainnet, devnet, testnet)
  • Ethereum (mainnet, sepolia)
  • Polygon (mainnet, amoy)
  • Base (mainnet, sepolia)
  • Arbitrum One (mainnet, sepolia)
  • BNB Smart Chain (mainnet, testnet)

How it’s structured

MUTX ships as a single unified binary with four surfaces:

  • mutx — the terminal UI, where you manage wallets and review SLK proposals from agents
  • mutx daemon — the background service that holds wallet state and runs the authorization flow
  • mutx web — a browser-based UI with the same operations as the TUI
  • mutx-link (also mutx link) — the MCP interface for AI agents

What you get

  • Wallet operations without handing agents raw private keys
  • Direct operator control from the TUI or Web UI at any time
  • Bounded agent autonomy through Short Lived Keys (SLK) — typed capability tokens with per-capability scopes, per-tx caps, total budgets, recipient whitelists, rate limits, and a hard expiry
  • Encrypted-at-rest per-SLK wallet secrets, so an agent’s autonomous signing survives a daemon restart without re-prompting
  • Autonomous WalletConnect session approval when an SLK grants can_wc_connect for the matching dApp scope
  • Multi-chain support across Solana and the major EVM networks
  • Automatic background balance and token refresh on every wallet

What MUTX can do

  • Create or import wallets on any supported chain
  • Send and receive the native asset (SOL, ETH, MATIC, BNB)
  • List and send tokens (SPL on Solana, ERC-20 on EVM)
  • Swap tokens via Jupiter or Raydium (Solana-only)
  • Connect wallets to dApps with WalletConnect
  • Manage an address book
  • Expose wallet operations to agents over stdio or HTTP via MCP
  • Expose wallet operations as CLI subcommands for scripts and Skills-based agents
  • Reach the daemon remotely through the MUTX relay

Start here

This documentation covers the public operator surface only.

Getting Started

This section covers how to install mutx and mutx-link, then get to a working SLK proposal review flow with an MCP client.

Installation

You can run MUTX as local binaries or as containers.

Components

  • mutx: interactive terminal application; this is the authority process
  • mutx-link: MCP server + CLI; this is the agent-facing process

In normal use, you run both.

Binary install

MUTX

Linux x86_64:

curl -LO https://download.mutx.net/mutx/latest/mutx-linux-x86_64
chmod +x mutx-linux-x86_64
sudo mv mutx-linux-x86_64 /usr/local/bin/mutx

macOS Intel:

curl -LO https://download.mutx.net/mutx/latest/mutx-macos-intel
chmod +x mutx-macos-intel
sudo mv mutx-macos-intel /usr/local/bin/mutx

macOS Apple Silicon:

curl -LO https://download.mutx.net/mutx/latest/mutx-macos-arm
chmod +x mutx-macos-arm
sudo mv mutx-macos-arm /usr/local/bin/mutx

Linux x86_64:

curl -LO https://download.mutx.net/link/latest/mutx-link-linux-x86_64
chmod +x mutx-link-linux-x86_64
sudo mv mutx-link-linux-x86_64 /usr/local/bin/mutx-link

macOS Intel:

curl -LO https://download.mutx.net/link/latest/mutx-link-macos-intel
chmod +x mutx-link-macos-intel
sudo mv mutx-link-macos-intel /usr/local/bin/mutx-link

macOS Apple Silicon:

curl -LO https://download.mutx.net/link/latest/mutx-link-macos-arm
chmod +x mutx-link-macos-arm
sudo mv mutx-link-macos-arm /usr/local/bin/mutx-link

Verify

mutx --version
mutx-link --version

Container images

Published images:

  • ghcr.io/mutx-net/mutx:latest
  • ghcr.io/mutx-net/mutx-link:latest

Run MUTX interactively:

docker run --rm -it \
  -v "$HOME/.config/mutx:/home/mutx/.config/mutx" \
  -v "$HOME/.local/share/mutx:/home/mutx/.local/share/mutx" \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx:latest

Run Link in HTTP mode:

docker run --rm \
  -p 8000:8000 \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx-link:latest

The shared /tmp/mutx mount is mandatory. Without it, the Link container cannot reach the MUTX socket and the two processes will not communicate.

Common deployment shapes

Host MUTX plus containerized Link:

mutx

docker run --rm \
  -p 8000:8000 \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx-link:latest

Containerized MUTX plus containerized Link:

docker run --rm -it \
  -v "$HOME/.config/mutx:/home/mutx/.config/mutx" \
  -v "$HOME/.local/share/mutx:/home/mutx/.local/share/mutx" \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx:latest

docker run --rm \
  -p 8000:8000 \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx-link:latest

Quick binary start

If you want the shortest local path, run the binaries directly:

mutx
mutx-link

Requirements

  • A terminal with TTY support for mutx
  • The MUTX daemon must be running before mutx-link (start it with mutx daemon)
  • Network access for wallet RPC and swap operations. By default this is the managed MUTX RPC proxy; you can also point individual wallets at your own provider.

Continue to Quick Start.

Quick Start

This is the shortest path to a working SLK proposal review flow.

MUTX ships as a single unified binary:

  • mutx — the terminal UI (default)
  • mutx daemon — the headless background service
  • mutx web — the browser-based UI
  • mutx-link (also reachable as mutx link) — the MCP agent interface

1. Start the daemon

mutx daemon

This starts the headless service that holds wallet state and runs the authorization flow.

2. Start the TUI

mutx

On first run, create or import a wallet from the Wallets tab:

  1. Press n to create a wallet, or i to import one
  2. Pick the chain — Solana for this example. The full list of supported chains is in the Wallet Management page.
  3. Pick the network — devnet if you want to experiment safely, mainnet for real funds
  4. Enter a wallet name
  5. Choose how the wallet should be protected. Use Password unless you are working with a throwaway wallet.
  6. Press r to display the receive address
  7. Press b to refresh balances (balances also refresh automatically in the background)

3. Connect an agent

Local stdio mode (default):

mutx link

HTTP mode:

mutx link serve --mode http --bind 0.0.0.0:8000

4. Configure your MCP client

Minimal local configuration:

{
  "mcpServers": {
    "mutx": {
      "command": "mutx",
      "args": ["link"]
    }
  }
}

If you run Link over HTTP, point your client to /mcp on the chosen host and port.

5. Approve the agent’s SLK proposal

The agent calls request_slk once at the start of the session:

  • the proposal appears in the Proposals tab
  • inspect capabilities, scopes, wallets, and expiry
  • press y to approve, e to narrow the draft before approving, or n to deny

Once approved, every subsequent agent call is authorized by the SLK — no per-call prompt. Inspect the SLK in the SLKs tab, audit dispatches in the Activity tab, and revoke at any time with r.

WalletConnect session proposals are handled from the DApps tab, unless the agent’s SLK grants can_wc_connect for the matching dApp scope — in that case the session is approved autonomously.

mutx link wallet list

If you see your wallets printed, the socket is healthy and any MCP client will be able to reach MUTX.

See the MCP Setup guide for detailed configuration, or Agent Integration for client-specific instructions.

TUI Guide

mutx is the primary operator interface. It renders proposal review and SLK / activity audit surfaces and is the only process that can unlock wallets and prime SLK signing secrets.

  • Proposals, SLKs, Activity — Review agent SLK drafts, inspect active SLKs, audit dispatch activity (recommended path)
  • Requests — Fallback per-call approval queue for SLK-less agent operations
  • Wallet Management — Create, import, and operate wallets
  • Keybindings — Complete keyboard shortcut reference

Proposals, SLKs, and Activity

Three TUI tabs cover the agent-authorization lifecycle. Agents never prompt the operator per-call; they request a typed policy (SLK) up front and then operate inside it.

Proposals tab

When an agent calls request_slk, the daemon queues an SlkDraft here. Each row shows agent id, capabilities, scope summary, expiry, and proposal id.

From the detail view:

  • y approves the draft as submitted; the daemon mints the SLK and returns the token to the agent.
  • n denies it; the agent receives a typed denied outcome from slk_status.
  • e edits the draft. You can narrow any scope — fewer wallets, smaller caps, smaller total budgets, shorter expiry, fewer allowed venues — but never widen one. Widening edits are rejected by the validator.

If a scoped wallet is password-protected, the unlock prompt appears once at approval time. The wallet’s secrets are then encrypted at rest under the SLK’s wrap key and persist across daemon restarts.

SLKs tab

The catalogue of every minted SLK: label, agent, status (Active, Expired, Exhausted, Revoked), capabilities + scope summary, cumulative usage, and expiry.

  • Enter opens detail: typed capabilities, per-capability scopes, rate-limit config, lifetime, persisted-secret status per wallet.
  • r revokes the SLK immediately. Revocation sweeps the SLK’s persisted secrets too.

The Free tier is capped at 1 active SLK; paid tiers raise the limit. Hitting the cap surfaces a tier-limit modal at proposal-approval time.

Activity tab

The append-only audit log of every agent dispatch attempt — success, violation, or refusal. Each row carries: timestamp, SLK, MCP call, redacted params, native / token / USDC spend, duration, outcome.

  • Enter opens detail with the full typed violation (if any) and the on-chain explorer link (when the call produced a tx).

The Activity tab is the operator’s primary post-hoc audit surface; it never blocks dispatch.

WalletConnect note

When an SLK grants can_wc_connect and a dApp pairing matches the SLK’s WC scope, the daemon approves the session proposal autonomously — no prompt in DApps. The session settles immediately and the agent proceeds via its SLK. Operator-initiated pairings (you typed the WC URI in DApps) still take the human-driven approval path.

Requests (Fallback Approval Queue)

The Requests tab is the fallback per-call approval surface for agent operations that don’t carry an SLK. The recommended path is SLK-first (Proposals, SLKs, Activity) — every agent op authorized up front by a typed policy, then dispatched without prompting.

If an MCP request arrives without an SLK token, the daemon stores it here and waits for the operator. This is useful for one-off operator-initiated runs and for clients that don’t yet speak the SLK Proposal Protocol.

What shows up here

  • wallet list, details, balance, transactions, token list requests
  • native-asset send (SOL, ETH, MATIC, BNB) and token send requests
  • swap requests (Solana only)
  • message / typed-data / hash signing requests
  • wallet create, import, and delete requests
  • address book list and add requests
  • WalletConnect-initiated session signing requests when no SLK with can_wc_connect matches the dApp

Controls

KeyAction
EnterOpen request detail (action, params, requesting client)
yApprove
nDeny
dDelete from history
eCopy explorer URL (when the call produced a tx)

The daemon blocks the agent’s call until you decide. Most agents will time out after 30s — long enough for interactive review, not for a long break.

When to prefer SLK over Requests

Use the Proposals → SLK path whenever the agent will perform more than one or two operations, or any signing op. SLK creation is a single approval that grants typed, scoped, time-bounded autonomy to the agent without per-call friction.

Wallet Management

The Wallets tab is where you create, import, inspect, and operate wallets.

Supported chains

MUTX supports the following blockchains. Pick one when you create a wallet, then pick the network you want to work on.

ChainNetworks
Solanamainnet, devnet, testnet
Ethereummainnet, sepolia
Polygonmainnet, amoy
Basemainnet, sepolia
Arbitrum Onemainnet, sepolia
BNB Smart Chainmainnet, testnet

Every wallet routes through the managed MUTX RPC proxy by default (https://<network>.<blockchain>.rpc.mutx.net). You only need to provide your own RPC if you want to use a private provider. That override is set per wallet from the wallet details page.

New wallets default to a testnet for the chain you pick, which is the safest place to try operations.

Create a wallet

From the Wallets tab:

  1. Press n
  2. Pick the chain (Solana, Ethereum, Polygon, Base, Arbitrum, BNB Smart Chain)
  3. Pick the network for that chain (mainnet or the matching testnet)
  4. Enter a wallet name
  5. Choose how the wallet should be protected

Import a wallet

Press i to import from a seed phrase or private key. The chain and network picker work the same way as in the create flow.

Protection modes

  • Password (default) — Requires a password for sensitive operations.
  • KeyFile — Uses the contents of a local file or an HTTPS URL as the encryption password.
  • Cleartext — No password; suitable only for temporary test wallets.

Common actions

With a wallet selected, the default shortcuts are:

  • r show receive address
  • t transfer the native asset (SOL, ETH, MATIC, BNB, depending on chain)
  • s open swap flow (Solana only)
  • b refresh balances immediately
  • h show transaction history
  • o toggle token account view
  • z close empty token accounts (Solana only)
  • x export seed phrase or private key
  • m rename wallet
  • p pin or unpin wallet in the sidebar
  • d delete wallet

Operations that are Solana-specific (swap, close empty token accounts) are disabled on EVM wallets.

Auto-refresh

Balances and token lists refresh automatically in the background, by default every 30 seconds. After you submit a transaction the refresh briefly accelerates (1s, 3s, 10s, 30s) so the new state appears quickly.

You can still press b for an immediate manual refresh — useful if you sent a transaction from another tool and don’t want to wait for the next tick.

Airdrops

The a shortcut requests faucet funds on a wallet’s testnet, currently supported on Solana devnet and testnet.

Mainnet wallets do not support airdrops.

Unlocking a wallet

A password-protected wallet must be unlocked before it can sign. You can unlock it on demand, ahead of any operation, from the wallet’s detail view:

  • u unlock the wallet — opens a duration picker (quick-pick presets like 5m / 15m / 1h / 4h / 12h / 24h / 7d, plus an editable amount and unit for any other value, and a “keep unlocked until I lock it manually” option), then the masked password prompt
  • l lock the wallet again
  • A toggle auto-approve while the wallet is unlocked
  • L (from the wallet list) lock all wallets at once — a panic switch

While a wallet is unlocked, signing happens without re-entering the password, until the unlock window expires or you lock it.

Wallet details

Press Enter on a wallet to inspect wallet-specific settings and network configuration. This is where you set a custom RPC endpoint for that single wallet, view its full address, see per-wallet metadata, and manage the wallet’s lock state (see Unlocking a wallet).

Keybindings

All keybindings are configurable. Defaults are listed below.

Global

KeyAction
Ctrl+pCommand palette
Ctrl+mFocus Sidebar
Ctrl+bHide/Show Sidebar
?Global help
hToggle balance visibility
EscBack / Cancel
qQuit

Wallets

KeyAction
nNew wallet
iImport wallet
dDelete wallet
xExport seed phrase / private key
sSwap tokens
rReceive address
tTransfer funds
bRefresh balance
hTransaction history
oToggle token accounts view
zClose empty token accounts
aAirdrop on devnet/testnet
pPin/unpin
mRename
cCopy to clipboard

Proposals

KeyAction
yApprove proposal
nDeny proposal
eEdit / narrow proposal before approving

Address Book

KeyAction
nNew contact
dDelete contact
cCopy address

DApps

KeyAction
pPair with WalletConnect URI
dDisconnect selected session
yApprove proposal or request
nReject proposal or request

SLKs

KeyAction
nCreate SLK directly (operator-initiated)
rRevoke selected SLK
EnterShow SLK detail (capabilities, scopes, usage)

Activity

KeyAction
EnterShow dispatch detail (call, spend, violation if any)

Logs

KeyAction
fToggle log follow mode
wToggle log wrapping
rToggle raw JSON log view

Web UI

MUTX includes a browser-based Web UI that is a full alternative to the TUI. It exposes the same wallet, key, and request flows in a graphical interface, useful when you don’t want to keep a terminal open or when you want to operate from a different machine on your local network.

Starting the Web UI

The daemon must be running first.

mutx daemon
mutx web

By default the Web UI binds to http://127.0.0.1:8080 (local only). Open that URL in your browser.

What’s in the Web UI

  • Dashboard — Portfolio overview across your wallets
  • Wallets — Create, import, view details, send native asset, send tokens, swap, receive (with QR code), transaction history, per-wallet settings. The create flow uses the same chain picker as the TUI — Solana, Ethereum, Polygon, Base, Arbitrum, BNB Smart Chain — followed by the network picker. Each wallet has a proactive Unlock / Lock control (parity with the TUI), plus a global Lock all wallets button. Unlock opens the same duration picker used elsewhere: quick-pick presets plus an editable amount and unit.
  • Keys (SLK) — Create with per-token budgets, revoke, delete, duplicate, view usage history
  • Requests — Approve or deny agent requests, clear history
  • Contacts — Address book management (add, edit, delete)
  • DApps — WalletConnect pairing and active session management
  • Logs — Real-time log viewer with search and filtering
  • License — Tier status, comparison, coupon redemption, USDC purchase
  • Settings — Theme, log level, navigation preferences

TUI and Web UI together

The TUI and the Web UI talk to the same background daemon. You can run both at once; the daemon is the source of truth, so a wallet you create from the Web UI shows up in the TUI immediately and vice versa.

Approval prompts (agent requests, WalletConnect proposals) appear in whichever UI is active. If both are open, you can answer from either side.

Configuration

# Custom bind address
mutx web --bind 0.0.0.0:3000

# Custom socket directory
mutx web --socket-dir /path/to/sockets

By default the Web UI binds to 127.0.0.1:8080, which means it is only reachable from the same machine. Use --bind 0.0.0.0:PORT to expose it on your local network — only do this on a trusted network, since anyone who can reach the port can issue wallet operations.

MCP Integration

mutx-link exposes MUTX wallet operations to MCP-compatible agents.

The boundary is simple:

  • mutx holds local state and wallet access
  • mutx-link forwards requests to MUTX
  • communication between them happens over a Unix socket at /tmp/mutx/mutx.sock

Link also supports a CLI mode (mutx-link wallet list, etc.) for Skills-based agents and scripts that prefer shell commands over MCP.

MCP Setup

Link supports local stdio transport and streamable HTTP transport.

Prerequisite

Start the daemon first:

mutx daemon

Link expects the MUTX socket at:

/tmp/mutx/link.sock

You can override the socket path with MUTX_SOCKET_PATH or mutx link --link-socket-path ....

stdio mode

mutx link

This is the default mode and the best choice when the agent runs on the same machine.

Example client configuration:

{
  "mcpServers": {
    "mutx": {
      "command": "mutx",
      "args": ["link"]
    }
  }
}

Note: The standalone mutx-link binary is still available and works identically. Use it if you prefer a dedicated binary or in Docker containers.

HTTP mode

mutx link serve --mode http --bind 0.0.0.0:8000

HTTP mode exposes:

  • MCP endpoint: http://HOST:8000/mcp
  • health check: http://HOST:8000/health

Use this mode when:

  • the agent cannot spawn local processes
  • you want to front MUTX with a container
  • you need a shared MCP endpoint on a trusted local network

CLI mode

Link also exposes all 17 MCP tools as CLI subcommands:

mutx link wallet list
mutx link wallet balance <wallet>
mutx link wallet send <wallet> <to> <amount>
mutx link slk info
mutx link address-book list

Use --json for machine-readable output. Use --link-socket-path to override the default socket location.

Container example

docker run --rm \
  -p 8000:8000 \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx-link:latest

If MUTX is also containerized, mount the same /tmp/mutx directory into both containers.

Verifying the connection

With the daemon running, confirm the socket is reachable:

mutx link wallet list

If you see your wallets listed, the socket connection is healthy and any MCP client configured with {"command": "mutx", "args": ["link"]} will work.

Troubleshooting

SymptomLikely causeFix
Could not reach MUTXDaemon is not runningStart with mutx daemon
request_slk tool call hangsWaiting for operator decisionApprove, deny, or narrow the proposal in the Proposals tab
Other tool calls fail with SLK not found or invalidNo SLK or token wrongCall request_slk first; pass the returned token on every subsequent call
HTTP 404 on /mcpWrong path or portEndpoint is /mcp, not /
SLK expired errorSLK has expiredRequest a new SLK via request_slk
MUTX_SOCKET_PATH ignoredEnv not passed to subprocessUse the --link-socket-path flag instead

For verbose logging, set RUST_LOG=mutx_link=debug before starting Link.

Operational notes

  • Link is stateless
  • if the daemon is not reachable, tool calls fail immediately
  • SLK proposal review happens in the TUI / Web UI, even when Link is served over HTTP

Agent Integration

How to connect MUTX to specific MCP clients.

Claude Code

Add to ~/.claude.json or your project .mcp.json:

{
  "mcpServers": {
    "mutx": {
      "command": "mutx",
      "args": ["link"]
    }
  }
}

The daemon must be running before the Claude Code session starts. Start it with mutx daemon. The agent spawns mutx link as a subprocess in stdio mode. The agent calls request_slk once; the SLK draft appears in the Proposals tab for operator approval, then every subsequent agent call is authorized by the SLK itself — no per-call prompt.

Claude Desktop

Config file location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "mutx": {
      "command": "/usr/local/bin/mutx",
      "args": ["link"]
    }
  }
}

Claude Desktop may not inherit your shell PATH. Use the full path to mutx.

Custom agents (SDK)

stdio transport

Spawn mutx link as a subprocess and wire stdin/stdout. This works with any MCP SDK that supports stdio transport.

HTTP transport

Run Link in HTTP mode:

mutx link serve --mode http --bind 0.0.0.0:8000

Point your SDK’s HTTP transport at http://HOST:8000/mcp.

Docker-based agents

When the agent cannot spawn local processes, run Link in a container:

docker run --rm -p 8000:8000 \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx-link:latest

The agent connects to http://localhost:8000/mcp. MUTX can run natively or in its own container – both just need to share /tmp/mutx.

CLI mode

For shell scripts and Skills-based agents that prefer commands over MCP:

mutx link wallet list
mutx link wallet balance <wallet>
mutx link wallet send <wallet> <to> <amount>
mutx link slk request --label "trading" --wallets "Main" --can-send-native --expires-in 3600
mutx link slk status <proposal-id-or-token>
mutx link address-book list
mutx link wc sessions

Full command groups:

mutx link wallet {list,receive,send,details,balance,transactions,token-list,token-send,swap,create,import-seed,import-key,delete}
mutx link slk {request,status,revoke}
mutx link address-book {list,add}
mutx link wc {connect,sessions,disconnect}

The signing tools (wallet_sign_message, wallet_sign_typed_data, wallet_sign_hash), swap_quote, wallet_close_token, and wallet_access are available over MCP only — see Available Tools.

Use --json for machine-readable output. Use --link-socket-path to override the default socket location.

Available MCP Tools

MUTX exposes 27 MCP tools.

Most tools follow one of these patterns:

  • approval in the terminal
  • autonomous execution with a valid SLK
  • direct execution for low-risk, read-only, or session-lifecycle operations

Conventions

  • Wallets are referenced by short ID (4-char prefix) or wallet name
  • slk is optional on tools that support autonomous execution
  • wallet_connect creates a pairing attempt, but the user still approves the WalletConnect proposal inside the terminal

Wallet Tools

wallet_list

List available wallets. Requires terminal approval — when the request appears, the operator picks which wallets to expose for this request. Every wallet is preselected by default; the operator deselects any wallet they want to keep hidden. With an SLK, the call returns only the SLK-permitted wallets immediately, with no prompt.

ParameterTypeRequiredDescription
slkstringnoSLK token for autonomous access

wallet_details

Get a wallet’s name, address, and network.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
slkstringnoSLK token (requires can_balance)

wallet_balance

Refresh and return the native asset balance (SOL, ETH, MATIC, BNB depending on chain) plus token balances. Triggers an RPC refresh.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
slkstringnoSLK token (requires can_balance)

wallet_receive

Get a wallet’s receive address.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
slkstringnoSLK token

wallet_send

Send the chain’s native asset to an address (SOL on Solana, ETH on Ethereum and Arbitrum, MATIC on Polygon, BNB on BNB Smart Chain, etc.).

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
recipientstringyesDestination address
amountstringyesAmount in the native asset (e.g. "1.5"), or "max" to drain the full balance (fee reserved automatically)
slkstringnoSLK token (requires can_send)

wallet_token_list

List tokens held by a wallet (SPL on Solana, ERC-20 on EVM chains).

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
slkstringnoSLK token

wallet_token_send

Send tokens (SPL on Solana, ERC-20 on EVM chains).

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
tokenstringyesToken identifier — mint address on Solana, ERC-20 contract address on EVM (legacy alias: mint)
recipientstringyesDestination address
amountstringyesToken amount, or "max" for the full token balance
slkstringnoSLK token (requires can_send_tokens)

wallet_swap

Swap tokens via a DEX (Jupiter or Raydium). Solana-only — the daemon rejects this call on EVM wallets.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
input_mintstringyesInput token (mint address or symbol like SOL, USDC)
output_mintstringyesOutput token (mint address or symbol)
amountstringyesInput amount, or "max" for full balance
slippage_bpsnumbernoSlippage tolerance in basis points (default: 50)
platformstringno"jupiter" or "raydium" (default: auto)
slkstringnoSLK token (requires can_swap)

swap_quote

Preview a swap without executing it: returns expected output, minimum after slippage, price impact, route, platform, and fee. Read-only — no funds move, no signing, no SLK budget consumed, and no approval required. Solana-only.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
inputstringyesInput token (mint address or symbol)
outputstringyesOutput token (mint address or symbol)
amountstringyesInput amount to quote
slippage_bpsnumbernoSlippage tolerance in basis points (default: 50)
slkstringnoSLK token (any active in-scope SLK is accepted; no budget consumed)

wallet_close_token

Close an empty SPL token account (associated token account) and reclaim its SOL rent to the wallet owner. The account must hold a zero balance. Solana-only. This is an on-chain signing transaction.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
token_accountstringyesThe (empty) token account address to close
slkstringnoSLK token (requires can_sign_message / can_sign_typed_data / can_sign_hash as appropriate)

wallet_transactions

Transaction history with optional filters.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
filterobjectnoSee filter fields below
slkstringnoSLK token (requires can_balance)

Filter fields:

FieldTypeDescription
directionstring"sent" or "received"
min_amountstringMinimum native-asset amount
max_amountstringMaximum native-asset amount
counterpartystringFilter by address
token_mintstringFilter by token (mint on Solana, contract address on EVM)
afternumberUnix timestamp lower bound (seconds)
beforenumberUnix timestamp upper bound (seconds)
limitnumberResults per page (default: 20, max: 100)
offsetnumberPagination offset

Signing Tools

These tools let an agent produce a signature for an external dApp (for example a Polymarket login challenge or order) without ever touching the wallet’s private key. Every signing tool is gated the same way: an SLK with the matching capability for autonomous execution (can_sign_message / can_sign_typed_data / can_sign_hash), or the Requests-tab fallback for SLK-less calls.

wallet_sign_message

Sign an arbitrary message. EVM wallets sign via EIP-191 personal_sign; Solana wallets sign via ed25519. The message may be plain UTF-8, or a 0x-prefixed hex string (matching the WalletConnect personal_sign convention). Returns a 0x-prefixed hex signature. Use this for dApp auth challenges.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name
messagestringyesUTF-8 text, or a 0x-prefixed hex string
slkstringnoSLK token (requires can_sign_message / can_sign_typed_data / can_sign_hash as appropriate)

wallet_sign_typed_data

Sign an EIP-712 typed-data document with an EVM wallet. Pass the full {domain, types, primaryType, message} object — the same shape Polymarket, viem, and ethers produce. Solana wallets are rejected. The terminal approval preview shows domain.name, verifyingContract, chainId, and primaryType so the operator can audit what they are signing. Returns a 0x-prefixed hex signature.

ParameterTypeRequiredDescription
walletstringyesEVM wallet short ID or name
typed_dataobjectyesFull EIP-712 document {domain, types, primaryType, message}
slkstringnoSLK token (requires can_sign_message / can_sign_typed_data / can_sign_hash as appropriate)

wallet_sign_hash

Sign a raw, pre-computed 32-byte digest directly with an EVM wallet’s key — no EIP-191 prefix, no extra hashing (the input is the message hash). Returns a 0x-prefixed 65-byte r||s||v signature. Use this only for ERC-1271 / ERC-7739 smart-contract-wallet flows where the caller has already computed the final hash. Solana wallets are rejected.

This is blind signing — the operator approves an opaque hash — so always pass a clear context describing what the hash represents. For human-readable messages use wallet_sign_message; for EIP-712 use wallet_sign_typed_data.

ParameterTypeRequiredDescription
walletstringyesEVM wallet short ID or name
hashstringyes0x-prefixed 32-byte hex digest (66 chars)
contextstringnoHuman-readable description, shown verbatim in the approval preview
slkstringnoSLK token (requires can_sign_message / can_sign_typed_data / can_sign_hash as appropriate)

Wallet Lifecycle

These tools create or destroy wallets. Each one requires terminal approval (no SLK path). Wallets created through MCP are Cleartext-protected — for a password-protected wallet, use the TUI or Web UI wizard instead.

wallet_create

Create a new Cleartext-protected wallet. Returns the generated seed phrase once — store it offline immediately, it is never shown again.

ParameterTypeRequiredDescription
namestringyesWallet display name (must be unique)
networkstringyes"solana", "ethereum", or "bitcoin"

wallet_import_seed

Import a wallet from an existing BIP-39 seed phrase, as Cleartext-protected.

ParameterTypeRequiredDescription
namestringyesWallet display name (must be unique)
networkstringyes"solana", "ethereum", or "bitcoin"
seed_phrasestringyes12- or 24-word BIP-39 seed phrase

wallet_import_private_key

Import a wallet from a raw private key, as Cleartext-protected. Solana: base58-encoded 64-byte keypair. Ethereum: hex (with or without 0x).

ParameterTypeRequiredDescription
namestringyesWallet display name (must be unique)
networkstringyes"solana", "ethereum", or "bitcoin"
private_keystringyesRaw private key

wallet_delete

Delete a wallet permanently. Destructive and irreversible — back up the seed phrase before approving.

ParameterTypeRequiredDescription
walletstringyesWallet short ID or name

Wallet Access

wallet_access

Read-only view of per-wallet access state: protection mode (password/keyfile/cleartext), lock state (locked, or unlocked with the remaining seconds), whether auto-approve-while-unlocked is enabled, and the active SLKs bound to each wallet. Visibility and audit only — there is no unlock/lock action here. Unlocking a wallet is a human-only operation done in the TUI or Web UI; an agent’s authorization grant is its SLK. No approval needed.

No parameters.

Address Book

address_book_list

List saved contacts.

ParameterTypeRequiredDescription
slkstringnoSLK token (requires can_balance; returns only contacts in the SLK’s address scope)

address_book_add

Add a contact. The contact is added globally.

ParameterTypeRequiredDescription
namestringyesContact name
addressstringyesWallet address
networkstringnoNetwork (default: "solana")
memostringnoOptional note
slkstringnoSLK token (requires can_send)

WalletConnect

wallet_connect

Submit a WalletConnect pairing URI. The session proposal is approved in the terminal.

ParameterTypeRequiredDescription
uristringyesWalletConnect wc: URI

wallet_sessions

List active WalletConnect sessions. No approval needed. No parameters.

wallet_disconnect

Disconnect a WalletConnect session. No approval needed.

ParameterTypeRequiredDescription
sessionstringyesSession topic prefix or DApp name

SLK Management

request_slk

Submit a full SlkDraft for operator review. The daemon queues it as a Proposal and returns immediately with proposal_id and expires_at. Poll slk_status with target=<proposal_id> to see the operator decision. On approval the response carries the SLK raw token; pass it on every subsequent agent call. See the SLK guide for the draft shape and per-capability scope structs.

ParameterTypeRequiredDescription
draftobjectyesFull SLK draft: identity_partial, wallet_scope, capabilities, scopes, limits (optional), lifetime, proposal_ttl_seconds (optional)

slk_status

Query the typed status of either a proposal (by id) or a minted SLK (by raw token). The daemon resolves both lookup paths. Returns a snapshot with lifecycle status, cumulative usage, expiry, capabilities, and scopes. No approval needed.

ParameterTypeRequiredDescription
targetstringyesProposal UUID or SLK raw token

slk_revoke

Revoke the agent’s own SLK by raw token. Proof of possession; no human approval needed (permission-reducing). The SLK transitions to Revoked and any subsequent dispatch with this token fails closed.

ParameterTypeRequiredDescription
tokenstringyesSLK raw token

Common Workflows

Check a wallet balance

  1. wallet_list — get available wallets
  2. Pick a wallet ID or name from the response
  3. wallet_balance — returns the native asset and token balances

Send the native asset with an SLK

  1. request_slk with can_send_native and a send_native scope carrying per_tx_cap, total_budget, and recipient_whitelist
  2. Operator approves (or narrows) in the Proposals tab
  3. slk_status returns the SLK raw token
  4. wallet_send with the SLK — executes without further approval

Execute a swap autonomously

  1. swap_quote to preview output, price impact, and route (no approval, no budget)
  2. request_slk with can_swap and a swap scope (allowed_pairs, max_slippage_bps, total_budget_usdc)
  3. Operator approves
  4. wallet_swap with the SLK — quote is fetched and swap executes within slippage bounds

Sign for a dApp without exposing keys

  1. request_slk with can_sign_typed_data (or can_sign_message / can_sign_hash) scoped to the wallet and dApp domain
  2. Operator approves
  3. Use wallet_sign_message (auth challenges), wallet_sign_typed_data (EIP-712 orders), or wallet_sign_hash (ERC-1271 / ERC-7739) with the SLK
  4. The agent gets a signature; the private key never leaves MUTX

Autonomous WalletConnect session

  1. request_slk with can_wc_connect + a wc scope listing allowed dApp origins
  2. Operator approves
  3. The dApp pairs (operator or agent supplies the wc: URI). When the proposed session matches the SLK’s WC scope, the daemon approves it autonomously — no prompt in DApps. The session settles and the agent proceeds.

SLK (Short Lived Keys)

Short Lived Keys are the sole authorization path for AI agents. Every MCP request from an agent must carry a valid SLK token; the daemon validates it on every call and rejects anything outside the SLK’s stated scope. Operator-direct ops in the TUI / Web UI never need an SLK and never go through the agent path.

An SLK is not a wallet key. It is a typed, scoped, time-bounded, auditable policy contract between you and one agent.

Requesting an SLK

An agent calls request_slk with a full SlkDraft — typed capabilities, per-capability scopes, a lifetime, and (optionally) rate limits. The draft is queued as a proposal for operator review in the Proposals tab (TUI / Web UI / CLI). The operator can narrow the draft — never widen it — and then approve or deny. On approval the daemon mints the SLK and returns the token to the agent; the agent then operates autonomously until expiry, budget exhaustion, or revocation.

If a scoped wallet is password-protected, the operator unlocks it once, at approval time. The wallet’s secrets are encrypted at rest under a per-SLK 32-byte wrap key, so the agent keeps signing across a daemon restart without re-prompting.

Wallet scope

Each SLK’s wallet scope is explicit:

  • Specific wallets — the SLK can only touch wallets the operator selected.
  • All wallets — an explicit allow_all_wallets grant that includes every wallet now and any wallet added later under the same daemon.

An SLK with neither set authorizes nothing (an empty scope is not treated as “all wallets”) and is rejected at draft validation.

Capabilities

Capabilities are typed boolean flags. Each flag is necessary but not sufficient: the matching scope (see below) constrains how the flag may actually be exercised.

CapabilityAllows
can_balanceRead native and token balances
can_transactionsRead transaction history
can_send_nativeSend the chain’s native asset (SOL, ETH, MATIC, BNB)
can_send_tokenSend tokens (SPL on Solana, ERC-20 on EVM)
can_swapSwap tokens via DEX (Jupiter / Raydium on Solana)
can_close_tokenClose empty SPL token accounts and reclaim rent
can_sign_messageSign arbitrary messages (EVM personal_sign / Solana ed25519)
can_sign_typed_dataSign EIP-712 typed data (e.g. Polymarket CLOB orders)
can_sign_hashSign a raw 32-byte digest (ERC-1271 / ERC-7739 SCW flows)
can_wc_connectApprove a WalletConnect session proposal autonomously

Scopes

Per-capability scope structs narrow what each granted capability may do:

  • send_native — per-tx cap, total budget, recipient whitelist.
  • send_token — per-mint per-tx cap, per-mint total budget, per-mint recipient whitelist, and global allowed / denied mint lists.
  • swap — allowed input/output pair list, max slippage in bps, total USDC-denominated budget, allowed venues.
  • sign_message — domain / dApp allowlist.
  • sign_typed_data — EIP-712 domain match rules.
  • sign_hash — context hashes the agent must declare (blind-signing guard).
  • wc — allowed dApp origins for autonomous session approval.

Scopes always narrow a capability — the daemon refuses any operator edit that would widen scope after the SLK is minted.

Rate limits

Optional SlkRateLimit constrains ops/minute, ops/hour, ops/day. The validator computes rolling windows from the activity log at dispatch time. Hitting any limit returns a typed SlkViolation; the SLK itself stays Active.

Lifetime

SlkLifetime carries an optional not_before (the SLK is dormant until that timestamp) and a mandatory expires_at (hard cutoff). No “forever” SLKs.

Inspection and revocation

  • slk_status — returns the typed status snapshot for a proposal id (before approval) or for an SLK token (after approval): lifecycle status, cumulative usage, expiry, capabilities, scopes.
  • slk_revoke — proof-of-possession revoke; the agent holding the token can revoke it without operator approval (permission-reducing). Operators can also revoke from the SLKs tab.

A revoked or expired SLK is rejected at dispatch with a typed violation; no operator interaction needed.

Surviving a daemon restart

Per-SLK wallet secrets are AES-256-GCM encrypted at rest under the SLK’s own wrap key and rehydrated on daemon startup, so an agent’s autonomous signing continues uninterrupted for the SLK’s lifetime.

Locking a wallet (the operator’s panic button) clears the cached secrets for every SLK on that wallet; the next agent op against that wallet surfaces PasswordRequired, the operator unlocks once, and the SLK resumes signing. Revocation and expiry sweep the persisted secrets too.

When to use SLKs

You need an SLK for every agent operation. Typical patterns:

  • periodic balance / transaction polling (read-only scope)
  • capped recurring payouts to a fixed whitelist
  • swap execution with a strict slippage ceiling
  • dApp order signing (EIP-712) within a time and budget window
  • autonomous WalletConnect session approval for a known dApp origin

Relay (Remote Access)

The MUTX relay lets remote AI agents reach your local daemon over the internet. Without it, agents can only reach the daemon from the same machine.

How it works

  1. Your daemon opens an outbound connection to relay.mutx.net.
  2. Remote agents send requests to the relay with your unique relay code.
  3. The relay forwards each request to your daemon.
  4. Your daemon validates the SLK and processes the request, exactly as it would for a local agent.
  5. The response flows back through the relay to the agent.

The relay is a transparent pipe. All authorization (SLK validation, approval queues, budget tracking) happens locally in your daemon — the relay never sees wallet keys and never makes authorization decisions.

Setup

1. Enable Relay

In MUTX settings, enable relay mode:

relay_enabled = true

2. Register

The daemon registers with the relay server and receives:

  • Relay code (MUTX-XXXX): Share this with agents so they can reach you.
  • Relay secret: Used by the daemon to authenticate to the relay. Keep this private.

3. Share Credentials with Agents

Give the agent:

  • Your relay code (e.g., MUTX-R7K3)
  • An SLK token (created via the TUI or another trusted agent)

The agent uses both to send requests through the relay.

Agent Request Format

Agents send HTTP POST requests to https://relay.mutx.net/v1/request:

{
  "relay_code": "MUTX-R7K3",
  "envelope": {
    "slk": "slk_...",
    "request": {
      "type": "wallet_list",
      "request_id": "unique-id"
    }
  }
}

The response is a standard McpResponse JSON object.

Discovery

Agents can discover capabilities at:

GET https://relay.mutx.net/.well-known/mutx.json

This returns available tools, the request URL, and auth requirements.

Security

  • SLK tokens control what agents can do (permissions, budgets, time limits).
  • The relay never sees your wallet keys or makes authorization decisions.
  • You can revoke relay access at any time by disabling relay mode or revoking the registration.
  • All traffic is encrypted via TLS.

Disabling

Set relay_enabled = false in settings, or revoke the registration. The daemon disconnects immediately and agents can no longer reach you.

Reference

  • Configuration — Paths, overrides, and runtime settings
  • Deployment — Binary and container deployment patterns
  • FAQ — Frequently asked questions

Configuration

MUTX uses XDG-style paths by default.

Paths

  • Config directory: ~/.config/mutx/
  • Data directory: ~/.local/share/mutx/
  • Bootstrap file: ~/.config/mutx/config.toml
  • Default socket path: /tmp/mutx/mutx.sock

After first run, most settings live in the SQLite database under the data directory. The TOML file becomes a minimal bootstrap file, mainly for db_path.

CLI and environment overrides

mutx supports these overrides:

  • --config-dir or MUTX_CONFIG_DIR
  • --data-dir or MUTX_DATA_DIR
  • --socket-path or MUTX_SOCKET_PATH
  • --log-file or MUTX_LOG_FILE
  • --log-level or MUTX_LOG_LEVEL

Bootstrap example

db_path = "/home/alice/.local/share/mutx/mutx.db"

Runtime settings

The application persists settings such as:

  • theme flavor: mocha, latte, macchiato, frappe
  • log level
  • log-to-file toggle
  • vim navigation mode
  • hidden balance mode
  • dashboard animation toggle
  • Solana network default
  • explorer URL templates for Solana
  • keybindings

Per-wallet custom RPC

By default, every wallet routes through the managed MUTX RPC proxy (https://<network>.<blockchain>.rpc.mutx.net). You do not need to configure anything for this to work.

If you want a wallet to use your own RPC endpoint (a private Helius URL, an internal validator, Alchemy, Infura, etc.), open the wallet details page and set the custom RPC URL field for that single wallet. Other wallets are unaffected.

There is no global “override the RPC for every wallet on chain X” setting — this is per wallet by design.

Auto-refresh

Balances and token lists refresh in the background every 30 seconds. You do not need to configure this. The TUI’s b key still triggers an immediate manual refresh.

Explorer URL overrides (Solana)

You can override the explorer URL templates that the TUI uses for transactions and addresses on Solana. Useful if you prefer Solana Beach, Solscan, or your own explorer over the default.

Templates use {tx} for transaction signatures and {addr} for addresses, configurable per cluster (devnet / testnet / mainnet).

Deployment

This page covers the public deployment shapes for MUTX.

Local binaries

This is the simplest setup:

  1. Run mutx
  2. Run mutx-link
  3. Configure the agent to spawn mutx-link

Use this when the operator, the TUI, and the agent all live on the same host.

This is useful when the agent expects an HTTP endpoint or when you want to keep the Link runtime isolated.

Requirements:

  • MUTX running on the host
  • shared socket directory mounted into the Link container

Example:

docker run --rm \
  -p 8000:8000 \
  -v /tmp/mutx:/tmp/mutx \
  ghcr.io/mutx-net/mutx-link:latest

Fully containerized

You can containerize both components, but MUTX still needs:

  • -it for interactive terminal access
  • persistent config and data volumes
  • a shared /tmp/mutx mount so the Link container can reach the socket

Health checks

In HTTP mode, Link exposes:

  • /health for liveness
  • /mcp for the actual MCP transport

Logging

mutx can write structured logs to file and export them with:

mutx logs export

Useful flags:

  • --category
  • --level
  • --since
  • --until
  • --encrypt

FAQ

General

What blockchains does MUTX support?

Solana and the major EVM L1 / L2 peers:

  • Solana (mainnet, devnet, testnet)
  • Ethereum (mainnet, sepolia)
  • Polygon (mainnet, amoy)
  • Base (mainnet, sepolia)
  • Arbitrum One (mainnet, sepolia)
  • BNB Smart Chain (mainnet, testnet)

You pick the chain and network when you create or import a wallet.

How do I use a custom RPC?

Open the wallet details page and set the custom RPC URL field for that wallet. It applies only to that wallet — there is no global per-chain override. Other wallets keep using the managed MUTX RPC proxy.

Why isn’t my balance refreshing?

It is. Balances and token lists refresh automatically in the background every 30 seconds, and accelerate briefly after you submit a transaction. If you want an immediate refresh, press b in the TUI on the selected wallet.

Is MUTX open source?

No. The public product is distributed as binaries and container images.

Where is my data stored?

All wallet data is stored locally in SQLite databases under ~/.local/share/mutx/. Private keys are encrypted with AES-256-GCM.

No. Wallet access stays in MUTX. Link forwards requests to the TUI over a local Unix socket.

Yes. mutx-link depends on the TUI socket and cannot serve wallet operations by itself.

MCP

Yes, using HTTP mode:

mutx-link serve --mode http --bind 0.0.0.0:8000

The MCP endpoint is /mcp and the health endpoint is /health.

What requires human approval?

request_slk — the SLK draft is queued as a Proposal for operator review and the operator approves, narrows, or denies it. Once the SLK is minted, every subsequent agent op is authorized by the SLK itself; no per-call approval. Operator-direct ops in the TUI / Web UI never need approval.

Can an SLK be revoked immediately?

Yes. The holder agent can call slk_revoke (proof-of-possession, permission-reducing, no human approval needed), or the operator can revoke it from the SLKs tab.

TUI

Can I use Docker for the TUI?

Yes, but it must run with an interactive TTY and persistent volumes for config, data, and the shared socket directory.

Which tab should I watch during operation?

  • Proposals to review and approve / deny / narrow SLK drafts from agents
  • SLKs to inspect active keys, usage, and revoke
  • Activity to audit per-dispatch log entries
  • DApps for WalletConnect proposals and sessions
  • Logs for troubleshooting and audit context