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

# Mail tools

> Tools that list your email jobs, read and propose outreach settings, send one outreach draft you already wrote, and queue a checked table of your drafts.

These tools list your email jobs, read and propose outreach settings, send one outreach draft you already wrote, and queue a checked table of your drafts. They need the permissions `mail:read`, `mail:send` and `profile:write`, which you grant on the Authorize access page when you connect.

This page is generated from the connector's tool catalogue. It describes 5 tools. Every tool reads or writes only your own account.

## Permissions this page needs

* `mail:read`: Read your outreach templates, thank-you drafts, email delivery jobs, and your outreach settings
* `mail:send`: Send a thank-you email you already drafted, to the address stored on the contact linked to that meeting, when you read the exact message and approve it, and send one stored outreach draft you already wrote, and queue a checked table of your own outreach drafts
* `profile:write`: Update your profile preferences, and propose booking page changes you approve

The [permissions reference](/mcp/scopes.md) lists every permission you can grant.

## `mail.jobs.list`

Your agent host shows this tool as "List email jobs".

List your email delivery jobs newest first with cursor pagination: status, purpose, subject, recipient, and the error class for failed jobs. The message body is not included.

Permissions: This tool needs `mail:read`, which the Authorize access page describes as "Read your outreach templates, thank-you drafts, email delivery jobs, and your outreach settings".

Risk: `read`. This tool only reads your own data. It never changes anything and it never asks for your approval.

### Input

| Property | Type | Required | Bounds |
| - | - | - | - |
| `cursor` | string | no | 1 to 512 characters; pattern `^[A-Za-z0-9_-]+$` |
| `limit` | integer | no | from 1 to 20 |

### Example call

```json mail.jobs.list input theme={"system"}
{}
```

### Result

A result is never larger than 16,384 bytes.

A result carries these top-level fields:

```json Top-level fields theme={"system"}
[
  "jobs",
  "nextCursor"
]
```

### Errors

A failed call returns one protocol error with no error code, and its text is `Tool call failed.` every time. This tool looks up no record by id, so it never sends a text that names a record. The [error codes](/mcp/errors.md) page gives every text a read failure can carry.

## `mail.drafts.send`

Your agent host shows this tool as "Send a stored outreach draft".

What this changes: Send one stored outreach draft you already wrote.

The subject, body, and recipient come from that draft. This tool cannot change them.

Permissions: This tool needs `mail:send`, which the Authorize access page describes as "Send a thank-you email you already drafted, to the address stored on the contact linked to that meeting, when you read the exact message and approve it, and send one stored outreach draft you already wrote, and queue a checked table of your own outreach drafts".

Risk: `consequential`. This tool sends one outreach draft you already wrote, from your own Gmail, as soon as the agent calls it. It cannot change the subject, the body or the recipient. Coffee Chats does not ask you to approve first. The tool is marked as not read only, so your agent host can ask you before it calls it.

### Input

| Property | Type | Required | Bounds |
| - | - | - | - |
| `messageId` | string | yes | pattern `^[a-f0-9]{24}$` |

### Example call

```json mail.drafts.send input theme={"system"}
{
  "messageId": "0123456789abcdef01234567"
}
```

### Result

A result is never larger than 1,024 bytes.

A result carries these top-level fields:

```json Top-level fields theme={"system"}
[
  "blocked",
  "deliveryId",
  "status"
]
```

### Errors

A call that does not succeed carries one of these codes.

| Code | What it means |
| - | - |
| `SERVICE_UNAVAILABLE` | Coffee Chats could not do the work just now and wrote nothing. Try again later. |

## `mail.outreach.get`

Your agent host shows this tool as "Get outreach settings".

Read your outreach settings: tone, email length, signature, scheduling link, and follow-up rules. Signature and scheduling link are the values outreach emails actually use; the source fields say whether each was saved by you or filled in by default (derived signature, booking page link).

Permissions: This tool needs `mail:read`, which the Authorize access page describes as "Read your outreach templates, thank-you drafts, email delivery jobs, and your outreach settings".

Risk: `read`. This tool only reads your own data. It never changes anything and it never asks for your approval.

### Input

This tool takes no input.

### Example call

```json mail.outreach.get input theme={"system"}
{}
```

### Result

A result is never larger than 4,096 bytes.

A result carries these top-level fields:

```json Top-level fields theme={"system"}
[
  "emailLength",
  "followUpDays",
  "followUpRemindersEnabled",
  "maxFollowUps",
  "preferredName",
  "schedulingLink",
  "schedulingLinkSource",
  "signature",
  "signatureSource",
  "tone"
]
```

### Errors

A failed call returns one protocol error with no error code, and its text is `Tool call failed.` every time. This tool looks up no record by id, so it never sends a text that names a record. The [error codes](/mcp/errors.md) page gives every text a read failure can carry.

## `mail.outreach.update`

Your agent host shows this tool as "Propose outreach settings change".

What this changes: Propose changes to the authenticated student's outreach settings: preferred name, email signature, scheduling link (an empty link means the booking page is used) and email tone (professional, warm, casual).

Send only the settings to change, each at most 200 characters. Nothing changes until the student approves the request in a browser.

Permissions: This tool needs `profile:write`, which the Authorize access page describes as "Update your profile preferences, and propose booking page changes you approve".

Risk: `consequential`. This tool cannot change anything on its own. It proposes the change, and nothing happens until you open the Coffee Chats page it points to and approve exactly what is shown.

### Input

The agent sends one object, and the table below is that object exactly as the connector publishes it. The connector accepts the object in one of these 2 forms and refuses any mixture of them. A published schema cannot state that rule, which is why the Required column reads `no` on every property and why each form is written out under the table. Within a form, every property the form does not name is refused.

