Persistent Email Memory with Letta Agents

Combine Letta's persistent memory with MultiMail's email infrastructure — agents that remember past email conversations and build relationships over time.


Letta (formerly MemGPT) provides agents with persistent memory that survives across conversations. When combined with MultiMail, your agents can remember past email interactions, track relationship history, and compose contextually aware messages — even weeks after the original conversation.

MultiMail's thread tracking pairs naturally with Letta's archival memory. An agent can store email thread summaries in its long-term memory, retrieve them when a contact emails again, and draft replies that reference prior exchanges. The default gated_send mode ensures a human reviews these context-rich responses before delivery.

Integration uses Letta's tool system. Register MultiMail API functions as tools available to your Letta agent, and the agent can invoke them alongside its memory operations.

Built for Letta (MemGPT) developers

Memory-Enhanced Email Conversations

Letta agents store email context in archival memory. When a contact emails again, the agent retrieves past interaction summaries to compose informed, relationship-aware replies.

Cross-Session Thread Continuity

MultiMail tracks email threads, and Letta maintains memory across sessions. Together, your agent can resume an email conversation days later with full context of what was discussed and decided.

Graduated Trust with Relationship Context

As a Letta agent builds memory about reliable email patterns, you can progressively relax oversight from gated_send to monitored. The agent's persistent memory helps it learn appropriate communication styles.

Contact Relationship Management

Letta's memory system combined with MultiMail's contact management creates a relationship layer. The agent remembers preferences, past issues, and communication patterns for each contact.


Get started in minutes

Register MultiMail Tools with Letta
python
from letta import create_client

client = create_client()

"cm"># Define email tool functions
send_email_code = """
import requests

def send_email(to: str, subject: str, body: str, mailbox_id: str) -> str:
    \"\"\"Send an email via MultiMail. In gated_send mode, the email
    is queued for human approval before delivery.\"\"\"
    resp = requests.post(
        "https://api.multimail.dev/v1/send",
        headers={"Authorization": "Bearer mm_live_your_api_key"},
        json={"mailbox_id": mailbox_id, "to": to,
              "subject": subject, "body": body}
    )
    return str(resp.json())
"""

check_inbox_code = """
import requests

def check_inbox(mailbox_id: str, limit: int = 10) -> str:
    \"\"\"Check inbox for recent messages.\"\"\"
    resp = requests.get(
        f"https://api.multimail.dev/v1/mailboxes/{mailbox_id}/inbox",
        headers={"Authorization": "Bearer mm_live_your_api_key"},
        params={"limit": limit}
    )
    return str(resp.json())
"""

# Register tools with the Letta client
send_tool = client.create_tool(send_email_code, name="send_email")
inbox_tool = client.create_tool(check_inbox_code, name="check_inbox")

Create a Letta agent with MultiMail email tools registered for sending and reading email.

Create a Memory-Enhanced Email Agent
python
agent = client.create_agent(
    name="EmailAssistant",
    tools=[send_tool.name, inbox_tool.name],
    system=(
        "You are a persistent email assistant with long-term memory. "
        "When you handle an email thread, store a summary in your "
        "archival memory for future reference. When a contact emails "
        "again, search your memory for past interactions before "
        "composing a reply.\n\n"
        "All outbound emails use gated_send mode — they are queued "
        "for human approval before delivery. Mention this to the "
        "user when drafting emails.\n\n"
        "Your mailbox ID is: your_mailbox_id"
    )
)

"cm"># Send a message — the agent persists memory across calls
response = client.send_message(
    agent_id=agent.id,
    role="user",
    message="Check my inbox and summarize any new messages. "
            "Remember the key details for future reference."
)

for msg in response.messages:
    print(msg)

Build a Letta agent with persistent memory and email capabilities.

Memory-Aware Email Replies
python
"cm"># Later session — the agent remembers past interactions
response = client.send_message(
    agent_id=agent.id,
    role="user",
    message="I got a new email from [email protected] about the "
            "project timeline. Draft a reply that references "
            "our previous conversations."
)

"cm"># The agent will:
"cm"># 1. Search archival memory for past interactions with [email protected]
"cm"># 2. Retrieve context about the project and previous discussions
"cm"># 3. Draft a reply that references specific past points
"cm"># 4. Send via MultiMail (queued for approval in gated_send mode)

for msg in response.messages:
    print(msg)

"cm"># Memory persists — next time [email protected] emails,
"cm"># the agent will have even more context to draw from

The agent uses its persistent memory to compose context-aware replies to returning contacts.


Step by step

1

Create a MultiMail Account and API Key

Sign up at multimail.dev, create a mailbox, and generate an API key from your dashboard. Your key will start with mm_live_.

2

Install Letta

Install the Letta package and start the Letta server.

bash
pip install letta && letta server
3

Register Email Tools

Define email functions as Python code strings and register them with the Letta client using create_tool. Create tools for send_email, check_inbox, and reply_email.

4

Create Your Email Agent

Create a Letta agent with the email tools attached and a system prompt that explains the oversight mode and instructs the agent to use archival memory for email context.

5

Approve Pending Emails

Review emails queued by the agent in the MultiMail dashboard. Approve messages before delivery. The agent's memory-enhanced context should produce higher-quality drafts over time.


Common questions

How does Letta's memory improve email responses over time?
Letta agents store email interaction summaries in archival memory. When a contact emails again, the agent searches its memory for past interactions and uses that context to compose informed replies. Over time, the agent builds a relationship history that makes responses more relevant and personalized.
Does the agent remember emails across sessions?
Yes. Letta's core feature is persistent memory across sessions. Email summaries stored in archival memory survive indefinitely. Combined with MultiMail's thread tracking, the agent has both its own memory and the email system's thread history to draw from.
Can I use Letta's recall memory for recent email context?
Yes. Recall memory captures recent conversation turns including email tool invocations. For recent email threads, the agent can reference recall memory for exact details. For older interactions, archival memory provides summarized context.
What happens when Letta's memory contradicts the email thread?
Use MultiMail's get_thread endpoint to retrieve the authoritative email thread history. The agent should cross-reference its memory with the actual thread data. You can instruct the agent in its system prompt to always verify memory against the thread before composing replies.

Explore more

The only agent email with a verifiable sender

Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.