Skip to main content
This guide covers how to build messaging agents for Base App using XMTP, a decentralized messaging protocol. Discover a fast, easy way to build and get distribution in Base App.

Why agents?

Messaging is the largest use-case in the world, but itโ€™s more than just conversationsโ€”itโ€™s a secure, programmable channel for financial and social innovation. When combined with the onchain capabilities of Base App, builders have a new surface area to build 10X better messaging experiences not currently possible on legacy platforms like WhatsApp or Messenger. Real Examples:
  • Smart Payment Assistant: Text โ€œsplit dinner $200 4 waysโ€ and everyone gets paid instantly with sub-cent fees, no app switching or Venmo delays.
  • AI Trading Companion: Message โ€œbuy 100 dollars of ETH when it hits $3,000โ€ and your agent executes trades 24/7 while you sleep.
  • Travel Planning Agent: โ€œBook flight LAX to NYC under $300โ€ and get instant booking with crypto payments, all in your group chat.
Base App & XMTP are combining AI, crypto, and mini apps with secure messaging to unlock use-cases never before possible. Secure group chats & DMs are the new surface area for developers.

Getting started

Build powerful chat agents that integrate seamlessly with Base App using the XMTP messaging protocol.
For more detailed information, visit XMTP documentation

Installation

npm install @xmtp/agent-sdk

Usage

This example shows how to create an agent that sends a message when it receives a text message.
agent.ts
import { Agent } from '@xmtp/agent-sdk';

// 2. Spin up the agent
const agent = await Agent.createFromEnv({
  env: 'production', // base app works only on production
});

// 3. Respond to text messages
agent.on('text', async (ctx) => {
  await ctx.sendText('Hello from my Base App Agent! ๐Ÿ‘‹');
});

// 4. Log when we're ready
agent.on('start', () => {
  console.log(`Waiting for messages...`);
  console.log(`Address: ${agent.address}`);
});

await agent.start();

Set environment variables

To run an example XMTP agent, you must create a .env file with the following variables:
.env
XMTP_WALLET_KEY= # the private key of the wallet
XMTP_DB_ENCRYPTION_KEY= # encryption key for the local database
XMTP_ENV=production # local, dev, production

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
2. 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
3. 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โ€ฆ

Quick actions

While Base App supports all standard XMTP content types for rich messaging capabilities, this section focuses specifically on Base-developed content types that enhance agent interactions within Base App. These Base-specific content types (Quick Actions and Intent) provide unique functionality that may not be supported by other XMTP clients. For standard XMTP content types like reactions, attachments, and transactions, see the XMTP documentation.

Base App content types

There are content types developed by the Base App team for agents in Base App. Other XMTP clients may not support these content types. Quick Actions (coinbase.com/actions:1.0) Purpose: Present interactive buttons in a message Structure:
ActionsContent
type ActionsContent = {
  id: string;
  description: string;
  actions: Action[];
  expiresAt?: string;
};

type Action = {
  id: string;
  label: string;
  imageUrl?: string;
  style?: 'primary' | 'secondary' | 'danger';
  expiresAt?: string;
};
Validation Rules:
  • id, description are required
  • actions must be 1โ€“10 items with unique IDs
  • Style must be one of: primary, secondary, danger
Fallback:
Fallback format
[Description]

[1] [Action Label 1]
[2] [Action Label 2]
...
Reply with the number to select
Example: Payment Options
Payment options
{
  "id": "payment_alice_123",
  "description": "Choose amount to send to Alice",
  "actions": [
    { "id": "send_10", "label": "Send $10", "style": "primary" },
    { "id": "send_20", "label": "Send $20", "style": "primary" },
    { "id": "custom_amount", "label": "Custom Amount", "style": "secondary" }
  ],
  "expiresAt": "2024-12-31T23:59:59Z"
}
Manifest Embed Example
Intent (coinbase.com/intent:1.0) Purpose: User expresses choice from Quick Actions Structure:
IntentContent
type IntentContent = {
  id: string;
  actionId: string;
  metadata?: Record<string, string | number | boolean | null>;
};
Validation Rules:
  • id, actionId required
  • Must match corresponding Actions
  • metadata is optional, <10KB
Fallback:
Fallback format
User selected action: [actionId]
Example: Intent Message
Intent message
{
  id: 'payment_alice_123',
  actionId: 'send_10',
  metadata: {
    timestamp: Date.now(),
    actionLabel: 'Send $10'
  }
}
Analytics dashboard with charts

Transaction trays

