This guide will walk you through creating, testing, and deploying your first XMTP messaging agent. By the end, you’ll have a fully functional agent that can send and receive messages on the XMTP messaging network.

Prerequisites

Before you begin, make sure you have:
  • Node.js (v20 or higher)
  • Git
  • A code editor
  • Basic knowledge of JavaScript/TypeScript

Helpful Resources

Development Guide

1

Set Up Your Development Environment

Clone the XMTP Agent Examples Repository:
git clone https://github.com/ephemeraHQ/xmtp-agent-examples.git
cd xmtp-agent-examples
2

Install Dependencies

Install all required packages:
npm install
3

Generate Keys for Your Agent

Run the key generation script to create your agent’s wallet:
npm run gen:keys
This creates a .env file with:
WALLET_KEY=0x... # Your agent's private key
ENCRYPTION_KEY=... # Encryption key for local database
XMTP_ENV=dev # Environment (local, dev, production)
4

Write Your Agent Logic

Create a basic agent that responds to messages:
// import the xmtp sdk
import { Client, type XmtpEnv, type Signer } from "@xmtp/node-sdk";

// encryption key, must be consistent across runs
const encryptionKey: Uint8Array = ...;
const signer: Signer = ...;
const env: XmtpEnv = "dev";

// create the client
const client = await Client.create(signer, {encryptionKey, env });
// sync the client to get the latest messages
await client.conversations.sync();

// listen to all messages
const stream = await client.conversations.streamAllMessages();
for await (const message of  stream) {
  // ignore messages from the agent
  if (message?.senderInboxId === client.inboxId ) continue;
  // get the conversation by id
  const conversation = await client.conversations.getConversationById(message.conversationId);
  // send a message from the agent
  await conversation.send("gm");
}
Then run your agent:
npm run dev

Getting the address of a user

Each user has a unique inboxId for retrieving their associated addresses (identifiers). One inboxId can have multiple identifiers like passkeys or EVM wallet addresses.
const inboxState = await client.preferences.inboxStateFromInboxIds([
  message.senderInboxId,
]);
const addressFromInboxId = inboxState[0].identifiers[0].identifier;

Example Implementations

Explore these examples in the /examples folder:
5

Test Your Agent

Development Testing

  1. Start your agent:
npm run dev
  1. Test on xmtp.chat:
  • Go to https://xmtp.chat
  • Connect your personal wallet
  • Switch to Dev environment in settings
  • Start a new conversation with your agent’s public address (from .env)
  • Send a test message and verify the agent responds

Production Testing

  1. Update environment:
XMTP_ENV = production;
  1. Test on Base App:
  • Open Base App mobile app
  • Go to messaging
  • Start conversation with your agent’s address
  • Verify functionality
6

Get a Basename for Your Agent

Give your agent a human-readable name:
  1. Import agent wallet to Base App extension:
  • Install Base App browser extension
  • Import using your agent’s private key
  1. Purchase a basename:
  • Visit https://base.org/names
  • Connect your agent’s wallet
  • Search and purchase your desired basename (e.g., myagent.base.eth)
  • Set as primary name
  1. Verify setup:
  • Your agent can now be reached via the basename instead of the long address
  • Users can message myagent.base.eth instead of 0x123…
7

Deploy Your Agent

  • Visit https://railway.app
  • Connect your GitHub repository
  • Add environment variables in Railway dashboard:
    • XMTP_ENV=production
    • WALLET_KEY=your_agent_private_key
    • ENCRYPTION_KEY=your_agent_encryption_key
  • Deploy and monitor logs

Option 2: Other Platforms

Heroku, Vercel, or any Node.js hosting platform:
  • Ensure your package.json has the correct start script
  • Set environment variables in your hosting platform
  • Deploy your repository

Monitor and Maintain

Best Practices

  1. Logging: Add comprehensive logging to track agent activity
  2. Error Handling: Implement try-catch blocks for network issues
  3. Rate Limiting: Respect XMTP rate limits in your agent logic
  4. Security: Never expose private keys; use environment variables

Monitoring

Add to your agent for basic monitoring:
const inboxState = await client.preferences.inboxState();
const address = inboxState.identifiers[0].identifier;
const inboxId = client.inboxId;
const installationId = client.installationId;
const conversations = await client.conversations.list();

console.log(`
✓ XMTP Client:
• InboxId: ${inboxId}
• Address: ${address}
• Conversations: ${conversations.length}
• Installations: ${inboxState.installations.length}
• InstallationId: ${installationId}
• Network: ${process.env.XMTP_ENV}`);

console.log(`Agent started. Address: ${xmtp.address}`)
console.log(`Environment: ${process.env.XMTP_ENV}`)
console.log(`Listening for messages...`)