# Let an AI agent answer support

Connect your AI assistant to your support inbox. It reads and sorts conversations, writes notes for your team, and leaves reply drafts for a person to send.

Paste this into your agent once it is connected:

```text
Triage the open conversations in our Rasket support inbox (support@yourdomain.com) using the Rasket MCP tools.
Read the Markdown of Rasket's guide first: /docs/inbox-api/agents.md on the Rasket website.
1. Call list_inbox_channels, then list_conversations with status open.
2. For each one, get_conversation, then add_conversation_note with a one-line summary and what the customer needs.
3. Assign it with update_conversation if the right teammate is obvious; otherwise leave it.
4. Write the answer with save_reply_draft so a person can read and send it. Do not call reply_to_conversation unless I say so.
5. Never open a personal mailbox or anything outside this channel, and stop and ask if a request needs a refund or an account change.
```

## 1. Connect with the Inbox tools

The Inbox tools are only offered when you ask for them, so connect to the MCP server with `?toolset=inbox`:

Claude Code:

```text
claude mcp add --transport http rasket-inbox "https://api.rasket.com/mcp?toolset=inbox"
```

Cursor (.cursor/mcp.json):

```text
{
  "mcpServers": {
    "rasket-inbox": {
      "url": "https://api.rasket.com/mcp?toolset=inbox"
    }
  }
}
```

Sign in when the browser opens and approve `inbox:read` and `inbox:write`. The agent then acts as you: it sees the channels you can open, and nothing else.

> A Claude connector added in Claude's settings can't reach the Inbox tools yet: it refuses an address with `?toolset=` in it. Use Claude Code, Cursor or another MCP client for now.

## 2. Let it triage

Paste the prompt above. These are the tools it uses:

| Tool | What it does |
| --- | --- |
| `list_inbox_channels` | Your channels, who can be assigned in each, and the team's labels and folders. |
| `list_conversations` | Conversations by channel, status, assignee, label, folder or place. |
| `get_conversation` | One conversation: its newest messages, its notes and the customer. |
| `search_inbox` | Search with the Inbox's own grammar. |
| `add_conversation_note` | An internal note. It never reaches the customer. |
| `update_conversation` | Set the status, assign it, change labels or file it. |
| `save_reply_draft` | A reply in your own drafts, for a person to read and send. |
| `reply_to_conversation` | Sends from the channel — only after a preview and your yes. |
| `create_conversation` | Opens a conversation — only after a preview and your yes. |

The full list, with every scope, is on the [MCP server](https://www.rasket.com/docs/mcp) page.

## 3. A person sends

1. The agent writes each answer with `save_reply_draft`. It waits in your drafts in Rasket Inbox.
2. You read it, change what you like, and press Send.
3. If you let the agent send itself, `reply_to_conversation` shows a preview first and sends only when called again with the token that preview returned.

The expected result: every open conversation has a note and, where the agent could answer, a draft. Nothing reached a customer without a person.

## Building your own agent

A program with no person behind it uses an API key with Inbox access **Read and reply**. It lists what is open, then notes and replies as the key, under the key's name:

List conversations:

```sh
curl -X GET "https://api.rasket.com/inbox/conversations?status=open&limit=20" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"
```

```ts
const response = await fetch("https://api.rasket.com/inbox/conversations?status=open&limit=20", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
  },
});

const data = await response.json();
```

```python
import os

import requests

response = requests.get(
    "https://api.rasket.com/inbox/conversations?status=open&limit=20",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
)

print(response.json())
```

Add an internal note:

```sh
curl -X POST "https://api.rasket.com/inbox/conversations/0192f8e1-7a40-7c55-b1e3-0f0a3b6d2e91/notes" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "Customer since 2024, on the Team plan. Offer the annual discount."
}'
```

```ts
const response = await fetch("https://api.rasket.com/inbox/conversations/0192f8e1-7a40-7c55-b1e3-0f0a3b6d2e91/notes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    body: "Customer since 2024, on the Team plan. Offer the annual discount."
  }),
});

const { id } = await response.json();
```

```python
import os

import requests

response = requests.post(
    "https://api.rasket.com/inbox/conversations/0192f8e1-7a40-7c55-b1e3-0f0a3b6d2e91/notes",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
    json={
    "body": "Customer since 2024, on the Team plan. Offer the annual discount."
  },
)

id = response.json()["id"]
```

- A key's reply goes out from the channel's own name and address, at most 60 an hour per key.
- A key can't snooze, because a snooze is a person's. Set status `pending` instead.
- Every call is on the [Inbox API reference](https://www.rasket.com/docs/api-reference/inbox).

## If something goes wrong

| Problem | What to do |
| --- | --- |
| The agent has no Inbox tools | It connected without `?toolset=inbox`. Remove the server and add it again with the URL above. |
| `403` | The scope was not approved when you connected, or you are a viewer, who can read and cannot write. |
| `404` | The conversation is in a personal mailbox or a channel you can't open. Agents never reach those. |
