Cette page t'a-t-elle aidé ?
Cette page t'a-t-elle aidé ?
Référence
MCP (Model Context Protocol) expose les capacités de votre workspace Gilbert (Gmail, Calendar, notifications Telegram, workspaces, routines) à n'importe quel client compatible : Claude Code, claude.ai, ChatGPT custom connectors, Cursor, Codex CLI, n8n, scripts custom. Auth OAuth 2.1 PKCE, token Bearer, scopes explicites.
Dernière mise à jour : 22 juillet 2026
MCP (Model Context Protocol) est un standard ouvert publié par Anthropic en 2024. C'est, en pratique, un format HTTP qui permet à un assistant IA (Claude, ChatGPT, Cursor, etc.) de découvrir et d'appeler des outils externes : lire un calendar, chercher dans une boîte mail, envoyer une notification, etc. Aujourd'hui, la majorité des clients IA grand public et professionnels parlent MCP.
Le bridge MCP de Gilbert expose une partie des capacités de votre workspace, celles qui sont déjà configurées via vos intégrations OAuth (Google, Telegram, LinkedIn, etc.), à ces clients externes. Concrètement : votre client MCP ouvre le flow OAuth Gilbert, vous approuvez les scopes demandés, puis le client appelle /api/mcp avec un access token Bearer. Votre assistant peut alors répondre à « quels sont mes 3 derniers mails ? » ou « qu'est-ce que j'ai cette semaine au calendar ? » en passant par vos tokens Google déjà connectés côté Gilbert.
Le client MCP ne récupère jamais vos refresh tokens Google ou LinkedIn : il reçoit seulement un token Gilbert court-vivant, scopé à MCP. Une fois branché, votre client IA voit la liste des tools disponibles via tools/list et les invoque via tools/call (JSON-RPC 2.0 par-dessus HTTP, streamable).
Le cas d'usage type, qui motive la plupart des installations : vous êtes IT dans une PME, vous avez déployé Gilbert pour l'équipe et configuré les intégrations Google (Gmail / Calendar) au niveau du workspace. Vos collaborateurs utilisent déjà Claude Code ou ChatGPT pour leur travail quotidien. Vous voulez que leur assistant puisse lire leur Gmail et leurCalendar via Gilbert, sans repasser par l'UI Gilbert et sans configurer chaque OAuth Google côté client IA.
Avec le bridge MCP, chaque collaborateur autorise son client favori via OAuth PKCE et bénéficie des intégrations workspace côté Gilbert, strict isolé par utilisateur : le token d'Alice ne voit jamais la boîte mail de Bob, même s'ils partagent le même workspace.
Cinq étapes. Comptez vraiment une minute si vos intégrations OAuth sont déjà connectées.
Le bridge MCP n'invente rien : il expose ce qui est déjà branché côté Gilbert. Allez sur Console → Mon compte → Intégrations et connectez au minimum Google (Gmail + Calendar) ou Telegram. Sans aucune intégration, votre token MCP fonctionnera mais ne pourra rien lire.
Dans Claude Code, ChatGPT, Cursor ou votre client compatible, ajoutez un serveur MCP HTTP avec cette URL :
https://gilbert.solveholding.com/api/mcpLes clients modernes découvrent automatiquement les endpoints OAuth depuis /.well-known/oauth-protected-resource et /.well-known/oauth-authorization-server. Connectez-vous à Gilbert, vérifiez le client et les scopes, puis approuvez. Le client reçoit un access token Bearer d'une heure ; aucun secret long terme n'est copié dans un fichier.
Choisissez votre client. Tous les exemples utilisent l'URL Gilbert à l'étape 2. La clé solveci-dessous n'est qu'un exemple : renommez ce connecteur selon le nom choisi par votre entreprise.
{
"mcpServers": {
"solve": {
"url": "https://gilbert.solveholding.com/api/mcp"
}
}
}Pour claude.ai (web) et ChatGPT custom connectors : pas de fichier config, allez dans Settings → Connectors → Add custom (HTTP transport), collez l'URL telle quelle. ChatGPT lit les métadonnées OAuth, ouvre le consent screen Gilbert, puis affiche les tools correspondant aux scopes approuvés.
Dans votre client, demandez par exemple : « Liste-moi mes 3 derniers mails non lus » ou « Qu'est-ce que j'ai au calendar aujourd'hui ? ». Le client devrait appeler gmail_list_recent ou calendar_list_today et répondre avec vos vraies données.
Gilbert expose les métadonnées OAuth attendues par les clients MCP modernes, dont ChatGPT MCP Apps. Le client part de la ressource https://gilbert.solveholding.com/api/mcp, lit les documents .well-known, enregistre un client public, puis échange un authorization code PKCE contre un access token.
| Endpoint | Usage |
|---|---|
| /.well-known/oauth-protected-resource | Métadonnées de la ressource MCP, scopes supportés et serveur d'autorisation. |
| /.well-known/oauth-authorization-server | Endpoints authorize/token/register, PKCE S256, grant authorization_code. |
| /api/oauth/register | Dynamic client registration (clients publics : Claude, ChatGPT). Redirect URI en https: ou localhost, sans secret (PKCE seul). Les clients confidentiels (Gemini Enterprise) sont pré-enregistrés depuis la console, pas par DCR. |
| /api/oauth/authorize | Consent screen Gilbert. Le code d'autorisation expire en 10 minutes. |
| /api/oauth/token | Échange code + verifier PKCE contre un access token Bearer. TTL actuel : 1 heure. |
Claude et ChatGPT s'enregistrent tout seuls (Dynamic Client Registration). Gemini Enterprise ne le fait pas : son connecteur « Custom MCP Server » attend un client OAuth confidentiel pré-enregistré (un client_id + un client_secretque l'admin colle dans la console Google). Gilbert génère ce client en self-serve.
Allez sur Console → Workspaces → [votre workspace] → Connecteurs IA, cliquez « Générer un connecteur ». Le client_secret s'affiche une seule fois : copiez-le immédiatement. Le client est scopé à ce workspace.
Google Cloud console → Gemini Enterprise → Data stores → Create data store → « Custom MCP Server (Preview) ». Collez :
MCP Server URL : https://gilbert.solveholding.com/api/mcp
Authorization URL : https://gilbert.solveholding.com/api/oauth/authorize
Token URL : https://gilbert.solveholding.com/api/oauth/token
Client ID : (généré à l'étape 1)
Client Secret : (généré à l'étape 1, affiché une fois)
Scopes : mcp:read mcp:write workspace:read mcp:destructive offline_access
Redirect URI : https://vertexaisearch.cloud.google.com/oauth-redirectmcp:destructivepeut être demandé explicitement ici (client confidentiel pré-enregistré) : il apparaîtra dans la liste des scopes sur l'écran de consentement. Ne l'incluez pas si ce connecteur ne doit jamais envoyer de mail ni poster en votre nom.
Le bouton « Login » du connecteur ouvre le consent screen Gilbert. L'utilisateur qui autorise doit avoir un compte Gilbert membre de ce workspace (le consentement passe par /login). La connexion atterrit dans le workspace du connecteur, pas ailleurs. Si le connecteur doit pouvoir envoyer des mails, répondre aux invitations ou poster sur Slack, cochez aussi « Autoriser les actions » sur cet écran : c'est elle, et non le scope demandé ci-dessus, qui décide en dernier ressort si mcp:destructive est accordé.
Les scopes sont portés par le token OAuth. tools/list masque les tools que le token ne peut pas appeler ; tools/call refuse avec Missing required scope si un scope manque.
| Scope | Ce qu'il débloque |
|---|---|
| mcp:read | Lister les tools disponibles via tools/list. |
| mcp:write | Appeler un tool via tools/call. Les handlers gardent leurs propres contrôles métier. |
| mcp:destructive | Appeler les tools qui écrivent réellement côté tiers (gmail_send, calendar_respond, calendar_create_event, slack_post_to_channel, create_scheduled_draft) et confirm_action, le seul chemin d'exécution de ces actions. Absent des scopes publiquement annoncés: ne s'obtient qu'en cochant « Autoriser les actions » sur l'écran de consentement OAuth, jamais par simple négociation de scope côté client. |
| workspace:read | Découvrir les workspaces accessibles, leurs routines, canaux et membres autorisés. |
| routines:run | Réservé aux appels de routines. Le scope est publié dans la metadata OAuth ; les tools actuels gardent encore leurs gates métier existants. |
| offline_access | Marqueur OAuth (pas une permission tool) : demande l' émission d'un refresh token pour garder la connexion au-delà d'une heure. Émis aussi d'office pour les clients confidentiels. |
Étapes exactes pour envoyer votre premier mail via MCP, du consentement à l'exécution confirmée.
Si ce n'est pas déjà fait : Console → Mon compte → Intégrations, connectez Gmail.
Lors de l'étape « Approuver OAuth PKCE » du setup ci-dessus, l'écran de consentement Gilbert affiche une case décochée par défaut : « Autoriser les actions (envoi de mails, invitations, posts) ». Cochez-la avant de cliquer sur « Autoriser ». Sans cette case, mcp:destructive n'est jamais accordé, même si votre client l'avait demandé dans son scope.
Un client MCP lit généralement la liste des tools une fois par session. Démarrez une nouvelle conversation dans votre client pour qu'il rappelle tools/list et voie apparaître gmail_send et les autres destructifs.
Le client appelle gmail_send. La réponse n'est pas un mail envoyé : c'est un texte qui décrit l'action proposée et contient une ligne pending_action_id: …. Rien n'est parti.
L'annotation MCP destructiveHint est portée par confirm_action(pas par gmail_send lui-même, qui ne fait que proposer) : un client conforme (claude.ai) affiche sa propre UI d'approbation avant d'appeler confirm_action. Une fois que vous approuvez, le client appelle confirm_action({id, action:'confirm'}) : Gilbert exécute réellement l'envoi et répond avec l'id du mail parti. Pour refuser sans rien exécuter : confirm_action({id, action:'abort'}). Sans confirmation ni annulation, l'action expire au bout de 10 minutes.
Liste des tools accessibles via un token personnel. La plupart sont en lecture seule, notification ou écriture non destructive (brouillon, création de routine). Les tools qui écrivent ou émettent réellement côté tiers (envoi de mail, RSVP calendar, post Slack…) sont marqués destructif dans la colonne Scope : ils exigent le scope mcp:destructiveet ne s'exécutent jamais directement, voir confirm_action plus bas. La colonne Intégration requiseindique quel OAuth doit être connecté côté Gilbert pour que le tool fonctionne, sinon il retourne une erreur explicite demandant à l'utilisateur de connecter l'intégration.
| Nom | Description | Scope | Intégration requise |
|---|---|---|---|
| gmail_list_recent | Liste les mails récents (24h, non-lus en priorité). | read | |
| gmail_search | Recherche dans toute la boîte (syntaxe Gmail : from:, subject:, after:…). | read | |
| gmail_read_message | Lit le corps complet d'un mail (au-delà du snippet). | read | |
| gmail_create_draft | Crée un brouillon Gmail. N'envoie rien : le brouillon reste rattrapable dans la boîte de l'utilisateur. Support reply_mode='all' pour répondre à tous. | write | |
| gmail_send | Envoie réellement un mail. Destructif: ne s'exécute jamais directement, crée une action en attente à confirmer via confirm_action. | destructif (mcp:destructive) | |
| calendar_list_today | Évenements du calendar primary pour aujourd'hui (timezone Europe/Paris par défaut). | read | |
| calendar_list_range | Événements entre deux timestamps ISO (semaine, mois, ad-hoc). | read | |
| calendar_respond | Répond à une invitation calendar (accepted / declined / tentative). Destructif : même gate que gmail_send, via confirm_action. | destructif (mcp:destructive) | |
| calendar_create_event | Crée un événement (primary). Envoie des invitations aux attendees fournis. Destructif : via confirm_action. | destructif (mcp:destructive) | |
| fetch_url | Récupère le contenu d'une URL publique (HTML, JSON, texte) en GET. SSRF-safe : hôtes privés et métadonnées cloud bloqués, re-vérifiés à chaque redirection. Plafond 16 Ko par défaut, réglable via max_bytes (borne 50 Ko). | read | Aucune |
| repo_list_files | Liste les fichiers d'un repo GitHub lié au workspace (branche et sous-dossier optionnels). workspace_idoptionnel pour cibler un autre workspace dans le périmètre du token (fail-closed si vous n'en êtes pas membre). | read | GitHub |
| repo_read_file | Lit le contenu UTF-8 d'un fichier d'un repo lié (max 100 Ko). workspace_id optionnel, même règle que repo_list_files. | read | GitHub |
| repo_search | Recherche de code dans les repos liés du workspace via GitHub Code Search. workspace_id optionnel, même règle que repo_list_files. | read | GitHub |
| list_routines | Liste les routines (tâches cron) de l'utilisateur : prochain tick, dernier statut, workspace. | read | Aucune |
| create_scheduled_draft | Crée une routine récurrente (cron), immédiatement active une fois confirmée. Destructif: c'est la création elle-même qui est gatée via confirm_action, pas chaque exécution ultérieure. | destructif (mcp:destructive) | Aucune |
| list_workspaces | Liste les workspaces accessibles au user authentifié. | workspace:read | Aucune |
| get_workspace | Détail filtré d'un workspace accessible : nom, description, rôle, settings non sensibles. | workspace:read | Aucune |
| get_workspace_summary | Résumé opérationnel d'un workspace (counts membres/routines/channels, dernières exécutions, statut global) et diagnostic des scopes MCP accordés à la connexion courante : quels scopes sont présents, lesquels manquent, et comment obtenir mcp:destructive s'il manque. | workspace:read | Aucune |
| list_workspace_routines | Liste les routines d'un workspace. enabledsignifie routine active + abonnement user non pausé (et, pour les routines à job serveur, job de planification actif ; les routines externes type Claude Code n'en ont pas et restent enabledtant qu'elles sont actives). Chaque routine porte ses categories ([{ slug, name, isRecommended }]) et un booléen isRecommended; la liste est triée recommandé d'abord. | workspace:read | Aucune |
| apply_routine | Applique une routine au document/contexte fourni dans le chat (« utilise ma routine Rédaction de PV d'AG sur ce document »). Résout par task_idou nom (workspaceId optionnel pour lever une ambiguïté) et renvoie les instructions de la routine à appliquer immédiatement : l'hôte (Claude/Gemini) produit le livrable, rien ne s'exécute côté serveur. Tout membre du workspace y a accès ; les résultats restent privés. | workspace:read | Aucune |
| create_routine | Crée une routine dans un workspace dont vous êtes membre (« crée une routine qui… »). Vous y êtes automatiquement abonné. cron_expression optionnel (absent = routine ad-hoc, applicable ensuite via apply_routine). model_tier optionnel (fast / smart / premium, défaut smart). mcp_server_slugs optionnel : slugs des serveurs MCP du workspace exposés à la routine (absent = tous, [] = aucun). Routine personnelle ; clé MCP personnelle requise. | workspace:read | Aucune |
| run_routine | Déclenche un run server-side (execution_mode=server) d'une routine dont vous êtes membre, par routine_id ou nom. Le serveur exécute le prompt et livre sur les canaux de la routine : rien à produire côté hôte. scope optionnel (workspace par défaut diffuse à tout le workspace, self réserve le résultat au caller ; sans effet sur une routine personnelle). | routines:run | Aucune |
| adopt_category | Abonne l'utilisateur à toutes les routines d'une catégorie (pack), en une action. Requiert workspaceId, plus categoryId ou categorySlug (ex. gmail). Idempotent : les routines déjà abonnées sont ignorées et listées dans skipped ; subscribed_count ne compte que les abonnements réellement créés ou réactivés. Clé MCP personnelle requise. | workspace:read | Aucune |
| deliver_artifact | Rend un contenu validé (html / docx / pdf) et l'envoie vers UN canal résolu et autorisé : user.email (vérifié), user.telegram_dm, workspace.email_broadcast ou workspace.slack. Pas de LLM, pas de routine. Les canaux workspace.* exigent le rôle admin. | notify | Aucune |
| list_workspace_channels | Liste les canaux/connecteurs d'un workspace sans exposer tokens, secrets, adresses webhook ou config sensible. | workspace:read | Aucune |
| list_workspace_members | Liste les membres si le caller est admin du workspace. | workspace:read | Aucune |
| slack_post_to_channel | Poste un message dans un channel Slack mappé au workspace (Gilbert doit y avoir été invité). Destructif : via confirm_action. | destructif (mcp:destructive) | Slack |
| notify_canal | Notifie sur votre canal connecté préféré (Telegram si apparié, sinon email vérifié) ou un Forum topic Telegram partagé. L'utilisateur peut répondre, Gilbert garde le contexte pour rerouter. | notify | Telegram, Email |
| mark_reply_processed | Acknowledge une reply Telegram après traitement par l'agent côté client. | write (ack) | Telegram |
| sync_scheduled_tasks | Récupère les routines execution_mode=client en attente de création côté Claude Code. | read | Aucune |
| mark_task_synced | Confirme côté Gilbert qu'une routine a bien été créée comme background task Claude Code. | write (ack) | Aucune |
| publish_linkedin_post | Programme une publication LinkedIn (texte uniquement, UGC ShareContent, max 3000 chars) avec un délai serveur de 5 minutes annulable via Telegram. Voir section dédiée. | delayed write | LinkedIn + Telegram |
| recall_actions | Recherche dans l'historique des actions proposées ou exécutées (mails envoyés, réponses calendar, posts…). Sur MCP, chaque ligne inclut son pending_action_id, réutilisable directement avec confirm_action. Read-only, pas de gate. | read | Aucune |
| confirm_action | Confirme (action:'confirm') ou annule (action:'abort') une action destructive précédemment proposée via MCP. C'est le SEUL chemin d'exécution des destructifs MCP, voir le walkthrough plus haut. | destructif (mcp:destructive) | Aucune |
Trois tools administratifs supplémentaires (provision_workspace, seed_workspace_routines, generate_commercial_offer) sont exposés via MCP mais gated à un caller admin d'au moins un workspace Solve : ils servent aux routines commerciales internes (provisioning de workspaces prospects). Vous ne les croiserez pas en usage standard. provision_workspacecrée toujours un workspace hors de tout périmètre choisi à l'écran de consentement (il n'existait pas encore au moment d'autoriser le connecteur) : il est donc refusé pour tout token dont l'allowlist est restreinte à un sous-ensemble de workspaces, même si le caller est admin Solve. L'écran de consentement rejette désormais une sélection vide dès qu'au moins un workspace est accessible, donc un token non restreint ne peut plus s'obtenir via le picker de cases à cocher — seule une clé legacy (personnelle ou workspace, jamais soumise à cette allowlist) permet d'appeler ce tool aujourd'hui.
Trois invariants tiennent l'ensemble du bridge :
gilbert. Côté workspace, cette allowlist est appliquée serveur à chaque tool de découverte/action, au chemin direct-id de run_routine et au handshake initialize: un token restreint à un sous-ensemble ne peut jamais atteindre un workspace hors périmètre, même si l'user en devient membre plus tard sans re-consentement.publish_linkedin_post est exposé via MCP avec un confirm-flow obligatoire. Deux remparts indépendants protègent contre la publication non-souhaitée :
La description du tool exige que le client AI (Claude, ChatGPT, Cursor) demande confirmation explicite à l'utilisateur avant de l'appeler, en montrant un preview du texte exact et en n'invoquant le tool que si l'utilisateur répond « oui » / « go » / « publie ». Cette convention couvre le cas d'usage légitime (Martin via Claude Code) : Claude demande « OK pour poster ? » et exécute le tool si l'utilisateur confirme.
Une fois le tool appelé, la publication n'est pas instantanée. Le serveur Gilbert programme l'action dans 5 minutes (insertion dans personal_pending_actions avec status='scheduled' et scheduled_at=now()+5min) et envoie immédiatement une notification Telegram à l'utilisateur avec un preview du texte + la commande /cancel-linkedin <action_id>.
Si l'utilisateur répond avec la commande dans la fenêtre, l'action passe à canceled et la publication ne part pas. Sans action, le worker /api/cron/pending-actions-tick exécute la publication une fois scheduled_at dépassé.
Les actions qui écrivent ou émettent réellement côté tiers (envoi de mail, réponse à une invitation calendar, création d'événement, post Slack, création de routine récurrente) sont exposées via MCP, mais aucune ne s'exécute directement : l'appel initial (gmail_send, calendar_respond, calendar_create_event, slack_post_to_channel, create_scheduled_draft) crée une action en attente (personal_pending_actions, TTL 10 minutes) et renvoie un texte contenant une ligne pending_action_id: …. Le client doit repasser cet id à confirm_actionpour que quoi que ce soit s'exécute réellement : c'est la même barrière humaine que le rituel « ok »/« annule » du chat Gilbert, portée côté MCP par l'annotation destructiveHint sur confirm_action (pas sur le tool destructif lui-même, qui ne fait que proposer). Voir le walkthrough plus haut pour un exemple complet.
confirm_action accepte deux actions :
action:'confirm' exécute réellement l'action proposée (idempotent : rappeler confirm avec le même id déjà exécuté renvoie le même résultat sans ré-exécuter).action:'abort'annule l'action sans rien exécuter.not_found: ré-invoquez le tool d'origine pour reproposer l'action (avec un nouvel id de confirmation).publish_linkedin_post reste exposé avec son propre mécanisme (confirm-flow côté client AI + délai serveur de 5 minutes annulable via Telegram, pas confirm_action), voir section dédiée plus bas.
Le scope mcp:destructiveest nouveau (12 juillet 2026). Les connexions MCP existantes, personnelles ou connecteurs Gemini Enterprise, ne l'ont pas : il n'y a pas d'octroi rétroactif. Sans reconnexion, gmail_send et les autres destructifs restent simplement absents de tools/list pour ces tokens.
Reconnectez le serveur MCP depuis votre client (déconnecter puis reconnecter Gilbert, ou révoquer la clé depuis Console → Mon compte → Bridge MCP) pour redéclencher le flow OAuth complet.
Sur l'écran de consentement qui s'affiche, cochez « Autoriser les actions (envoi de mails, invitations, posts) » avant de cliquer sur « Autoriser ». C'est la seule voie d'acquisition de mcp:destructive: le scope n'est pas dans la liste publiquement annoncée, un client ne peut pas l'obtenir simplement en le demandant.
Un admin ajoute mcp:destructive aux scopes du connecteur (Google Cloud console → Gemini Enterprise → Data stores → connecteur Gilbert) puis relance le flow « Login » : l'utilisateur qui consent doit cocher la même case « Autoriser les actions ».
Une session déjà ouverte a mis en cache l'ancienne liste de tools. Démarrez une nouvelle conversation pour que le client rappelle tools/list et voie apparaître les destructifs.
Les anciennes clés (feature flag mcp_legacy_key_auth) ont des scopes figés à la création et ne peuvent jamais obtenir mcp:destructive. Migrez vers OAuth pour débloquer les actions.
WWW-Authenticate avec l'URL de discovery OAuth ; relancez le flow de connexion du client. ChatGPT custom connectors sait reprendre automatiquement après le callback OAuth.mcp:read pour lister les tools, mcp:write pour les appeler, workspace:read pour découvrir workspaces/routines/membres, ou mcp:destructive pour les tools qui envoient/écrivent réellement (voir la section Migration : reconnecter pour débloquer les actions ci-dessus : ce dernier ne s'obtient qu'en cochant « Autoriser les actions » au consentement, pas en le demandant simplement dans le scope).Missing required scope (voir ci-dessus), pas Unknown tool. Une clé workspace qui appelle un tool réservé aux clés personnelles reçoit un message dédié l'indiquant explicitement (« requires user-scope MCP key »).workspaceIddemandé n'est pas accessible au user authentifié, ou est en dehors du périmètre de workspace(s) choisi à l'écran de consentement OAuth pour ce token : réautorisez le connecteur en cochant ce workspace pour l'ajouter au périmètre. list_workspace_members exige en plus le rôle admin sur ce workspace./api/personal/api-key/rotate, sans impact en usage normal. Attendez 60s avant la prochaine rotation.mcp-remote côté npm) qui fait le pont stdio ↔ HTTP.execution_mode=client tournent en background tasks Claude Code, ack via mark_task_synced, et routent les replies Telegram vers la session active. Le provider LLM est indépendant : server ou client, anthropic ou google. Pour qui veut automatiser via cron plutôt que par chat.