Give your AI agent a real email address and phone number. Production-ready examples for LangChain, CrewAI, OpenAI Agents SDK, Claude, MCP, OpenClaw, and agent-to-agent networks. Powered by Commune.
Email is the identity layer for agents. A human has name@gmail.com as their internet identity. An agent gets agent-name@commune.email — a permanent address that survives process restarts, framework changes, and infrastructure migrations.
# One line — your agent has an identity on the internet
inbox = commune.inboxes.create(local_part="my-agent")
print(inbox.address) # → my-agent@org.commune.emailThis address is yours. It can receive email from any human or any other agent. It has a thread history that persists across sessions. It can be searched semantically. It can forward structured data to your webhook in real time. It is the single stable reference point for your agent in the world.
# Python — give your agent an email address
from commune import CommuneClient
commune = CommuneClient(api_key="comm_...")
inbox = commune.inboxes.create(local_part="support")
print(inbox.address) # → support@yourdomain.commune.email// TypeScript — give your agent an email address
import { CommuneClient } from 'commune-ai';
const commune = new CommuneClient({ apiKey: process.env.COMMUNE_API_KEY! });
const inbox = await commune.inboxes.create({ localPart: 'support' });
console.log(inbox.address); // → support@yourdomain.commune.emailThat's a real, deliverable inbox. Your agent can now send replies, search its thread history semantically, extract structured data from inbound mail, and receive webhook events — all with two lines of code.
OpenClaw users: install the Commune email + SMS skills in 30 seconds. Your agent gets a real inbox and phone number it can use from WhatsApp, Telegram, or wherever it lives.
git clone https://github.com/shanjai-raj/commune-openclaw-email-sms-quickstart
cd commune-openclaw-email-sms-quickstart
bash install.shThe installer copies two skills into ~/.openclaw/workspace/skills/:
commune-email— send, receive, search, and manage email threadscommune-sms— send SMS, read conversations, manage phone numbers
Once installed, your agent understands natural-language commands like "check my email", "reply to that thread about the contract", and "text Alex that I'm running late."
→ Full OpenClaw setup guide · → Dedicated repo with use cases
Agents communicate through Commune the same way humans do — by sending each other email. Every agent gets an address. Addresses are permanent. Threads preserve the full task chain.
# Each agent is an email address
orchestrator = commune.inboxes.create(local_part="orchestrator")
researcher = commune.inboxes.create(local_part="researcher")
# Send a task
task = commune.messages.send(
to=researcher.address, # researcher@org.commune.email
subject="Research task",
text="Compare Postgres hosting pricing: Neon, Supabase, Railway.",
inbox_id=orchestrator.id,
idempotency_key="research-001", # safe to retry
)
# Researcher replies in the same thread — full context preserved
commune.messages.send(
to=orchestrator.address,
subject="Re: Research task",
text=result,
inbox_id=researcher.id,
thread_id=task.thread_id, # binds reply to task
)
# Orchestrator reads the full chain
messages = commune.threads.messages(task.thread_id)
# messages[0] = task, messages[1] = result, messages[n] = any follow-upNo shared database. No coordination layer. The thread IS the task context.
→ Full A2A examples with typed task delegation, semantic deduplication, and agent mesh patterns
| Example | LangChain | CrewAI | OpenAI Agents | Claude | MCP | TypeScript | A2A |
|---|---|---|---|---|---|---|---|
| Customer Support Agent | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — |
| Lead Outreach | ✅ | ✅ | — | ✅ | — | — | — |
| Multi-Agent Coordination | — | ✅ | — | — | — | ✅ | ✅ |
| SMS Notifications | — | — | — | — | ✅ | ✅ | — |
| Structured Extraction | — | — | — | ✅ | ✅ | — | — |
| Webhook Handler | — | — | — | — | — | ✅ | — |
| Task Delegation | — | — | — | — | — | — | ✅ |
Most agent frameworks are great at reasoning — but stop short when it comes to communicating with the outside world asynchronously. Email and SMS fill that gap:
- Agents are async by nature. A task might take minutes or hours. Email is the right protocol for async handoffs — your agent sends, the user replies when ready, the thread stays intact.
- Email is the universal protocol. Every system on the planet speaks SMTP. Your agent can talk to any user, any tool, any service — no integration required.
- Threading keeps context.
In-Reply-ToandReferencesheaders (RFC 5322) tie every message to its thread. Your agent never loses the conversation history. - SMS adds the urgency channel. Some things need immediate attention. Two-way SMS lets your agent escalate, notify, and confirm — all from a real phone number.
- Agent-to-agent is next. Agents will increasingly communicate with other agents — delegating tasks, routing results, building mesh networks. Email is the right protocol: async, persistent, addressable, universally supported.
| Feature | What it means for your agent |
|---|---|
| Vector search across threads | commune.search.threads({ query }) — find relevant past conversations with semantic similarity, not keyword matching |
| Structured JSON extraction | Define a JSON schema per inbox; every inbound email is parsed into structured data automatically |
| Idempotent sends | Pass an idempotency_key and your agent gets a 202 immediately — Commune deduplicates sends within a 24-hour window, so retries never produce duplicate messages |
| Guaranteed webhook delivery | 8 retries with exponential backoff and a circuit breaker — your agent's handler will receive every event even through transient failures |
| Per-inbox task schemas | Configure what a "task email" looks like — Commune extracts typed fields before your webhook fires |
flowchart LR
subgraph Agents["AI Agents"]
A1["Agent A\norchestrator@org.commune.email"]
A2["Agent B\nresearcher@org.commune.email"]
A3["LangChain / CrewAI\nOpenAI / Claude / MCP"]
end
subgraph Commune["Commune Platform"]
B[Inbox] --> C[Email Threading]
C --> D[Vector Search]
C --> E[JSON Extraction]
C --> F[Webhook Delivery]
end
Human["User / External\nEmail Client"] <-->|"email"| Commune
A1 <-->|"task delegation"| A2
Agents <-->|"Commune SDK\ncommune-ai / commune-mail"| Commune
F -->|"webhook\n(HMAC signed)"| Agents
1. Install the SDK
# Python
pip install commune-mail
# TypeScript / Node
npm install commune-ai2. Get your API key
Sign up at commune.email — free tier included, no credit card required.
3. Pick an example below and follow its README
Every example is self-contained: install, set your key, run.
OpenClaw is the most popular open-source personal agent framework. Commune provides first-party skills for email and SMS — install once, and your OpenClaw agent can manage a real inbox from any chat interface.
| Example | Description |
|---|---|
| Personal Assistant | Agent manages your personal email — check, reply, summarize from WhatsApp |
| Company Agent | Agent handles customer email: triage, draft replies, SMS escalation |
| Skill: commune-email | Full email skill: create inboxes, read threads, send, reply, search |
| Skill: commune-sms | SMS skill: send, receive, list phone numbers |
→ See all OpenClaw examples · → Dedicated quickstart repo
Each agent gets its own inbox address. Agents delegate tasks by sending emails, receive results as replies, and maintain full thread history without shared state.
| Example | Description |
|---|---|
| Orchestrator → Worker | Orchestrator sends typed task, worker processes and replies in thread |
| Typed task delegation | Extraction schema on worker inbox — tasks auto-parsed before webhook fires |
| Agent mesh | N agents each with own inbox, delegating tasks across the network |
LangChain tools wrap Commune with the @tool decorator. Your chain gains send_email, read_inbox, search_threads, and send_sms as first-class tools — callable by any LLM in the chain.
| Example | Description |
|---|---|
| Customer Support Agent | Full support workflow: read inbound, classify, draft reply, send |
| Lead Outreach | Personalised outreach from a CRM list with open-tracking |
CrewAI agents communicate through shared Commune inboxes — one inbox per crew, or one per agent. Multi-agent coordination over email with full thread history.
| Example | Description |
|---|---|
| Customer Support Crew | Triage agent → specialist agent → reply agent pipeline |
| Lead Outreach Crew | Researcher + writer + sender crew for personalised outreach |
| Multi-Agent Coordination | Agents hand off tasks to each other via email threads |
Use @function_tool to expose Commune capabilities to OpenAI's agent loop. The agent decides when to send, when to search, and when to escalate — you just wire the tools.
| Example | Description |
|---|---|
| Customer Support Agent | Support agent with handoff to human escalation via email |
→ See all OpenAI Agents examples
Claude's tool_use API maps cleanly to Commune operations. Pass the tool definitions, handle tool_use blocks, return tool_result — Commune becomes part of Claude's reasoning loop.
| Example | Description |
|---|---|
| Customer Support Agent | Claude reads, extracts, classifies, and replies |
| Lead Outreach | Claude writes and sends personalised cold emails |
| Structured Extraction | Claude uses Commune's per-inbox schema to parse inbound emails |
Run commune-mcp as a local MCP server and connect it to Claude Desktop, Cursor, Windsurf, or any MCP-compatible client. No SDK integration required — the model calls the tools directly.
| Example | Description |
|---|---|
| Customer Support via MCP | Full support workflow through Claude Desktop |
| SMS Notifications via MCP | Provision a number and send SMS from within a chat session |
| Structured Extraction via MCP | Define schemas and extract structured data from inbound mail |
Full end-to-end TypeScript examples: webhook handlers with HMAC verification, multi-agent coordination with typed payloads, and SMS flows — all typed against the commune-ai SDK.
| Example | Description |
|---|---|
| Customer Support Agent | Express webhook handler + Commune reply flow |
| Multi-Agent Coordination | Two agents hand off tasks over email with typed thread payloads |
| SMS Notifications | Provision a number, send SMS, handle inbound replies |
| Webhook Handler | Reference implementation with verifyCommuneWebhook and retry-safe handling |
Browse examples by what you want to build:
| Use Case | Channel | Complexity |
|---|---|---|
| AI Email Support Agent | Beginner | |
| SMS Worker Dispatch | SMS | Intermediate |
| Candidate Outreach Sequence | Intermediate | |
| Cold Email Outreach | Intermediate | |
| SMS Lead Qualification | SMS | Intermediate |
| Omnichannel Support | Email + SMS | Advanced |
| Incident Alert System | Email + SMS | Advanced |
| Multi-Agent Coordination | Advanced | |
| Agent-to-Agent Task Delegation | Advanced |
Reference examples for every Commune feature:
| Capability | What it does | Get started |
|---|---|---|
| Quickstart | Give your agent an email + phone | 3 lines of code |
| Email Threading | Reply in the same thread | RFC 5322 explained |
| Structured Extraction | Auto-parse email fields to JSON | Zero extra LLM calls |
| Semantic Search | Natural language inbox search | Vector embeddings |
| Webhook Delivery | Receive emails in real time | HMAC verified, 8 retries |
| Phone Numbers | Agent phone number management | Provision + SMS + voice |
| SMS | Send, receive, broadcast SMS | Quickstart → mass SMS |
Your agent can also send and receive SMS.
# Provision a real phone number
phone = commune.phoneNumbers.provision()
print(phone.number) # → +14155552671
# Send an SMS
commune.sms.send(
to="+14155551234",
body="Your order has shipped.",
phone_number_id=phone.id,
)Two-way conversations. Semantic search across SMS and email in a single unified index. Escalation from email thread to SMS with one method call.
Email threading
Commune implements RFC 5322 threading natively. Every message sent through commune.messages.send() carries the correct In-Reply-To and References headers, so replies appear as threads in every email client — Gmail, Outlook, Apple Mail, anything.
Every thread gets a stable thread_id. Pass that ID to commune.messages.send() and your agent's reply lands in the right conversation — no matter how many hours or days have passed.
# Reply to an existing thread
commune.messages.send(
to="user@example.com",
subject="Re: Your support request",
text="We've resolved your issue.",
inbox_id=inbox.id,
thread_id=thread.id, # keeps the conversation threaded
)Structured extraction
Define a JSON schema on an inbox and every inbound email will be parsed against it automatically — before your agent ever sees the message. Useful for order confirmations, form submissions, support tickets, typed task delegation between agents, or any email with a predictable structure.
commune.inboxes.update(inbox.id, extraction_schema={
"type": "object",
"properties": {
"order_id": { "type": "string" },
"issue_type": { "type": "string", "enum": ["damaged", "missing", "wrong_item"] },
"urgency": { "type": "string", "enum": ["low", "medium", "high"] },
}
})
# Every inbound message now has a .extracted field
message = commune.messages.get(message_id)
print(message.extracted) # → { "order_id": "ORD-123", "issue_type": "damaged", ... }Semantic search
Every message is embedded at ingest time. Search across an inbox — or across all inboxes — with a natural language query. Results are ranked by semantic similarity, not keyword overlap.
results = commune.search.threads(
query="customer angry about shipping delay",
inbox_id=inbox.id,
limit=5,
)
for thread in results:
print(thread.subject, thread.score)SMS messages are indexed in the same vector store. One query surfaces relevant context regardless of channel.
Idempotent sends
Agent loops retry. Networks fail. Commune's idempotency key system means a message is never sent twice, even if your agent calls messages.send() multiple times with the same key.
commune.messages.send(
to="user@example.com",
subject="Your weekly report",
text=report_body,
inbox_id=inbox.id,
idempotency_key=f"weekly-report-{user_id}-{week}",
)
# Call this 10 times — exactly one email is delivered.
# Every call returns 202 immediately.The deduplication window is 24 hours. Keys are scoped to your account.
Guaranteed webhook delivery
When a message arrives in your inbox, Commune fires a webhook to your registered endpoint. If your server is down, Commune retries — up to 8 attempts with exponential backoff (1s, 2s, 4s, 8s, 16s, 32s, 64s, 128s). A circuit breaker trips after 5 consecutive failures to protect your server from thundering herd on recovery.
Every webhook payload is HMAC-signed with your webhook secret. Verify the signature before processing:
import { verifyCommuneWebhook } from 'commune-ai';
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const payload = verifyCommuneWebhook(req.body, req.headers['commune-signature'], process.env.WEBHOOK_SECRET!);
// payload is verified — process safely
res.sendStatus(200);
});| Method | Description |
|---|---|
commune.inboxes.create(local_part) |
Create an inbox, returns address |
commune.messages.send({ to, subject, text, inbox_id, thread_id }) |
Send or reply to a thread |
commune.threads.list({ inbox_id, limit }) |
List conversation threads |
commune.threads.messages(thread_id) |
Get all messages in a thread |
commune.search.threads({ query, inbox_id }) |
Semantic search across threads |
commune.threads.set_status(thread_id, status) |
Update thread status |
commune.sms.send({ to, body, phone_number_id }) |
Send an SMS |
commune.phone_numbers.provision() |
Provision a real phone number |
| Method | Description |
|---|---|
commune.inboxes.create({ localPart }) |
Create an inbox, returns address |
commune.messages.send({ to, subject, text, inboxId, threadId }) |
Send or reply to a thread |
commune.threads.list({ inboxId, limit }) |
List conversation threads |
commune.threads.messages(threadId) |
Get all messages in a thread |
commune.search.threads({ query, inboxId }) |
Semantic search across threads |
commune.threads.setStatus(threadId, status) |
Update thread status |
commune.sms.send({ to, body, phoneNumberId }) |
Send an SMS |
commune.phoneNumbers.provision() |
Provision a real phone number |
Run these notebooks directly in your browser — no setup required:
| Notebook | Framework | Open |
|---|---|---|
| Customer Support Agent | LangChain | |
| Multi-Agent Email Crew | CrewAI | |
| Email Agent with OpenAI | OpenAI Agents SDK | |
| Structured Email Extraction | Any framework | |
| 5-Minute Quickstart | Python |
Built something with this? Open a PR — new framework examples, language ports, and real-world use cases are all welcome. See CONTRIBUTING.md for guidelines.