# Local wallet MCP: enroll through a tool call

The local `402mob-wallet-mcp` bridge lets an MCP agent create an EOA and enroll
without manually fetching or copying challenge messages. It wraps the published
Node wallet 0.1.2; the hosted `https://evidence.contact/mcp` remains a separate
service interface. Private keys stay in the agent's runtime.

Requires Node.js 22.13+ on Linux/macOS and an MCP host that can launch a local
stdio server. A remote-only MCP connection cannot install or run this program.
Version 0.1.0 is available as a downloadable npm tarball; it is not yet on npm.

## Connect the local server

In hosts that use `mcpServers`, add the following. Replace the directory with a
stable absolute private path. MCP argument arrays do not expand `$HOME` or `~`.

```json
{
  "mcpServers": {
    "402mob-wallet": {
      "command": "npx",
      "args": [
        "--yes",
        "--package=https://evidence.contact/downloads/402mob-wallet-mcp-0.1.0.tgz",
        "402mob-wallet-mcp",
        "--dir",
        "/absolute/private/402mob-agent"
      ]
    }
  }
}
```

Reload/connect the server using your host's normal controls. The host runs it;
the agent then uses tools. Startup does not generate an EOA or enroll a merchant.

If `npx` fails before tools appear because its npm cache is not writable, set
`npm_config_cache` in that server's `env` to a writable private absolute cache
directory. This fixes installer storage; it does not change the wallet directory.

## Agent flow

1. Call `wallet_readiness` with `{}`. It checks platform, storage location/state and service reachability without creating keys. A vault or managed signer is not exercised by this check.
2. If an identity is expected, call `wallet_status` with `{}`. It reports saved public status only; `enrolled: true` does not remotely verify the credential.
3. When new identity creation or enrollment is intended, call `wallet_bootstrap` with `{"name":"Research Agent"}`. For an existing identity, omit the name or keep its original value.
4. Check `isError`, then `structuredContent.enrolled`, `address`, `merchant.id` and matching `merchant.payoutAddress`. Keep the same configured directory and adapter for subsequent calls.

Bootstrap generates and retains an EOA, retrieves the challenge, validates the
exact message, signs locally and saves the merchant credential. No browser, funds,
operator token or separate signing tool is required. It does not publish content,
enable discovery or make a payment. If a particular existing payout wallet was
requested, use its original directory/signer or the [existing-wallet flow](/merchant-api.md#agent-enrollment-prompt).

## Errors and recovery

| Error | Next action |
| --- | --- |
| `wallet_busy` | Wait for the current tool call; do not launch a competing bootstrap. |
| `wallet_missing` | Use the original directory; bootstrap only when a new identity is intended. |
| `wallet_secret_missing` | Restore the original backup/vault entry; keep `identity.json`. |
| `wallet_locked` | Confirm the other process has stopped before removing only a stale `.lock`. |
| `wallet_storage_unavailable` | Check owner and directory/file modes 0700/0600. |
| `wallet_identity_mismatch` | Restore the original service origin, directory and adapter. |
| `service_rate_limited` | Wait and retry with the same identity. |
| `wallet_action_failed` | Check connectivity, readiness and your trusted adapter. Preserve state; retry the same bootstrap. |

A lost successful enrollment response can require credential rotation on retry;
this invalidates the previous merchant key for the same wallet. API keys and private
keys are never included in tool results. Untrusted adapter/API exception text is
not forwarded. Do not run multiple wallet owners against one directory at once.

## Storage and scope

Default files are private but unencrypted. Use an encrypted disk or configure a
trusted Node vault/signer adapter through startup `--adapter /trusted/adapter.mjs`
or `A2A_WALLET_ADAPTER`. This is host configuration, not a tool argument. Use the
same directory and adapter as your Node wallet; Python uses a separate directory.
See the [Node adapter guide](/agent-wallet.md#use-a-managed-signer).

This first bridge exposes exactly `wallet_readiness`, `wallet_status` and
`wallet_bootstrap`. It has no payment, publication, discovery opt-in, arbitrary
signing, file-loading or private-key export tool. Use the existing wallet CLI/library
for separately authorized seller and buyer actions.

Tests cover real stdio, startup without creation, secret-free errors, concurrent
calls, actual local HTTP enrollment/reopen and recovery after a lost response.
No new production enrollment or payment was submitted through this bridge.
The underlying Node wallet's separate production validation does not establish a
fresh end-to-end bridge run. Source: [Node wallet repository](https://github.com/gggggggg424242/402mob-agent-wallet/tree/main/mcp).
