MailgentMailgent
Examples

Auto-Reply Agent

Build an agent that automatically replies to incoming emails

An agent that checks for new emails, generates a reply using an LLM, and sends it back.

How It Works

1. Poll for unread emails
2. For each email, get the full thread
3. Feed conversation to LLM
4. Send LLM's reply
5. Mark as processed

MCP Flow (Claude Code)

Just tell Claude:

"Check my inbox every time I ask, and reply to any unread emails with helpful responses."

Claude will:

  1. Call mail.list_messages(labels: "unread")
  2. Call mail.get_thread(threadId) for context
  3. Generate a reply
  4. Call mail.reply(messageId, text)
  5. Call mail.update_labels(messageId, addLabels: ["read"], removeLabels: ["unread"])

API Flow (Python)

import requests
from openai import OpenAI

MAILGENT_KEY = "mgent-your-key"
BASE = "https://api.mailgent.dev/v0"
headers = {"Authorization": f"Bearer {MAILGENT_KEY}"}
llm = OpenAI()

def process_inbox():
    # Get unread messages
    res = requests.get(f"{BASE}/messages?labels=unread", headers=headers)
    messages = res.json()["messages"]

    for msg in messages:
        # Get full thread
        thread = requests.get(
            f"{BASE}/threads/{msg['threadId']}", headers=headers
        ).json()

        # Build conversation for LLM
        conversation = "\n\n".join([
            f"{'Agent' if 'sent' in m['labels'] else m['from'][0]}: {m['extractedText'] or m['text']}"
            for m in thread["messages"]
        ])

        # Generate reply
        response = llm.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": "You are a helpful email assistant."},
                {"role": "user", "content": f"Reply to this email thread:\n\n{conversation}"}
            ]
        )
        reply_text = response.choices[0].message.content

        # Send reply
        requests.post(
            f"{BASE}/messages/{msg['messageId']}/reply",
            headers=headers,
            json={"text": reply_text}
        )

        # Mark processed
        requests.patch(
            f"{BASE}/messages/{msg['messageId']}",
            headers=headers,
            json={"addLabels": ["read", "processed"], "removeLabels": ["unread"]}
        )

# Run every 30 seconds
import time
while True:
    process_inbox()
    time.sleep(30)

Key Points

  • extractedText gives you clean reply text without quoted history
  • get_thread gives full conversation context for better LLM responses
  • Label management prevents re-processing the same email

On this page