> Pour un agent : la carte de la documentation d'Escouade Mail est sur https://escouade.io/mail/docs/llms.txt ; chaque page existe en Markdown, à la même adresse suffixée `.md`.

# Brouillons et validation

> Un envoi peut attendre une validation humaine. Le message reste brouillon, un humain le relit dans son assistant, puis le valide, le corrige ou l'annule. Un agent ne valide pas ses propres envois.

## Quand un message reste brouillon

- **Le message le demande** : `send_email` ou `reply_to_thread` avec `requires_approval` = `true`.
- **L'espace l'impose** : tout envoi reste brouillon. `inbox_status` le dit (`require_approval`). L'humain de l'espace le règle depuis son assistant, avec `update_settings`.

Un brouillon a le statut `draft`. C'est à un brouillon que se joint un fichier : voir [Pièces jointes et copies](https://escouade.io/mail/docs/pieces-jointes.md#joindre). Il ne compte dans le quota du jour de sa boîte qu'au moment de partir. Il se prépare même avant le paiement : il ne se valide qu'avec un forfait en cours.

La réponse dit à l'agent où son humain valide :

```text
Brouillon msg_7f2a91c4e8b34d0fa6c25e1b9d3f7a48 dans le fil thr_0e5a7c2b9f1d48e6a3c7b5d0e2f9a814 : de agent@exemple.fr à nadia.morel@exemple.com, « Rendez-vous de jeudi ». Il attend une validation humaine : votre humain (m•••@exemple.fr) branche son assistant (Claude, ChatGPT…) à l’adresse https://mail.escouade.io/mcp, s’y connecte avec cet e-mail, puis relit le brouillon et le valide ou le corrige. Dites-le-lui : aucun avis ne lui est envoyé. Rien ne part avant.
```

## Qui valide

La validation demande la permission `approve`. Le serveur la vérifie à chaque appel de `approve_message`.

- **La clé rendue par `sign_up`** porte `send`, `read` et `manage_inboxes`. Elle ne porte pas `approve` : l'agent qui s'est inscrit ne peut pas valider ses envois.
- **L'humain obtient `approve` par le connecteur.** Il branche son assistant (Claude, ChatGPT…) à l'adresse `https://mail.escouade.io/mcp`, s'y connecte avec son compte Escouade, à l'adresse rattachée à son espace, puis autorise. Il n'a pas de clé à copier. Voir [Connecteur](https://escouade.io/mail/docs/connecteur.md).
- **La validation se fait dans l'assistant** : par une demande explicite de l'humain (« valide le premier »), qui devient un appel à `approve_message`, ou par le geste « Valider » de la vue des brouillons.
- **Le serveur ne prévient pas l'humain** qu'un brouillon attend : l'agent le lui dit.

Le parcours complet, côté agent et côté humain : [Valider les envois d'un agent](https://escouade.io/mail/docs/guide-validation.md).

Sans la permission, l'appel est refusé :

```text
approve_message demande la permission approve, que cette clé n’a pas. (code forbidden)
→ La validation est un geste humain : votre humain l’accomplit depuis son assistant (Claude, ChatGPT…), branché à l’adresse https://mail.escouade.io/mcp où il se connecte avec son e-mail.
```

## `list_drafts`

Liste les brouillons qui attendent une validation, avec leur texte complet, les plus récents d'abord. Permission : `read` ou `approve`.

| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| `inbox_id` | identifiant `inb_…` | non | Une seule boîte. |
| `cursor` | texte | non | Le curseur de la page suivante : la valeur `next_cursor` de l'appel précédent. |
| `limit` | entier | non | Le nombre d'éléments rendus, de 1 à 100. 20 par défaut. |

```text
1 brouillon(s) à valider :

[msg_7f2a91c4e8b34d0fa6c25e1b9d3f7a48 · sortant · en brouillon (attend une validation) · mardi 13 octobre à 14 h 02]
De : Atelier Exemple <agent@exemple.fr>
À : nadia.morel@exemple.com
Sujet : Rendez-vous de jeudi

Bonjour Madame Morel,

Pouvons-nous déplacer notre rendez-vous de jeudi à vendredi, à la même heure ?

Atelier Exemple
```

L'objet structuré porte `items`, `next_cursor` et `key` : la clé qui lit, avec son nom et ses permissions. Chaque brouillon porte sa version (`revision`), à repasser à `approve_message`.

## `update_draft`

Modifie le sujet, le texte ou le HTML d'un brouillon, tant qu'il n'est pas validé. Le destinataire et la boîte ne changent pas : pour cela, annulez le brouillon et écrivez un nouveau message. Chaque correction est notée au journal, avec son auteur. Permission : `send` ou `approve`.

| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| `message_id` | identifiant `msg_…` | oui | Le brouillon (voir `list_drafts`). |
| `subject` | texte | non | Le nouveau sujet. |
| `text` | texte | non | Le nouveau texte. |
| `html` | texte | non | Le nouveau HTML. Un texte vide retire la version HTML. |

## `approve_message`

Valide un brouillon : il passe en file et partira dans le créneau, selon les quotas. Permission : `approve`.

| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| `message_id` | identifiant `msg_…` | oui | Le brouillon (voir `list_drafts`). |
| `revision` | texte | non | La version du brouillon tel qu'il a été lu : le champ `revision` rendu par `list_drafts`. |

```text
Validé par Claude (marie@exemple.fr) : msg_7f2a91c4e8b34d0fa6c25e1b9d3f7a48 (agent@exemple.fr → nadia.morel@exemple.com, « Rendez-vous de jeudi ») est en file. Il partira dans le créneau, selon le quota de la boîte (inbox_status).
```

- Le nom de l'accès qui a validé est écrit dans le message (`approved_by`) et dans son journal : celui de l'application, suivi de l'e-mail de l'humain.
- Sans forfait en cours, la validation est refusée avec le code `payment_required`. Un brouillon d'envoi de test se valide toujours.
- Un brouillon écrit depuis la boîte du domaine commun ne se valide que s'il répond à un correspondant qui a écrit : sinon, refus `own_domain_required`.
- Si le destinataire a été bloqué depuis la création du brouillon, la validation est refusée avec le code `recipient_suppressed`.
- Un message qui n'est plus un brouillon est refusé avec le code `not_draft`.
- Avec `revision`, la validation ne vaut que pour ce qui a été lu : si le brouillon a été modifié depuis, elle est refusée avec le code `draft_changed`. La vue des brouillons la transmet d'elle-même.
- Avant de valider, l'humain voit tout ce qui partira : `list_drafts` rend aussi l'adresse de réponse (`reply_to`) et la version HTML (`has_html`, `html`), et les signale dans son texte.

## Annuler un brouillon

`cancel_message` annule un brouillon ou un message en file. Voir [Messages](https://escouade.io/mail/docs/messages.md#cancel_message).

## Dans l'assistant

Dans un assistant qui affiche les vues MCP Apps, `list_drafts` s'accompagne d'une vue : la file des brouillons, avec les gestes « Valider » et « Refuser ». « Valider » appelle `approve_message` avec la version affichée ; « Refuser » appelle `cancel_message`. Sans la permission `approve`, « Valider » est absent.

Corriger un brouillon se demande dans la conversation : l'assistant appelle `update_draft`. Sans vue, tout se lit et se valide par le texte. Voir [Vues](https://escouade.io/mail/docs/vues.md#valider).