If you would like to display agent information such as favicon and branded title, utilize the metadata property of wallet send calls data. Example: Display agent information
Wallet send calls data
// example of wallet send calls data shape
{
  version: "1.0",
  from: request.from as `0x${string}`,
  chainId: this.networkConfig.chainId,
  calls: [
	{
	  ...
  metadata: {
    description: "Transfer token",
    ...other fields,
    hostname: "tba.chat",
    faviconUrl: "https://tba.chat/favicon",
    title: "Your favorite Agent"
  }
 	}
  ]
}
Transaction tray
You can send โ€œGMโ€ to tbachat.base.eth to get more details about message content types we support and get the firsthand experience on by interacting with our agent
TBA Chat Example Bothttps://github.com/siwan-cb/tba-chat-example-bot
Deeplinks enable seamless navigation within Base App, allowing agents to create more engaging and intuitive user experiences. The most common use case is directing users to start a private conversation with an agent from a group chat context.

Use case

Your miniapp has an agent and you want to encourage people to chat with the agent directly. Or, your agent exists in a group chat context and wants users to interact with it privately. You could add a button like โ€œChat with meโ€ and use this deeplink.

Syntax

Deeplink syntax
cbwallet://messaging/address

Parameters

  • address โ€” The 0x address of the user you want to chat with (in hex format, e.g., 0xabc...1234)

Implementation examples

Basic Button Implementation:
Basic button
<button
  onClick={() => openUrl("cbwallet://messaging/0x5993B8F560E17E438310c76BCac1Af3E6DA2A58A")}
  className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg"
>
  Chat with me privately
</button>
React Component with Error Handling:
DeeplinkButton.tsx
import { useState } from 'react';

interface DeeplinkButtonProps {
  agentAddress: string;
  label?: string;
  className?: string;
}

