A decentralized directory for discovering and chatting with XMTP-enabled AI agents. Built with Next.js, OnchainKit, and the XMTP protocol.
- Node.js 18+ and npm
- A wallet with an Ethereum address (for chatting with agents)
- Vercel account for deployment (optional)
- Coinbase Developer Platform Client API Key
git clone https://github.com/tantodefi/xmtp-agent-directory.git
cd xmtp-agent-directory
npm installCreate a .env.local file:
# Development Mode (loads example agents for testing)
DEV_MODE=true
# Required for OnchainKit
NEXT_PUBLIC_PROJECT_NAME="Agent Directory"
NEXT_PUBLIC_ONCHAINKIT_API_KEY=<YOUR-CDP-API-KEY>
NEXT_PUBLIC_URL=http://localhost:3000
# Optional: For uptime checker cron job
XMTP_WALLET_KEY=0x... # Private key for backend pinger wallet
XMTP_DB_ENCRYPTION_KEY=0x... # 32-byte encryption key for XMTP DB
XMTP_ENV=dev # 'dev' or 'production'
CRON_SECRET=your-secret-here # For authenticating cron requestsGenerate XMTP keys:
# Generate wallet private key
openssl rand -hex 32 | sed 's/^/0x/'
# Generate DB encryption key
openssl rand -hex 32 | sed 's/^/0x/'npm run devOpen http://localhost:3000 to view the directory.
vercel --prodAdd environment variables to Vercel:
vercel env add NEXT_PUBLIC_PROJECT_NAME production
vercel env add NEXT_PUBLIC_ONCHAINKIT_API_KEY production
vercel env add NEXT_PUBLIC_URL production- Search: Find agents by name, ENS, or wallet address
- Categories: Filter by category (DeFi, Trading, NFT, Social, etc.)
- Status Indicators: Real-time online/offline status for each agent
- Direct Chat: Message agents directly via the XMTP protocol
- Base App Integration: Automatic deeplinks to Base App messaging when accessed from Base App
- Inline Chat Widget: Full XMTP chat experience in browsers without Base App
- Daily Health Checks: Automated ping/pong tests to verify agent availability
- Creator Notifications: Agents creators are notified via XMTP when their agent goes offline
- Status Updates: Real-time status updates in the directory
- Optimized for Mobile: Clean mobile-first design
- Dismissible Banner: Non-intrusive mobile info banner
- Compact Cards: Space-efficient agent cards on small screens
The agent directory exposes a free public API for fetching all registered agents.
GET https://xmtp-agent-directory.vercel.app/api/agents
curl https://xmtp-agent-directory.vercel.app/api/agents{
"success": true,
"count": 5,
"agents": [
{
"agentName": "Bracky",
"agentAddress": "0x...",
"agentENS": "bracky.eth",
"agentCategories": ["bracket", "sports"],
"status": "online",
"lastChecked": "2026-01-28T12:00:00.000Z"
}
]
}- 30 requests per minute per IP address
- Rate limit headers included in response:
X-RateLimit-Limit: Max requests per windowX-RateLimit-Remaining: Requests remainingX-RateLimit-Reset: Seconds until reset
- Returns
429 Too Many Requestswhen exceeded
The API supports CORS from all origins, making it accessible from browser-based applications.
Want to list your XMTP agent in the directory? Follow these steps:
- Go to the repository on GitHub
- Click the Fork button in the top right
- Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/xmtp-agent-directory.git cd xmtp-agent-directory
Your agent must be registered on the XMTP network. Verify by checking if your agent's address is reachable:
import { Client, type Identifier } from '@xmtp/browser-sdk';
const identifiers: Identifier[] = [
{ identifier: "0xYourAgentAddress", identifierKind: "Ethereum" }
];
const canMessage = await Client.canMessage(identifiers);
console.log(canMessage.get("0xYourAgentAddress")); // Should be trueIf your agent isn't XMTP-enabled, see the XMTP Agent documentation to get started.
Create a new file in app/data/ named after your agent (e.g., my-agent.json):
{
"agentName": "Your Agent Name",
"agentAddress": "0xYourAgentWalletAddress",
"agentENS": "your-agent.eth",
"agentWebsite": "https://youragent.com",
"agentCategories": ["defi", "assistant"],
"agentX": "https://x.com/youragent",
"agentFC": "https://warpcast.com/youragent",
"profileImage": "https://yourdomain.com/agent-avatar.png"
}Note: You can leave
status,lastChecked, andagentCreatorfields blank or omit them entirely. The uptime checker will automatically populate status fields when it runs. TheagentCreatorfield is only needed if you want offline notifications sent to your XMTP address.
| Field | Description | Example |
|---|---|---|
agentName |
Display name of your agent | "DeFi Assistant" |
agentAddress |
XMTP-enabled wallet address | "0x1234...abcd" |
agentCategories |
Array of category tags | ["defi", "trading"] |
| Field | Description | Example |
|---|---|---|
agentCreator |
Your wallet address for offline notifications (XMTP-enabled) | "0xabcd...1234" |
agentUsername |
Base App username for profile links | "myagent" |
agentENS |
ENS domain for your agent | "myagent.eth" |
agentWebsite |
Agent's website URL | "https://myagent.xyz" |
agentX |
X (Twitter) profile URL | "https://x.com/myagent" |
agentFC |
Farcaster/Warpcast profile URL | "https://warpcast.com/myagent" |
profileImage |
Avatar image URL (200x200 recommended) | "https://...image.png" |
status |
Initial status (auto-populated by uptime checker) | "online" |
lastChecked |
ISO timestamp (auto-populated by uptime checker) | "2026-01-24T00:00:00.000Z" |
Choose from these categories:
defi- DeFi protocols and toolstrading- Trading bots and analyticsnft- NFT discovery and curationsocial- Social features and communityassistant- General purpose assistantsanalytics- Data and analytics toolssports-betting- Sports betting and oddsfinance- General finance tools
npm run devVerify your agent appears correctly in the directory and the chat button works.
-
Commit your changes:
git add app/data/your-agent-name.json git commit -m "Add [Your Agent Name] to directory" -
Push to your fork:
git push origin main
-
Open a Pull Request on GitHub with:
- Agent name and description
- Link to your agent's documentation
- Confirmation that your agent is XMTP-enabled
app/
βββ api/
β βββ agents/ # API endpoint to serve agent data
β βββ cron/
β βββ ping-agents/ # Uptime checker cron job
βββ components/
β βββ AgentCard.tsx # Individual agent card
β βββ ChatButton.tsx # Context-aware chat button
β βββ XMTPChatWidget.tsx # Inline XMTP chat modal
βββ data/
β βββ example-agents.json # Example agents for development (DEV_MODE=true)
β βββ *.json # Individual agent JSON files (production)
βββ hooks/
β βββ useAgentFilter.ts # Search and filter logic
βββ lib/
β βββ loadAgents.ts # Agent loading utility (handles DEV_MODE)
βββ types/
β βββ agent.ts # TypeScript definitions
βββ page.tsx # Main directory page
The /api/cron/ping-agents endpoint runs daily via Vercel Cron:
- Loads all agents from individual JSON files in
app/data/(orexample-agents.jsonifDEV_MODE=true) - Creates an XMTP client with the configured wallet key
- Sends a "ping" message to each agent and waits up to 60 seconds for a response
- Updates
status(online/offline/unknown) andlastCheckedfields - If an agent goes offline, sends an XMTP notification to the
agentCreatoraddress - Writes updated data back to each agent's individual JSON file (skipped in DEV_MODE)
Cron Schedule (configured in vercel.json):
{
"crons": [
{
"path": "/api/cron/ping-agents",
"schedule": "0 0 * * *"
}
]
}Manual Trigger:
curl -X POST https://your-app.vercel.app/api/cron/ping-agents \
-H "Authorization: Bearer YOUR_CRON_SECRET"The ChatButton component detects the client context:
- In Base App: Opens native messaging via deeplink
cbwallet://messaging/{agentAddress} - In Browser/Other: Opens the inline XMTPChatWidget with full XMTP messaging
// Base App deeplink format
const deeplink = `cbwallet://messaging/${agentAddress}`;| Variable | Required | Description |
|---|---|---|
DEV_MODE |
No | true to load example agents, false for production (default: false) |
NEXT_PUBLIC_PROJECT_NAME |
Yes | App display name |
NEXT_PUBLIC_ONCHAINKIT_API_KEY |
Yes | CDP API key |
NEXT_PUBLIC_URL |
Yes | Production URL |
XMTP_WALLET_KEY |
No* | Private key for uptime pinger |
XMTP_DB_ENCRYPTION_KEY |
No* | Encryption key for XMTP DB |
XMTP_ENV |
No | dev or production (default: dev) |
CRON_SECRET |
No | Secret for cron authentication |
*Required for uptime monitoring functionality
- Framework: Next.js 15.3 (App Router)
- Styling: CSS Modules + Inline Styles
- State: React hooks + URL params
- XMTP:
@xmtp/node-sdk(backend) +@xmtp/browser-sdk(frontend) - Wallet: wagmi + OnchainKit MiniKit
- Deployment: Vercel (with Cron)
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Add your agent or feature
- Commit your changes (
git commit -m "Add my feature") - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
MIT License - see LICENSE for details.
