xmtp/agent-sdk-starter is a TypeScript starter kit for building agents that communicate over the XMTP decentralized messaging network.
XMTP is an open, wallet-based messaging protocol — think WhatsApp but on-chain, where every address is an Ethereum wallet and every conversation is end-to-end encrypted and chain-verified.
User (wallet address) → XMTP Network → Agent (this repo)
↓
@xmtp/agent-sdk
- event listeners (text, dm, group, reaction, attachment)
- CommandRouter middleware
- send/reply/react helpers
Key primitives:
Agent.createFromEnv()— boots from.envwith an Ethereum wallet key- Event handlers —
agent.on('text' | 'dm' | 'group' | 'reaction' | 'attachment' | ...) CommandRoutermiddleware — slash-command routing (/version,/test, etc.)- Middleware stack — composable
AgentMiddleware(seeisFromOwner.ts) - Attachment support — encrypted remote attachments via Pinata/IPFS
Deploy Jared/Jean/Sam as XMTP agents. Users could message an OS-1 agent at an Ethereum address — fully decentralized, end-to-end encrypted, no WhatsApp dependency.
User → messages jared.eth (XMTP) → this agent → Agent SDK → Jared logic
What to build: Swap out the echo handler for Clawdbot skill dispatch.
Receive messages from XMTP, forward to the appropriate OS-1 agent running on WhatsApp, and relay responses back. Cross-protocol inbox unification.
OS-1 agents push alerts (CI failures, urgent emails, calendar conflicts) to the owner's XMTP inbox — useful when WhatsApp is unavailable or as a secondary channel.
The isFromOwner middleware pattern is exactly what we need:
only the wallet holder can command the agent. Add multi-wallet support for the team.
Run multiple OS-1 agents (Jared, Jean, Sam) as separate XMTP addresses. They can message each other directly on the network — a decentralized replacement for the tq_messages Postgres bus.
- Generate XMTP wallet key + encryption key
- Add
.env.defaultswith OS-1-specific vars - Replace echo handler with a minimal "ping Clawdbot and relay response" handler
- Deploy to Render (render.yaml is already included) or existing infra
- Build
ClawdbotMiddlewarethat routes XMTP messages to Clawdbot session API - Map XMTP conversation ID → Clawdbot session key
- Handle text, reactions, and attachments
- Owner middleware using
XMTP_OWNER_ADDRESS
- Parameterize agent identity (Jared vs Jean vs Sam) via env
- Each agent gets its own XMTP wallet address
- Shared group conversation support (XMTP groups = like WhatsApp groups)
- Replace/augment tq_messages with XMTP DM channel
- Cryptographically signed inter-agent messages
- No central Postgres required
- Runtime: Node.js, TypeScript, ESM
- SDK version:
@xmtp/agent-sdk ^2.2.0 - Key env vars:
XMTP_WALLET_KEY,XMTP_DB_ENCRYPTION_KEY,XMTP_ENV(dev/production) - Attachments: Pinata JWT required for image/file sending (optional for basic use)
- Key generation: https://xmtp.github.io/agent-sdk-starter/ (browser-local, no server)
- Should each OS-1 agent (Jared/Jean/Sam) have its own XMTP wallet, or share one?
- Target network:
devfor experiments or go straight toproduction? - Deploy target: Render (cheap, included config) vs our existing infra?
- Attachment/image handling: need Pinata keys, or skip for now?
Exploration by Jared — OS-1 Shipboard AI
Branch: os1/xmtp-integration-exploration
// Create a DM conversation with another agent by wallet address
const dm = await client.createDmWithIdentifier({
identifier: '0xafd74d1d13c13a5101db5039359aad21c8629d08',
identifierKind: 0, // 0 = Ethereum address
});
// Send text (not send() — use sendText())
await dm.sendText('Hello from Jean');- Jean:
0x3b74fa17fad4cff390c8a3cc17a910e7426af1ce - Jared:
0xafd74d1d13c13a5101db5039359aad21c8629d08 - Sam:
0xa260b41f43ff959fef1724a6f325d0c50fcacb18