| Property | Type | Required | Bounds |
| - | - | - | - |
| `idempotencyKey` | string | no | 16 to 128 characters |
| `operationId` | string | no | pattern `^[a-f0-9]{24}$` |
| `preferredName` | string | no | at most 200 characters |
| `schedulingLink` | string | no | at most 200 characters |
| `signature` | string | no | at most 200 characters |
| `tone` | string | no | one of `professional`, `warm`, `casual` |

#### Form 1, sending `idempotencyKey`

Send `idempotencyKey`. It is required in this form. `preferredName`, `schedulingLink`, `signature` and `tone` may be sent beside it, and nothing else may be.

#### Form 2, sending `operationId`

Send `operationId`. It is required in this form. No other property is accepted with it.

### Example calls

```json mail.outreach.update input form 1 theme={"system"}
{
  "idempotencyKey": "example-idempotency-key-0017",
  "tone": "warm"
}
```

```json mail.outreach.update input form 2 theme={"system"}
{
  "operationId": "0123456789abcdef01234567"
}
```

### Result

A result is never larger than 4,096 bytes.

This tool's result takes one of these 6 forms, and one call returns exactly one of them. The field named beside each form below says which one you are looking at. Open a form to read its top-level fields.

> **Shape 1, where tag is completed**
>
> ```json Top-level fields theme={"system"}
> [
>   "operationId",
>   "operationStatus",
>   "result",
>   "scenario",
>   "tag"
> ]
> ```

> **Shape 2, where tag is requires\_confirmation**
>
> ```json Top-level fields theme={"system"}
> [
>   "actionStatus",
>   "handoff",
>   "operationId",
>   "scenario",
>   "tag"
> ]
> ```

> **Shape 3, where tag is accepted**
>
> ```json Top-level fields theme={"system"}
> [
>   "operationId",
>   "operationStatus",
>   "scenario",
>   "tag"
> ]
> ```

> **Shape 4, where status is failed**
>
> ```json Top-level fields theme={"system"}
> [
>   "error",
>   "operationId",
>   "scenario",
>   "status"
> ]
> ```

> **Shape 5, where status is cancelled**
>
> ```json Top-level fields theme={"system"}
> [
>   "error",
>   "operationId",
>   "scenario",
>   "status"
> ]
> ```

> **Shape 6, where status is uncertain**
>
> ```json Top-level fields theme={"system"}
> [
>   "error",
>   "operationId",
>   "scenario",
>   "status"
> ]
> ```

### The result may carry a retry hint

A call can be accepted and still ask the agent to come back later. When that happens the result is an accepted result and not a failure, and it carries a hint beside it holding one of these codes and a delay in milliseconds. Nothing has gone wrong and nothing has been written yet.

| Code | What it means |
| - | - |
| `PERMIT_BACKPRESSURE` | Too much work is already running on this connection. The agent should wait for the stated delay and call the tool again. |
| `PERMIT_CONTENTION` | Another call was holding the same slot. The agent should wait for the stated delay and call the tool again. |

### Errors

A call that does not succeed carries one of these codes.

| Code | What it means |
| - | - |
| `ACTION_DENIED` | Either you declined this review request, or the connection was no longer allowed to make the change when Coffee Chats came to apply it. Nothing was written. |
| `ACTION_EXPIRED` | The review request ran out of time, either before you decided or before Coffee Chats could apply it. Nothing was written. |
| `NOT_APPLIED` | Coffee Chats stopped before writing anything. Your data is exactly as it was. |
| `OPERATION_CANCELLED` | The connection was revoked before the change started, so nothing was written. |
| `OUTCOME_UNKNOWN` | Coffee Chats cannot prove whether the change was written and will not guess. Open your Coffee Chats page and look before you decide what to do. Do not ask the agent to retry with a new key, because that could apply the change twice. |
| `SERVICE_UNAVAILABLE` | Coffee Chats could not do the work just now and wrote nothing. Try again later. |
| `VERSION_CONFLICT` | The page changed after the agent read it, so nothing was written. Ask the agent to read the page again and propose the change from what is there now. |

## `mail.batch.enqueue`

Your agent host shows this tool as "Queue a table of outreach drafts".

What this changes: Queue a checked table of your own outreach drafts.

Parse a csv or markdown table of email, subject, and body. Each row must match a contact you already have. A row is checked before a job is built.

Permissions: This tool needs `mail:send`, which the Authorize access page describes as "Send a thank-you email you already drafted, to the address stored on the contact linked to that meeting, when you read the exact message and approve it, and send one stored outreach draft you already wrote, and queue a checked table of your own outreach drafts".

Risk: `consequential`. This tool queues each row of your table to send from your own Gmail as soon as the agent calls it. Every row must match a contact you already have, and a row that fails its check is not queued. Coffee Chats does not ask you to approve first. The tool is marked as not read only, so your agent host can ask you before it calls it.

### Input

| Property | Type | Required | Bounds |
| - | - | - | - |
| `table` | string | yes | 1 to 20000 characters |

### Example call

```json mail.batch.enqueue input theme={"system"}
{
  "table": "email,subject,body\nada@example.com,Hello,Nice to meet you"
}
```

### Result

A result is never larger than 8,192 bytes.

A result carries these top-level fields:

```json Top-level fields theme={"system"}
[
  "blocked",
  "queued"
]
```

### Errors

A call that does not succeed carries one of these codes.

| Code | What it means |
| - | - |
| `SERVICE_UNAVAILABLE` | Coffee Chats could not do the work just now and wrote nothing. Try again later. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.