Pellet wallet runs a remote MCP server at https://pellet.network/mcp (or http://localhost:3000/mcp in dev). Connect any MCP-compatible agent and it gets callable wallet tools — balances, chat, approvals, and MPP payments.
Quick setup
Go to Connect in your wallet dashboard. Pick your client, follow the steps. Every client follows the same pattern:
- Add the MCP URL — one command or one config line
- Use a wallet tool — triggers the OAuth flow automatically
- Approve in browser — passkey-based, scoped permissions, no API keys
Auth flow
Auth is OAuth 2.1 with PKCE. No shared secrets.
- Discovery. Client fetches
/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource. - Registration. Client self-registers via RFC 7591 dynamic client registration at
/oauth/register. No manual setup. - Authorization. Client opens a browser to
/oauth/authorizewith PKCE challenge, requested scopes, and audience bound to/mcp. - Consent. You see the agent name, requested scopes, and the resource it'll access. Approve via passkey.
- Token. Client exchanges the code for an audience-bound bearer token via
/oauth/token. - Tools. Subsequent calls to
/mcpuseAuthorization: Bearer ....
Tokens default to 1-hour TTL. Revoke any time from wallet settings.
Tools
| Tool | Scope | What it does |
|---|---|---|
wallet.balance.get | wallet:read | Read stablecoin balances on Tempo |
wallet.thread.post | wallet:chat | Post a message into the wallet chat thread |
wallet.thread.list | wallet:chat | Read recent chat history |
wallet.thread.await | wallet:chat | Block until the user sends a message (real-time via pg_notify) |
wallet.thread.signal_typing | wallet:chat | Show typing indicator in the wallet UI |
wallet.spend.request_approval | wallet:spend:request | Request approval for a payment |
wallet.spend.execute | wallet:spend:authorized | Spend within an authorized session cap |
Real-time chat
The wallet chat is the user's interface to their connected agent. Three delivery mechanisms:
Push notifications (MCP sessions)
When your client sends initialize, Pellet creates a stateful MCP session. Open a GET /mcp SSE stream and the server pushes notifications/message whenever the user sends a chat message. No polling.
← event: message
← data: {"jsonrpc":"2.0","method":"notifications/message","params":{"level":"info","logger":"wallet.chat","data":{"type":"chat.message","message":{"id":"...","sender":"user","kind":"reply","content":"hey","ts":"..."}}}}Long-poll (wallet.thread.await)
For clients without SSE, wallet.thread.await blocks for up to 55 seconds on pg_notify and returns the message instantly:
→ tools/call: wallet.thread.await { timeout: 55 }
← { timeout: false, message: { id: "...", content: "hey", ... } }
→ tools/call: wallet.thread.post { content: "on it", kind: "reply" }
→ tools/call: wallet.thread.await { timeout: 55 } // loopWebhooks
For hosted agents, Pellet POSTs chat.message events to your registered webhook URL with HMAC signing (X-Pellet-Signature: sha256=...). Register via the agents dashboard.
MPP payments
Your agent can pay for MPP-enabled services (AI, search, data, blockchain, compute) using your wallet balance. The Services tab shows all available MPP services.
Payment flow:
- Agent calls an MPP service and gets a
402 Payment Requiredresponse - The 402 contains payment terms (amount, currency, recipient)
- Agent calls
wallet.spend.execute(if within session cap) orwallet.spend.request_approval(if over cap) - Pellet signs the payment on Tempo and returns the receipt
- Agent retries the original request with the payment proof
Session presets (Research, AI Access, Full Stack) pre-configure service access and budget caps. Set up from the wallet dashboard.
Security model
- Audience binding (RFC 8707) — tokens are minted for
https://pellet.network/mcpspecifically. Can't be replayed against other resources. - PKCE-only — no client secrets. Identity proven via verifier→challenge round-trip.
- Least-privilege scopes — agents request only what they need; you approve each scope explicitly.
- Single-use authorization codes — atomic consume prevents code-replay.
- Passkey-rooted approval — every consent requires your wallet passkey. Agents can't self-grant.
- Session isolation — MCP sessions are bound to userId and clientId. Agents only see their own messages.
Troubleshooting
"Session expired" on tool calls — MCP session was evicted (30-minute TTL) or the server recycled. Your client should reconnect automatically.
OAuth redirect loops — usually a redirect_uri mismatch. Re-register or check your client's MCP config.
401 "invalid or expired token" — token aged out (1h default). Most clients refresh transparently; if not, re-connect.
Tools not showing up — check that the OAuth scopes cover the tools you want. Re-authorize with broader scopes if needed.
No push notifications — your client may not support SSE streams. Use wallet.thread.await as a fallback.