# ObsiGate — Guide MCP (Model Context Protocol) > **Statut :** livré (#79 phase E + F) · **Dernière mise à jour :** 2026-09-11 > **Voir aussi :** [AI_ARCHITECTURE_GUIDE.md](./AI_ARCHITECTURE_GUIDE.md) · > [features/ai-tools-mcp.md](./features/ai-tools-mcp.md) · [ROADMAP.md](./ROADMAP.md) ObsiGate expose ses vaults à des **clients MCP externes** (Claude Desktop, Cursor, tout client compatible MCP) via un serveur **Streamable HTTP** monté sur `/mcp`. Les outils sont les **mêmes** que ceux de l'assistant in-app : la couche `backend/tools/` est la source unique de vérité. --- ## 1. Prérequis 1. Une instance ObsiGate accessible (locale ou distante). 2. Un **jeton JWT** valide (`Authorization: Bearer `), obtenu via `POST /api/auth/login` (ou une clé API). Le jeton porte les permissions par vault de l'utilisateur — l'autorisation MCP réutilise `get_current_user`. 3. Si l'authentification est désactivée (`OBSIGATE_AUTH_ENABLED=false`), le serveur MCP accepte un utilisateur anonyme disposant de tous les vaults. > Le transport `stdio` n'est **pas** encore supporté ; utilisez le transport > HTTP (un pont local type `mcp-remote` si votre client ne gère pas nativement > le Streamable HTTP distant). --- ## 2. Endpoint & protocole | Élément | Valeur | |---|---| | URL | `https:///mcp` | | Transport | Streamable HTTP (`POST` JSON-RPC 2.0, `Accept: application/json, text/event-stream`) | | Auth | `Authorization: Bearer ` | | Protocole MCP | `2025-03-26` (négocié à l'`initialize`) | | Réponses | JSON (`json_response=True`) | Handshake minimal : ```bash curl -sS https://obsigate.example/mcp \ -H "Authorization: Bearer $TOKEN" \ -H "Accept: application/json, text/event-stream" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{ "protocolVersion":"2025-03-26","capabilities":{}, "clientInfo":{"name":"curl","version":"1.0"}}}' ``` La réponse contient l'en-tête `Mcp-Session-Id` à réutiliser pour les appels suivants (`tools/list`, `tools/call`, `resources/read`, …). --- ## 3. Configuration des clients ### Claude Desktop (via pont `mcp-remote`) ```json { "mcpServers": { "obsigate": { "command": "npx", "args": [ "-y", "mcp-remote", "https://obsigate.example/mcp", "--header", "Authorization: Bearer ${OBSIGATE_TOKEN}" ], "env": { "OBSIGATE_TOKEN": "eyJ..." } } } } ``` ### Cursor `.cursor/mcp.json` : ```json { "mcpServers": { "obsigate": { "url": "https://obsigate.example/mcp", "headers": { "Authorization": "Bearer eyJ..." } } } } ``` --- ## 4. Primitives exposées ### 4.1 Tools Les outils de **lecture/recherche** sont exposés directement. Les outils **d'écriture/destructifs** sont exposés via une paire **two-step** : `propose_` (aperçu + jeton de confirmation, aucune modification) puis `apply_` (consomme le jeton et exécute). | Catégorie | Outils | |---|---| | Vaults / navigation | `list_vaults`, `list_directory`, `list_all_files` | | Lecture | `read_file`, `read_file_raw`, `get_backlinks`, `list_backups`, `diff_backup`, `get_graph` | | Recherche | `search_fulltext`, `search_advanced`, `search_paths`, `list_tags`, `suggest_tags`, `list_recent` | | Écriture (propose/apply) | `create_file`, `create_directory`, `edit_file`, `append_to_file`, `restore_backup` | | Destructif (propose/apply) | `rename_file`, `rename_directory`, `move_path`, `replace_in_files`, `delete_file`, `delete_directory` | Flux d'une mutation : ```text 1. tools/call { name: "propose_edit_file", arguments: { vault, path, content } } → { tool, arguments, diff, confirmation_token, expires_in } 2. (l'utilisateur / l'agent valide) 3. tools/call { name: "apply_edit_file", arguments: { confirmation_token } } → { ok: true, data: { ... } } ``` Le jeton est **signé (JWT), à usage unique et à durée de vie limitée** (`OBSIGATE_MCP_CONFIRMATION_TTL`, défaut 300 s). Un rejeu renvoie `token_reused`. ### 4.2 Resources | URI | Contenu | |---|---| | `vault://` | Vault accessible (métadonnées, nombre de fichiers) | | `vault:///` | Contenu d'un fichier (lecture seule, **secrets redactés**) | ### 4.3 Prompts `summarize-directory`, `generate-note`, `find-related`. --- ## 5. Sécurité - **Permissions par vault** : `check_vault_access` est appliqué à chaque outil et chaque resource ; un utilisateur ne voit que ses vaults. - **Anti path-traversal** : `resolve_safe_path` rejette tout chemin hors du vault. - **Confirmation two-step** pour toute mutation (jeton signé, usage unique). - **Toggle par vault** `aiDestructiveTools` (défaut : activé) : le désactiver bloque rename/move/replace/delete tout en laissant create/edit/append. - **Backup automatique** avant chaque opération destructive. - **Rate limiting** : par jeton et par outil (`OBSIGATE_TOOL_RATE_LIMIT`, `OBSIGATE_TOOL_RATE_LIMIT_PER_TOOL`, `OBSIGATE_TOOL_RATE_WINDOW`). Une limite dépassée renvoie le code `rate_limited`. - **Redaction des secrets** : les résultats d'outils (lectures, diffs, extraits de recherche) sont nettoyés avant tout retour au client. - **Audit** : chaque appel est journalisé (`data/audit.log`, action `ai_tool_call`) avec arguments sensibles résumés. ### Variables d'environnement | Variable | Défaut | Rôle | |---|---|---| | `OBSIGATE_MCP_CONFIRMATION_TTL` | `300` | Durée de vie (s) des jetons de confirmation | | `OBSIGATE_TOOL_RATE_LIMIT` | `60` | Appels d'outils max par identité et par fenêtre | | `OBSIGATE_TOOL_RATE_LIMIT_PER_TOOL` | = global | Appels max par outil et par fenêtre | | `OBSIGATE_TOOL_RATE_WINDOW` | `60` | Longueur de la fenêtre (s) | | `BOOKSLM_MAX_TOOL_CALLS` | `25` | Quota d'appels d'outils par run d'agent | | `BOOKSLM_MAX_TOOL_READ_BYTES` | `200000` | Taille max renvoyée par `read_file` | --- ## 6. Dépannage | Symptôme | Cause probable / remède | |---|---| | `401 Authentification requise` | En-tête `Authorization: Bearer` absent ou jeton expiré | | `vault_access_denied` | Le jeton n'a pas accès à ce vault (`vaults` / `_token_vaults`) | | `destructive_tools_disabled` | `aiDestructiveTools=false` pour ce vault | | `confirmation_required` | Appeler d'abord `propose_` puis `apply_` | | `token_reused` / `invalid_confirmation` | Jeton déjà consommé ou expiré → refaire un `propose_` | | `rate_limited` | Quota dépassé ; respecter `retry_after` | | Le client ne se connecte pas | Vérifier le transport Streamable HTTP / le pont `mcp-remote` |