Skip to main content
Time: 15-20 minutes.

What You’ll Build

A self-hosted MCP server that can:
  • Create wallets with BIP-39 mnemonics (stored encrypted in a local vault)
  • Sign transactions locally for Ethereum and Tron
  • Enforce policy gates (chain allowlists, expiry)
  • Broadcast signed transactions to chain RPCs
  • Run as a Docker container or Node.js process

Architecture

Your Infrastructure
  |
  |-- MCP Server (HTTP, port 3000)
  |     |-- Read/Prepare tools  -> WalletSuite API
  |     \-- Sign/Broadcast tools -> OWS Vault (local)
  |
  |-- OWS Vault (~/.ows, AES-256-GCM encrypted)
  |
  \-- Chain RPCs (Ethereum, Tron)
Keys never leave your infrastructure. The MCP server orchestrates, OWS signs.
Self-host signing is the path for regulated, audit-driven, or compliance-bound organizations that require key custody on their own infrastructure. See Security Diligence for the procurement-ready security posture.

Prerequisites

  • WalletSuite API key — see Credentials & Authentication
  • Docker (recommended) or Node.js 22+
  • Ethereum and/or Tron RPC URL (for broadcasting)

Step 1 — Configure Environment

Create an .env file:
# Required
WALLETSUITE_API_KEY=your-api-key

# Transport
MCP_TRANSPORT=http
MCP_HTTP_MODE=stateless
MCP_BANDS=full

# OWS — Owner mode for initial setup
OWS_ENABLED=true
OWS_AUTH_MODE=owner
OWS_PASSPHRASE=your-secure-passphrase
OWS_VAULT_PATH=~/.ows

# Chain RPCs (required for broadcasting)
OWS_ETHEREUM_RPC_URL=https://your-ethereum-rpc.com
OWS_TRON_RPC_URL=https://your-tron-rpc.com
Do not commit the .env file to version control. Add it to .gitignore.

Step 2 — Start the Server

Step 3 — Create a Wallet (Owner Mode)

Connect to the MCP server and ask:
Create a wallet called treasury
The create_wallet tool generates a BIP-39 mnemonic, derives addresses for Ethereum and Tron, and stores the key material encrypted in the vault.
The mnemonic is shown once during creation. Save it securely — it cannot be retrieved later.
You will see the derived addresses:
{
  "wallet": {
    "name": "treasury",
    "accounts": [
      { "chainId": "eip155:1", "address": "0x1234..." },
      { "chainId": "tron:mainnet", "address": "T1234..." }
    ]
  }
}

Step 4 — Test Signing

There are two shapes to test. Start with the detached path — it exercises the full signing flow without touching the chain.

Detached signing (safe; no on-chain side effect)

Prepare a transfer of 0.001 ETH from treasury to 0xdef... and sign it
The agent will:
  1. Call prepare_serialized_unsigned_tx → builds the unsigned transaction hex
  2. Show you a review (amount, recipient, estimated fee)
  3. Call sign_transaction → signs locally and returns the signature. Nothing is broadcast.

Sign and broadcast (destructive; sends on-chain)

send_transaction is the destructive path — it signs and broadcasts. It requires confirmBroadcast=true, the matching chain RPC URL, and produces a real on-chain transaction hash that cannot be undone once confirmed. Use a testnet wallet and funded testnet address before running this against mainnet.
Prepare a transfer of 0.001 ETH from treasury to 0xdef... and broadcast it
The agent will prepare the transaction, show you the review, and then call send_transaction with confirmBroadcast=true. The response is the resulting transaction hash.

Step 5 — Create a Policy and Agent Key

For production, switch from owner mode to agent mode with a restricted policy.

Create a policy

Create a policy called "eth-only-90d" allowing Ethereum only, expiring in 90 days

Create an agent key bound to that policy

Create an agent API key for wallet treasury with policy eth-only-90d
The token is written to ~/.walletsuite/ows-agent-token (mode 0600).

Switch to agent mode

Update your .env:
OWS_AUTH_MODE=agent
OWS_AGENT_TOKEN=<contents of ~/.walletsuite/ows-agent-token>
# Remove OWS_PASSPHRASE
Restart the server. The agent can now sign only on Ethereum and only until the policy expires. It cannot create wallets, keys, or policies.

Step 6 — Connect Clients

Point any MCP-compatible client at the HTTP endpoint:
{
  "mcpServers": {
    "walletsuite": {
      "type": "http",
      "url": "http://localhost:3000/mcp"
    }
  }
}
Or with Claude Code:
claude mcp add --transport http walletsuite http://localhost:3000/mcp

Production Recommendations

  • Use agent mode — never run owner mode in production. Owner mode is for setup only.
  • Set restrictive policies — chain allowlists + short expiry windows.
  • Back up the vault~/.ows contains your encrypted keys. Losing it means losing access.
  • Use HTTPS RPCs — HTTP is allowed only for localhost.
  • Monitor the audit trail~/.walletsuite/audit-trail.jsonl logs every signing operation.
  • Run the production checklistProduction Checklist.