Recipes

Build an email agent

Build an AI email agent: give it its own address, connect it to Inboundr's MCP server, and let it read and triage its inbox.

Inboundr was built for this setup: an agent with its own inbox that reads incoming mail and decides what to do with it, using only MCP tools. You don't write any email-handling code.

What you'll set up#

  1. Give the agent an address

    On a verified domain, create an inbox for the agent. A store-only address, one with no endpoint, works best: the agent reads mail when it acts, so it doesn't need a server listening for webhooks.

    bash
    curl https://inboundr.net/api/v1/addresses \
      -H "Authorization: Bearer $INBOUNDR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "domainId": "dom_123", "localPart": "ada" }'

    Now ada@yourdomain.com accepts mail and keeps it for the agent to read.

  2. Connect the MCP server

    Point your MCP client at Inboundr with the same inb_ key:

    json
    {
      "mcpServers": {
        "inboundr": {
          "url": "https://inboundr.net/api/mcp",
          "headers": { "Authorization": "Bearer inb_xxxxxxxxxxxx" }
        }
      }
    }

    The agent can now call list_emails, get_email, get_thread and the other tools. See the full tool list.

  3. Run the loop

    Give the agent a short instruction and let it use the tools:

    Check ada@yourdomain.com for new mail. For each new message, read the thread for context and decide what it needs: file it, escalate it, or flag the sender.

    To do that, the agent will:

    1. call list_emails with direction: "inbound" to find new mail,
    2. call get_thread to read the conversation,
    3. call create_shield_rule if future mail like it should be blocked, allowed, routed or quarantined.

The loop in pseudocode#

loop:
  new = list_emails(direction="inbound", to="ada@yourdomain.com")
  for email in new:
      thread = get_thread(email.threadId)
      action = «your model decides what this needs, given `thread`»
      handle(action)   # file a ticket, post to a channel, escalate:
                        # whatever your own systems do with it

Design tips#

Track what's already handled

Inboundr stores every message but doesn't mark any as handled. Keep your own record, such as the newest receivedAt you've processed or a list of handled email IDs, so the agent doesn't act on the same message twice.

Give the model the whole thread

Call get_thread before deciding anything. The latest message on its own rarely has enough context; the whole conversation usually does.

Check risky actions first

For actions with big consequences, such as a Shield rule that blocks a whole domain, have the agent draft the change and a person approve it first.

Give each agent its own address

Separate inboxes (sales@, support@, ada@) keep each agent's context separate and make it clear which agent owns a conversation. The catch-all still covers every other address.

Prefer a server?#

If your agent runs as an always-on service, route the address to a webhook endpoint instead of polling. Each message is pushed to you as it arrives, and the rest of the loop stays the same.

MCP reference

Every tool, its parameters, and how to connect.