> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waterr.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code

> Give a Claude Code agent its own inbox with a skill it can follow.

Claude Code already has everything it needs to drive Agent Mailbox — the API is plain HTTPS and it has a shell. What it lacks is knowing the shape of it: which field to read, when not to reply, what a `404` on an inbox actually means.

That is what a skill is. A markdown instruction bundle that teaches an agent to use tools it already has, loaded only when the work calls for it.

<Note>
  Claude Code can take either route. A skill keeps you in control of the HTTP calls and needs no extra setup; the [MCP server](/agent-mailbox/mcp) hands it twelve ready-made tools instead. Skill is the lighter default — reach for MCP if you want the tool-approval prompts that come with it.
</Note>

## Install

```bash theme={null}
mkdir -p .claude/skills/agent-mailbox
curl -sL https://docs.waterr.ai/agent-mailbox/skill.txt \
  -o .claude/skills/agent-mailbox/SKILL.md

export AGENT_MAILBOX_KEY="wai_live_..."
```

<Tip>
  `.claude/skills/` in a project scopes the skill to that repo. Put it in `~/.claude/skills/` instead and every project gets it.
</Tip>

Your existing Waterr `wai_` developer key works — see [Authentication](/agent-mailbox/authentication). Nothing else to provision.

## Check it loaded

Start Claude Code and ask for something mail-shaped:

```
> check if my agent inbox has any new mail
```

Claude Code reads the skill, calls `GET /v0/inboxes`, and reports what it finds. If it asks what Agent Mailbox is, the file is in the wrong place — confirm `.claude/skills/agent-mailbox/SKILL.md` exists relative to where you started the session.

## What the skill teaches

Not just the endpoint list. The parts that are easy to get wrong:

|                                          |                                                                                                                                                                                      |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Read `extracted_text`, not `text`**    | `text` is the raw body with quoted history. On a live thread that is mostly the conversation repeated back, which burns context and invites a reply to a message from two weeks ago. |
| **Check the `auto-reply` label first**   | Answering a vacation responder produces another one, and the two systems will do that to each other indefinitely.                                                                    |
| **Acknowledge webhooks before thinking** | A handler that calls a model synchronously blows the 30s timeout, gets retried, and answers the same email twice.                                                                    |
| **Verification codes need a cue word**   | A bare `\d{4,8}` match returns the year out of a date. The skill's extractor requires a cue like *code* or *verify* and rejects years.                                               |
| **Draft before sending**                 | Email has no unsend. An agent that drafts is recoverable.                                                                                                                            |

## What it can do once installed

<CardGroup cols={2}>
  <Card title="Handle a support thread" icon="headset">
    Read the thread for context, answer in it, keep replying as the conversation continues.
  </Card>

  <Card title="Collect a verification code" icon="key">
    Sign up somewhere with the agent's own address, then pull the OTP out of the inbox.
  </Card>

  <Card title="Follow up on its own" icon="clock">
    Queue a scheduled draft on a thread the moment it promises something, so nothing depends on remembering later.
  </Card>

  <Card title="Draft for your approval" icon="pen-to-square">
    Compose the reply, leave it unsent, and let you send it once you have read it.
  </Card>
</CardGroup>

## Containment worth setting up first

An agent that reads email and can send email is a prompt-injection target — the content it processes is written by whoever emailed it. Before pointing one at a real inbox, bound where it can send:

```bash theme={null}
curl -X POST "https://agent.waterr.ai/v0/inboxes/ava@agent.waterr.ai/lists/send/allow" \
  -H "Authorization: Bearer $AGENT_MAILBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entry":"yourcompany.com","reason":"containment while testing"}'
```

One allow entry makes that direction deny-by-default, so add every address the agent legitimately needs before the first one. This holds even when the model is talked into something. See [Allow and block lists](/agent-mailbox/lists).

## Other coding agents

The skill is plain markdown against a plain REST API, so it carries anywhere an agent can read a file and run `curl` — Codex, Cursor, and similar. Only the install path differs:

| Agent       | Where the file goes                                 |
| ----------- | --------------------------------------------------- |
| Claude Code | `.claude/skills/agent-mailbox/SKILL.md`             |
| Codex       | `AGENTS.md`, or paste the contents into your prompt |
| Cursor      | `.cursor/rules/agent-mailbox.mdc`                   |

<Note>
  These are skill-only installs — the agent calls the REST API directly. If you would rather it received **tools** than instructions, there is a hosted [MCP server](/agent-mailbox/mcp) at `https://agent.waterr.ai/mcp`, which is also how Cursor and Grok connect.
</Note>
