Le serveur MCP de Campbooks se trouve à POST /api/mcp sur toute instance Campbooks. Il implémente le protocole MCP version 2025-03-26 sur HTTP streamable et expose 72 outils (plus 3 outils de contexte qui ne nécessitent aucun scope).
Autorisation
POST /api/mcp accepte trois formes d'Authorization :
| Forme | Valeur d'en-tête | Notes |
|---|
| Clé MCP | Bearer <uid>.<client-secret> | UID du client et secret en clair séparés par un point. Les UID et secrets Doorkeeper ne contiennent pas de point, le point est donc sans ambiguïté. |
| HTTP Basic | Basic base64(uid:secret) | Équivalent HTTP standard de la forme clé MCP. |
| Token Doorkeeper | Bearer <access-token> | Token de courte durée (2 h) obtenu via POST /api/oauth/token. Convient pour les scripts ponctuels ; pas adapté aux configurations d'agents statiques. |
L'API REST (/api/v1/*) accepte uniquement les tokens bearer Doorkeeper. Les formes 1 et 2 — clés MCP — ne sont prises en charge qu'à /api/mcp.
Expiration et rotation des clés
Les clés MCP n'expirent pas. Le serveur effectue une comparaison bcrypt à chaque requête ; les taux d'appel des agents sont bien en deçà de la limite de 600 req/min.
Révoquer un token d'accès Doorkeeper ne désactive pas une clé MCP. Pour révoquer une clé MCP, faites pivoter le client secret ou supprimez le client dans Paramètres → Accès à l'API. La clé MCP est affichée une fois lors de la création du client ; regénérez le client secret si vous la perdez.
Codes d'erreur d'authentification
| Statut | error.code | Quand |
|---|
| 401 | invalid_client | Client introuvable, secret incorrect, application non confidentielle ou secret vide |
| 403 | insufficient_scope | Le client n'a aucun scope assigné |
Scopes
Les scopes contrôlent quels outils apparaissent dans tools/list. Un ensemble plus restreint signifie moins d'outils et moins de contexte par session. La liste complète des scopes est documentée dans la vue d'ensemble de l'API sous Développeurs.
Les trois outils de contexte — get_overview, get_setup_status et guide — ne nécessitent aucun scope et sont toujours disponibles pour tout client authentifié.
Limites de débit
600 requêtes par minute par client. Dépasser cette limite renvoie HTTP 429 avec error.code: "rate_limit_exceeded".
Les outils sont regroupés par famille ci-dessous. La colonne « Scope » indique le OAuth scope requis ; (any) signifie qu'aucun scope n'est requis.
Outils de contexte
| Outil | Scope | Finalité |
|---|
get_overview | (any) | Snapshot rapide de ce qui nécessite attention. Ne renvoie que les sections dont les compteurs ne sont pas nuls. À appeler en premier. |
get_setup_status | (any) | Snapshot de configuration de l'espace de travail pour l'intégration et les diagnostics. Liste les lacunes comme next_steps pour guider la skill de configuration. |
guide | (any) | Guides narratifs pour travailler avec Campbooks via MCP. Sans sujet — liste des sujets disponibles. Passez un nom de sujet pour le guide complet. |
E-mail
| Outil | Scope | Finalité |
|---|
list_emails | emails:read | Liste les e-mails les plus récents accessibles à l'appelant, du plus récent au plus ancien. Filtres optionnels : non lus, requête, compte, catégorie, priorité, plage de dates. |
search_emails | emails:read | Recherche des e-mails avec des filtres. Utilise une combinaison sémantique + mots-clés lorsqu'une requête textuelle est fournie. |
get_email | emails:read | Récupère un seul e-mail par id. format=text (défaut) renvoie le corps en texte brut, tronqué à 8 000 caractères. |
send_email | emails:send | Envoie un nouvel e-mail depuis l'un des comptes connectés de l'appelant. |
reply_email | emails:send | Répond à un e-mail existant. Enchaîne depuis le message source et envoie depuis son compte sauf substitution. |
mark_email_read | emails:write | Marque un e-mail comme lu et synchronise le drapeau avec la boîte aux lettres du fournisseur. |
mark_email_unread | emails:write | Marque un e-mail comme non lu (local uniquement). |
add_email_tag | tags:write | Attache une étiquette existante de l'espace de travail à un e-mail (par tag_id ou nom). Les étiquettes ne sont pas créées ici — utilisez create_tag. |
remove_email_tag | tags:write | Détache une étiquette d'un e-mail. |
update_emails | emails:write | Action en masse sur les e-mails. archive/unarchive/trash/snooze/unsnooze agissent sur des fils entiers (comme l'UI de l'application). |
move_emails_to_folder | emails:write | Déplace des e-mails (et leurs fils complets) vers un dossier. Passez folder_name pour travailler entre comptes. |
tag_emails | tags:write | Ajoute ou supprime une étiquette sur un ensemble d'e-mails. L'étiquette doit exister — utilisez create_tag pour en créer de nouvelles. |
forward_email | emails:send | Transfère un e-mail à une autre adresse. |
get_skim_deck | emails:read | Renvoie le jeu de skim sous forme d'anneaux compacts et de cartes de clusters. Appliquez les décisions avec skim_decide. |
skim_decide | emails:write | Applique une décision de triage Skim aux e-mails d'un cluster. Reproduit la boucle d'apprentissage de l'UI de la boîte de réception (archiver, conserver, promouvoir). |
Comptes e-mail
| Outil | Scope | Finalité |
|---|
list_email_accounts | email_accounts:read | Liste les comptes e-mail connectés visibles à l'appelant. Utilisez l'id comme email_account_id pour le filtrage. |
connect_email_account | email_accounts:write | Connecte un nouveau compte e-mail. mode=web renvoie une URL à ouvrir dans un navigateur (flux OAuth normal — recommandé pour les utilisateurs cloud). mode=token accepte un token de rafraîchissement pré-créé (chemin OAuth local pour l'auto-hébergé). |
Documents
| Outil | Scope | Finalité |
|---|
list_documents | documents:read | Liste les documents de l'espace de travail, du plus récent au plus ancien. Filtres optionnels par id de type de document et statut de révision. |
get_document | documents:read | Récupère un document par id avec ses champs extraits et les informations de fichier (téléchargement via download_path du fichier). |
upload_document | documents:write | Téléverse un nouveau document depuis un contenu base64. La classification par IA s'exécute de manière asynchrone. |
update_document | documents:write | Modifie les champs extraits d'un document. Ne change pas son statut de révision (utilisez approve/reject/reclassify pour cela). |
approve_document | documents:write | Approuve (signe) un document. |
reject_document | documents:write | Rejette un document. |
reclassify_document | documents:write | Change le type d'un document (l'approuve également). |
| Outil | Scope | Finalité |
|---|
list_contacts | contacts:read | Liste les contacts de l'espace de travail. Requête textuelle optionnelle sur nom/e-mail et filtre favoris uniquement. |
get_contact | contacts:read | Récupère un seul contact par id. |
update_contact | contacts:write | Met à jour le nom et/ou le type de relation d'un contact. |
set_contact_state | contacts:write | Ajouter/retirer des favoris, autoriser, bloquer ou débloquer un contact. |
Étiquettes
| Outil | Scope | Finalité |
|---|
list_tags | tags:read | Liste les étiquettes de l'espace de travail (les étiquettes s'appliquent aux e-mails). |
create_tag | tags:write | Crée une nouvelle étiquette dans l'espace de travail. Les étiquettes s'appliquent aux e-mails et peuvent être utilisées pour filtrer. |
Types de document
| Outil | Scope | Finalité |
|---|
list_document_types | document_types:read | Liste les types de document de l'espace de travail (utilisés pour classifier les documents). |
create_document_type | document_types:write | Crée un nouveau type de document pour classifier les pièces jointes. |
Dossiers
| Outil | Scope | Finalité |
|---|
list_folders | folders:read | Liste les dossiers personnalisés de l'espace de travail. |
get_folder | folders:read | Récupère un dossier et les documents qui y sont archivés. |
create_folder | folders:write | Crée un dossier personnalisé. Quand provision: true, le dossier est créé sur chaque compte e-mail connecté comme étiquette/dossier côté fournisseur. |
file_document | folders:write | Archive un document dans un dossier. |
unfile_document | folders:write | Retire un document d'un dossier (par id de membre). |
Tâches (conditionnel)
Les outils de tâches nécessitent que la fonctionnalité Tâches soit activée sur le serveur (ENABLE_TASKS). Ils n'apparaissent dans tools/list que lorsque la fonctionnalité est active.
| Outil | Scope | Finalité |
|---|
list_tasks | tasks:read | Liste les tâches de l'espace de travail. Filtre de statut optionnel ; include_archived pour voir les tâches archivées. |
get_task | tasks:read | Récupère une tâche par id avec le détail complet. |
create_task | tasks:write | Crée une tâche dans l'espace de travail. |
update_task | tasks:write | Met à jour les champs d'une tâche. Les changements de statut utilisent la transition appropriée (publie des événements). |
complete_task | tasks:write | Marque une tâche comme terminée. |
create_task_from_email | tasks:write | Extrait et crée une tâche à partir d'un e-mail via le registre d'actions. |
Calendrier
| Outil | Scope | Finalité |
|---|
list_calendars | calendar:read | Liste les calendriers visibles à l'appelant. Utilisez l'id comme calendar_id dans create_calendar_event. |
list_calendar_events | calendar:read | Liste les événements de calendrier accessibles à l'appelant, du plus proche au plus lointain. Filtres optionnels start_after / start_before. |
get_calendar_event | calendar:read | Récupère un événement de calendrier par id. |
create_calendar_event | calendar:write | Crée un événement de calendrier sur l'un des calendriers modifiables de l'appelant. Les heures sont en ISO-8601. |
update_calendar_event | calendar:write | Met à jour un événement de calendrier (accès en écriture requis). recurrence_scope : this ou all. |
delete_calendar_event | calendar:write | Supprime un événement de calendrier (suppression asynchrone côté fournisseur). recurrence_scope : this ou all. |
rsvp_calendar_event | calendar:write | Définit votre RSVP sur un événement (needs_action, accepted, declined, tentative). |
create_event_from_email | calendar:write | Extrait et crée un événement de calendrier à partir d'un e-mail. L'IA infère les détails de l'événement ; fournissez des substitutions au besoin. |
Rappels
| Outil | Scope | Finalité |
|---|
list_reminders | reminders:read | Liste les rappels extraits par l'IA accessibles à l'appelant. Filtre de statut optionnel (pending, confirmed, dismissed, snoozed). |
get_reminder | reminders:read | Récupère un rappel par id. |
confirm_reminder | reminders:write | Confirme un rappel en événement de calendrier. Passez optionnellement due_at pour ajuster l'heure d'abord. |
dismiss_reminder | reminders:write | Ignore un rappel. |
snooze_reminder | reminders:write | Reporte un rappel à l'heure indiquée, ou une semaine si omis. |
E-mails programmés
| Outil | Scope | Finalité |
|---|
list_scheduled_emails | scheduled_emails:read | Liste les e-mails programmés (et récurrents) dans l'espace de travail, de la prochaine occurrence la plus proche à la plus lointaine. |
get_scheduled_email | scheduled_emails:read | Récupère un e-mail programmé par id. |
create_scheduled_email | scheduled_emails:write | Programme un e-mail pour envoi ultérieur (optionnellement récurrent via RRULE). Envoie depuis un compte depuis lequel l'utilisateur peut envoyer. |
update_scheduled_email | scheduled_emails:write | Met à jour un e-mail programmé en attente (destinataire, sujet, corps, heure, rrule). |
cancel_scheduled_email | scheduled_emails:write | Annule un e-mail programmé (doux : définit le statut à cancelled). |
Scout
| Outil | Scope | Finalité |
|---|
list_scout_threads | scout:read | Liste les fils de chat Scout de l'appelant, du plus récent au plus ancien. |
create_scout_thread | scout:write | Démarre un nouveau fil de chat Scout. |
list_scout_messages | scout:read | Liste les messages dans un fil Scout. Passez after_message_id pour attendre la réponse asynchrone de l'IA. |
send_scout_message | scout:write | Publie un message utilisateur dans un fil Scout. La réponse de l'IA est générée de manière asynchrone ; utilisez list_scout_messages avec after_message_id jusqu'à ce qu'elle apparaisse. |
Flux de travail (conditionnel)
Les outils de flux de travail nécessitent que la fonctionnalité Flux de travail soit activée sur le serveur (ENABLE_WORKFLOWS). Ils n'apparaissent dans tools/list que lorsque la fonctionnalité est active.
| Outil | Scope | Finalité |
|---|
list_workflows | workflows:read | Liste les flux de travail d'automatisation de l'espace de travail. |
trigger_workflow | workflows:trigger | Déclenche un flux de travail webhook activé avec un payload JSON optionnel. |
list_workflow_executions | workflows:read | Liste l'historique d'exécutions d'un flux de travail (du plus récent au plus ancien). |
Modèles (conditionnel)
| Outil | Scope | Finalité |
|---|
list_email_templates | templates:read | Liste les modèles d'e-mail réutilisables de l'espace de travail. |
Familles conditionnelles
Trois familles d'outils sont masquées lorsque la fonctionnalité serveur correspondante est désactivée :
| Famille | Variable d'environnement serveur | Par défaut |
|---|
| Tâches | ENABLE_TASKS | désactivé |
| Flux de travail | ENABLE_WORKFLOWS | désactivé |
| Modèles | (drapeau interne) | variable |
Ces outils n'apparaissent simplement pas dans tools/list quand la fonctionnalité est désactivée — ils ne renvoient pas d'erreur.
connect_email_account — mode web vs. token
L'outil connect_email_account prend en charge deux modes :
mode: "web" — renvoie un chemin relatif à ouvrir dans un navigateur. Le flux OAuth du serveur gère la redirection ; c'est le bon choix pour les utilisateurs de Campbooks Cloud et tout serveur dont les callbacks OAuth sont publiquement accessibles.
mode: "token" — accepte un token de rafraîchissement pré-créé directement. Utilisez-le pour les instances auto-hébergées où les callbacks OAuth du serveur ne sont pas accessibles depuis internet. Le token doit avoir été créé avec les accréditations OAuth du serveur lui-même (GOOGLE_CLIENT_ID/ZOHO_CLIENT_ID), sinon le serveur échouera à le rafraîchir. Consultez Claude Code → OAuth local pour le script d'assistance.
Garanties de sécurité
Permissions de boîte aux lettres par utilisateur — une clé MCP agit en tant qu'utilisateur qui l'a créée. Les boîtes aux lettres que cet utilisateur ne peut pas lire dans l'application, la clé ne le peut pas non plus. Les comptes depuis lesquels cet utilisateur ne peut pas envoyer, la clé ne le peut pas non plus. Les OAuth scopes sont un plafond supplémentaire au-dessus de ces permissions, pas un remplacement.
404-pas-403 — les ressources qui existent mais appartiennent à un espace de travail différent renvoient 404, pas 403. L'API et le serveur MCP ne révèlent jamais si une ressource existe en dehors de vos données.
Confirmer avant d'envoyer — les skills /campbooks:triage et /campbooks:setup sont conçues pour afficher le texte complet du brouillon et attendre un « oui » explicite avant d'appeler send_email, reply_email ou forward_email. Si vous construisez votre propre invite d'agent sur les outils MCP, suivez le même modèle : n'appelez jamais un outil d'envoi sans approbation explicite de l'utilisateur dans le même échange.