ouija-mcp
v0.1.1
Published
MCP server exposing ouija's identity-collapse rails: derive Solana wallet + Tor v3 .onion + Ed25519 keypair from one BIP-39 mnemonic, query mainnet/devnet balances, compute PDAs.
Readme
ouija-mcp
MCP server exposing ouija's identity-collapse rails to any MCP-capable agent.
One BIP-39 mnemonic → one Ed25519 keypair → three identities:
- a Solana wallet (
base58(pubkey)) - a Tor v3
.onionaddress (base32(pubkey || checksum || version)) - a deterministic storage namespace (the pubkey is a seed for PDAs)
This server lets agents do the derivation math, convert between encodings, query Solana balances on any cluster, and look up the deployed ouija-group program — without re-implementing any crypto.
Install
cd /Users/stacc/ouija-mcp
npm install
npm run buildThen register with Claude Code:
# from npm (recommended — auto-fetches latest)
claude mcp add ouija -s user -- npx -y ouija-mcp
# or from a local clone
claude mcp add ouija -s user -- node /Users/stacc/ouija-mcp/dist/index.jsOr wire into any MCP client by pointing it at npx -y ouija-mcp (stdio transport).
Tools
| Tool | What it does |
|---|---|
| derive_identity({mnemonic, passphrase?}) | Full identity: Ed25519 seed + pubkey + Solana address + .onion. Path m/44'/501'/0'/0' (matches Phantom/Solflare/Backpack). |
| onion_to_solana({onion}) | Tor v3 .onion → Solana wallet address |
| solana_to_onion({solana_address}) | Solana → .onion (math only — service may or may not be live) |
| ouija_get_sol_balance({address, cluster?}) | Lamports + SOL on mainnet / devnet / testnet / custom RPC URL |
| ouija_get_token_balances({address, cluster?}) | All SPL + Token-2022 holdings with non-zero balance |
| ouija_compute_pda({seeds, program_id}) | Generic PDA derivation. Seeds support utf8:, hex:, base58: prefixes. |
| ouija_group_program_info() | Deployed program ID + PDA layout + instruction list for the ouija-group Anchor program. |
Verification vector
Standard BIP-39 test mnemonic abandon × 11 + about at m/44'/501'/0'/0' MUST produce:
- Solana:
HAgk14JpMQLgt6rVgv7cBQFJWFto5Dqxi472uT3DKpqk - .onion:
6a3coysgu5nz3yzut3kcwfpcgl3fdd6cb5p42ty5mtub7g6sld35qlid.onion
Verified across:
- Go bridge (ouija-bridge,
SeedFromMnemonic+tor.GetTorV3Hostname) - This MCP server (
@noble/curves+ manual SLIP-0010 + base32 encoding) - Phantom wallet (import the mnemonic, derived address matches)
Any other implementation that produces a different result has a bug.
Why this exists
Agents working in the Solana × Tor space repeatedly need the same primitives:
- "what Solana wallet does this .onion correspond to"
- "derive everything from a mnemonic"
- "what's the balance on devnet"
- "compute the PDA for these seeds"
Re-implementing in each agent / project is wasteful and error-prone (especially the base32 + checksum + version byte ordering for v3 onions, which is easy to get wrong). This server is the single source of truth.
Related work
ouija(Go) — Cwtch fork with the same identity primitive baked in: /Users/stacc/ouijaouija-bridge(Go FFI) — exposes the same derivation to Flutter viac_exports: /Users/stacc/ouija-bridgeouija-ui(Flutter) — Cwtch UI with the wallet panel: /Users/stacc/ouija-uiouija-group(Anchor) — hybrid group state program (Solana + optional Tor relay): /Users/stacc/ouija-group. Deployed on mainnet atEsrqfUpGRmYppZJ6spQtQJ2QzdSCQHYhvYXXHgpBRqhG(default) and on devnet atBcwsnKq3DLoTsp1AuP3Nuu4Z1WJuLa162DCZVok7aRKv(free testing —solana airdrop 1 <addr> --url devnet).SKILL.md— agent-facing skill explaining when + how to use these rails:/Users/stacc/.claude/skills/ouija/SKILL.md
License
Same as parent project (Cwtch is MIT; ouija additions inherit).