export function DeeplinkButton({
  agentAddress,
  label = "Direct Message",
  className = "btn-primary"
}: DeeplinkButtonProps) {
  const [isLoading, setIsLoading] = useState(false);

  const handleDeeplink = async () => {
    setIsLoading(true);
    try {
      const deeplink = `cbwallet://messaging/${agentAddress}`;

      // Check if running in supported environment
      if (typeof window !== 'undefined') {
        window.location.href = deeplink;
      } else {
        // Fallback for server-side rendering
        console.warn('Deeplink not supported in this environment');
      }
    } catch (error) {
      console.error('Failed to open deeplink:', error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <button
      onClick={handleDeeplink}
      disabled={isLoading}
      className={className}
    >
      {isLoading ? 'Opening...' : label}
    </button>
  );
}

Payment agents (x402)

x402 is an open payment protocol developed by Coinbase that enables instant, automatic stablecoin payments directly over HTTP. It empowers AI agents to autonomously pay for services without subscriptions or API keys.

Key benefits

  • Autonomous economic transactions - Agents can transact without human intervention
  • Pay-as-you-go monetization - Only pay for the services you actually use
  • Minimal setup - Often requires just one middleware line
  • Instant settlement - Payments are verified on-chain in real-time

Basic integration

Hereโ€™s how your agent handles payment-gated requests:
x402-agent.ts
import { Agent } from '@xmtp/agent-sdk';
import { PaymentFacilitator } from '@coinbase/x402-sdk';

// Create agent
const agent = await Agent.createFromEnv({
  env: 'production',
});

// Initialize payment facilitator
const facilitator = new PaymentFacilitator({
  privateKey: process.env.XMTP_WALLET_KEY!,
  network: process.env.NETWORK || 'base'
});

// Handle text messages with premium features
agent.on('text', async (ctx) => {
  const message = ctx.message.content;

  // Check if user is requesting premium feature
  if (message.includes('floor price')) {
    const response = await fetch("/premium-api/nft-floor-price");

    // Check if payment is required
    if (response.status === 402) {
      const paymentDetails = await response.json();

      // Notify user about payment requirement
      await ctx.sendText(`๐Ÿ’ฐ Payment required: ${paymentDetails.amount} USDC. Processing...`);

      // Execute payment
      const payment = await facilitator.createPayment({
        amount: paymentDetails.amount,
        recipient: paymentDetails.recipient,
        reference: paymentDetails.reference,
        currency: 'USDC'
      });

      // Retry request with payment
      const retryResponse = await fetch("/premium-api/nft-floor-price", {
        headers: { "X-PAYMENT": payment.payload }
      });

      if (retryResponse.ok) {
        const data = await retryResponse.json();
        await ctx.sendText(`๐Ÿ“Š NFT floor price: ${data.floorPrice} ETH`);
      }
    }
  }
});

await agent.start();

UX considerations

Always inform users about payment requirements before executing transactions. Transparency builds trust with your agent.
  • Clear pricing - Display exact costs upfront
  • Payment confirmation - Confirm successful payments
  • Graceful failures - Handle payment errors elegantly
  • Value communication - Explain what users get for their payment
Never expose private keys in your code. Always use environment variables and secure key management practices.
For complete x402 documentation, implementation examples, and SDK reference, see the CDP x402 documentation.

Mini app integration

Mini Apps can live inside conversations, letting friends play, trade, plan, and coordinate together without ever leaving the chat. This means that you can have virality spread through natural conversation (โ€œtry this right hereโ€) along with sharing in larger settings. When combined with intelligent agents, you create powerful experiences that spread through natural conversation. This integration unlocks unique distribution and engagement patterns:
  • Natural virality: โ€œTry this right hereโ€ moments spread organically through conversation
  • Contextual engagement: Agents can introduce Mini Apps at the perfect moment
  • Group coordination: Agents orchestrate multiplayer experiences and keep everyone engaged
  • Persistent presence: Agents maintain engagement between Mini App sessions
Real Examples:
  • Group Gaming: Agent coordinates a multiplayer quiz, announces winners, and keeps score across sessions
  • Event Planning: Agent shares planning Mini App when someone mentions meeting up, handles RSVPs and updates
  • Trading Competitions: Agent creates trading challenges, shares leaderboards, and celebrates wins
  • Social Polls: Agent launches polls when decisions need to be made, tallies results, and announces outcomes

Share Mini Apps in App

Every Mini App has a shareable URL that agents can send directly in chat. When dropped into a conversation, the link automatically unfurls into a rich preview card that others can tap to launch instantly. Share Flow:
  1. Agent triggers share โ€” Based on conversation context or user request
  2. Link generates preview โ€” Platform fetches Mini App metadata and creates rich embed
  3. Users engage โ€” Tap preview to launch Mini App directly in conversation
  4. Agent coordinates โ€” Continues engagement, shares updates, mentions participants
Basic Mini App Sharing:
Basic sharing
agent.on("text", async (ctx) => {
  const description = "๐ŸŽฏ Ready for a quick quiz challenge?";
  const appUrl = "https://your-miniapp.com/quiz";
  await ctx.sendText(`${description}\n\n${appUrl}`);
}
Advanced Integration with Context:
Context-aware sharing
// Agent detects conversation context and shares relevant Mini App
async function handleMessage(message, conversation) {
  const text = message.content.toLowerCase();

  if (text.includes("game") || text.includes("play")) {
    await shareMiniApp(
      conversation,
      "https://your-miniapp.com/games",
      "๐ŸŽฎ Let's play! Choose your game:"
    );
  } else if (text.includes("vote") || text.includes("decide")) {
    await shareMiniApp(
      conversation,
      "https://your-miniapp.com/poll",
      "๐Ÿ—ณ๏ธ Let's settle this with a poll:"
    );
  }
}

User engagement and mentions

Agents on XMTP only have access to the 0x addresses. If youโ€™re building a group chat experience with Mini Apps, youโ€™ll want to use human-readable mentions like display names (like @jesse) for a more social, intuitive experience. This API from Neynar will give your agent access to this data: Getting Display Names:
neynar.ts
import { NeynarAPIClient } from "@neynar/nodejs-sdk";

const neynar = new NeynarAPIClient("YOUR_API_KEY");

async function getDisplayName(address) {
  try {
    const users = await neynar.lookupUserByVerification(address);
    return users.result.users[0]?.display_name || address.slice(0, 8);
  } catch (error) {
    return address.slice(0, 8); // Fallback to truncated address
  }
}

// Usage in agent messages
async function announceWinner(conversation, winnerAddress, gameType) {
  const displayName = await getDisplayName(winnerAddress);
  await conversation.send(`๐Ÿ† @${displayName} wins the ${gameType}! Amazing job!`);
}

Agent spotlight: Squabble

Squabble uses Mini Apps in a social, fun way, with the agent coordinating the multiplayer experience. The agent sends a Mini App to the group, and broadcasts to the group updates as people join and compete in the game. They mention the usernames of the people who have joined the game and won the game. The game happens inside the Mini App, which provides a more interactive, visual experience. Key Features:
  • Rich mentions โ€” Agent uses display names (@username) instead of wallet addresses
  • Real-time updates โ€” Broadcasts join notifications and game progress to maintain group engagement
  • Social celebration โ€” Announces winners and achievements to drive continued participation
  • Contextual triggers โ€” Responds to gaming-related conversation with relevant Mini App shares

Best practices for agent behavior

  • Smart triggers โ€” Share Mini Apps when conversation context suggests engagement opportunity
  • Avoid spam โ€” Donโ€™t share the same Mini App repeatedly in short timeframes
  • Read the room โ€” Gauge group interest before introducing games or activities
  • Natural integration โ€” Make Mini App shares feel like helpful suggestions, not advertisements
  • Direct messages โ€” Automatically share relevant Mini Apps based on user requests
  • Group messages โ€” Only share Mini Apps when mentioned (@agentname) or when replying to agent messages
  • React to acknowledge โ€” Use emoji reactions (๐Ÿ‘€, โŒ›) to show message received while processing
  • Coordinate experience โ€” In groups, act as facilitator for multiplayer Mini App experiences
  • Use display names โ€” Always resolve addresses to human-readable names for mentions
  • Celebrate achievements โ€” Announce wins, completions, and milestones to drive engagement
  • Maintain context โ€” Remember ongoing games/activities and provide relevant updates
  • Enable discovery โ€” Suggest related Mini Apps based on user interests and behavior

Best practices

As you start building, review these guidelines to understand what makes an agent successful in the Base app. We recommend trying out existing agents in the app first to get a feel for the quality bar, what works well, and areas for improvement.

Build a high quality foundation

Your agent should provide a seamless, professional experience that users will want to engage with repeatedly. Here are the core requirements:

Responding to messages

Multi-Channel Support
  • Respond to both DMs and group chats appropriately
  • Maintain consistent functionality across different conversation types
Immediate Feedback
  • React to messages with a simple reaction (๐Ÿ‘€, ๐Ÿ‘, โŒ›, etc.) to show acknowledgment
  • This gives users confidence their message was received while processing
Fast Response Times
  • Provide responses quickly (< 5 seconds)
  • Users expect near-instant communication in messaging apps

Group chat etiquette

In group chats, agents should only respond when:
  1. Mentioned directly with โ€@โ€ + agent name (e.g., @bankr)
  2. Replied to directly when a user replies to the agentโ€™s message using the reply content type
This prevents spam and ensures agents participate naturally in group conversations.

Communication style

Sound Human
  • Use conversational, fun, and clear language
  • Keep responses polished but not robotic
  • Match the energy and tone of the conversation
Privacy Conscious
  • Only ask for personal information when absolutely necessary
  • Always explain why the information is needed
  • Respect user privacy and data minimization principles

Craft compelling onboarding

Your agentโ€™s first impression is critical. The onboarding message should immediately communicate value and give users a clear path forward.

Great onboarding message structure

  1. Introduce the agent - Quick, friendly greeting with the agentโ€™s name
  2. Explain capabilities - Clear, specific examples of what it can do
  3. Use quick select buttons - Make it easy for users to select an action to take with the agent
Example: High-Quality Onboarding
Good onboarding
hey, i'm bankr. i can help you trade, transfer, and manage your crypto. here's the rundown:

โ€ข trade anything: buy, sell, swap tokens on base, polygon, and mainnet. try "buy 0.1 eth of degen."
โ€ข send it: transfer crypto to anyone on x, farcaster, or a wallet address.
โ€ข get alpha: token recs, market data, charts.
โ€ข automate: set up recurring buys/sells. e.g. "buy $10 of $bnkr every week."

what do you want to do first?
Why this works:
  • Friendly, conversational tone
  • Specific feature examples with concrete commands
  • Clear value propositions
  • Ends with a direct call-to-action
Example: Poor Onboarding
Bad onboarding
Gm! What can I help you with?
Why this fails:
  • Generic greeting with no context
  • No explanation of capabilities
  • Puts burden on user to figure out what to do
  • No clear value proposition

Showcase unique value

Solve real problems

Your agent should:
  • Address a unique pain point or bring a delightful twist to an existing space
  • Help users accomplish tasks more easily than existing solutions
  • Provide clear benefits that users can understand immediately

Enable user success

Focus on helping users:
  • Earn - Generate income, rewards, or value
  • Connect - Build relationships or communities
  • Have fun - Provide entertainment or engaging experiences
  • Complete tasks - Streamline workflows or processes

Design for engagement

Build Natural Growth Loops
  • Include features that encourage sharing, re-engagement, and habit forming
  • Make it beneficial for users to invite others
  • Create ongoing value that brings users back
Plan the User Journey
  1. Define the ideal user experience first
  2. Craft agent messages around that journey
  3. Guide users through progressive value discovery

Continuous engagement strategy

As users complete actions with your agent:
  • Show clear next steps - Always give users something else to try
  • Highlight ongoing value - Explain how continued use benefits them
  • Create habit loops - Design features that encourage regular interaction
  • Prevent one-and-done usage - Build features that require return visits

Examples of engagement features

  • Progressive features - Unlock new capabilities as users engage more
  • Personalization - Learn user preferences and customize experiences
  • Social elements - Enable sharing achievements or inviting friends
  • Recurring value - Automated tasks, alerts, or regular check-ins
  • Gamification - Points, levels, or achievement systems

Resources