Documentation MCP
Le serveur MCP de Tauraco permet à un assistant IA (Claude, un agent maison, tout client compatible avec le Model Context Protocol) de lire les données d'une entreprise, avec les droits de l'utilisateur qui l'a connecté et rien de plus. Il est en lecture seule, à une exception non destructive près : demander un export.
En ligne depuis le 2026-11-05 (répond 401 sans jeton) ; seize outils, deux ères du protocole, éprouvés hors production. Sans jeton,
https://api.tauraco.io/mcprépond 401 avec un en-têteWWW-Authenticatequi porteresource_metadata: c'est la réponse attendue, celle qui lance la découverte OAuth de votre client. Aucun connecteur Claude.ai n'a encore été vérifié en conditions réelles ; la procédure de connexion ci-dessous est inchangée.
Adresse
- Endpoint :
https://api.tauraco.io/mcp(transport Streamable HTTP, sans état). - Alias en ligne :
https://mcp.tauraco.io/mcp(depuis le 2026-11-05) ethttps://mcp.tauraco.ai/mcp(depuis le 2026-11-06), même serveur ; seuls/mcpet/.well-known/y sont servis. L'identité de la ressource restehttps://api.tauraco.io/mcp. - Ressource protégée (RFC 9728) :
https://api.tauraco.io/.well-known/oauth-protected-resource/mcp. - Serveur d'autorisation :
https://api.tauraco.io(métadonnées RFC 8414 à/.well-known/oauth-authorization-server).
Les deux ères du protocole
Le serveur est bi-ère : un même endpoint sert les clients de l'ère historique et ceux de l'ère moderne. Un client historique face à un serveur seulement moderne échoue ; c'est pourquoi les deux sont servies.
| Ère historique (« legacy ») | Ère moderne | |
|---|---|---|
| Révisions | 2025-11-25 et antérieures | 2026-07-28 et suivantes |
| Ouverture | poignée de main initialize puis notifications/initialized | aucune session ; découverte facultative par server/discover |
| Métadonnées | négociées une fois à initialize | portées par chaque requête (_meta) |
| En-têtes | MCP-Protocol-Version après l'initialisation | MCP-Protocol-Version, Mcp-Method et, pour tools/call, Mcp-Name obligatoires sur chaque POST |
| Clients constatés | Claude.ai (web, Desktop, mobile), Claude Code v1, MCP Inspector par défaut | Claude Code v2 (négociation automatique), SDK Python 2.x en mode automatique |
Une incohérence entre en-tête et corps en ère moderne donne 400 avec l'erreur JSON-RPC -32020 ; une version inconnue 400 avec -32022 et la liste data.supported.
Authentification
- Sans jeton, toute requête reçoit
401avecWWW-Authenticate: Bearer resource_metadata="https://api.tauraco.io/.well-known/oauth-protected-resource/mcp", scope="mcp:read". C'est ce 401 qui déclenche la connexion OAuth du client. - Le client lit les métadonnées de la ressource puis du serveur d'autorisation.
- S'il n'a pas d'identifiant, il s'enregistre par
/oauth/register(enregistrement dynamique RFC 7591, ouvert par un drapeau dédié ; client public, aucun scope avant consentement). Les adresses de retour admises sonthttps://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callbacket la boucle locale (http://localhost:<port>/…,http://127.0.0.1:<port>/…). - Flux
authorization_codeavec PKCE S256 etresource=https://api.tauraco.io/mcp: l'utilisateur choisit l'entreprise et accepte les scopes sur la page de consentement de Tauraco. - Jeton d'audience
tauraco-mcp, 60 minutes, rafraîchissable.
Chaque requête exige mcp:read ; chaque outil exige en plus son scope. Un scope manquant est refusé au niveau HTTP par 403 avec WWW-Authenticate: Bearer error="insufficient_scope", scope="mcp:read invoices:read", ce qui permet au client de redemander l'autorisation. Les « Client ID Metadata Documents » (CIMD) ne sont pas pris en charge en v1 : un client qui ne sait pas faire d'enregistrement dynamique doit utiliser un identifiant pré-enregistré.
Outils
Tous en lecture seule (readOnlyHint: true), sauf tauraco_request_export (readOnlyHint: false, destructiveHint: false, idempotentHint: true), à sortie typée, paginés (limit 50 au plus, cursor).
| Outil | Données | Scope en plus de mcp:read |
|---|---|---|
tauraco_get_company_profile | fiche de l'entreprise | company:read |
tauraco_list_customers | clients, sans données personnelles | customers:read |
tauraco_list_suppliers | fournisseurs, sans coordonnées bancaires | suppliers:read |
tauraco_list_invoices | factures clients (status, customer_id, dates) | invoices:read |
tauraco_get_invoice | une facture et ses lignes | invoices:read |
tauraco_list_accounting_entries | écritures comptables résumées | accounting:read |
tauraco_get_cash_position | position de trésorerie, IBAN masqués | treasury:read |
tauraco_list_tenders | avis de marchés publics relayés | tenders:read |
tauraco_get_tender | un avis (chaque lecture compte une vue côté marchés) | tenders:read |
tauraco_list_financing_requests | demandes de financement | financing:read |
tauraco_get_financing_status | étape d'une demande, nombre d'offres reçues et de banques destinataires, sans montant ni taux ; même refus not_found pour une demande absente ou d'une autre entreprise | financing:read |
tauraco_list_collateral | sûretés, avec avertissement juridique | collateral:read |
tauraco_get_collateral_status | une sûreté, avec avertissement juridique | collateral:read |
tauraco_list_exports | exports visibles de l'utilisateur | exports:read |
tauraco_get_export_status | état d'un export | exports:read |
tauraco_request_export | crée un export (csv, xlsx, json) ; non destructif, idempotent sur 10 minutes | exports:write |
Aucun outil ne modifie une facture, ne déplace d'argent, ne prend une décision de financement ni ne fait un geste juridique.
Ressources
tauraco://docs/api, tauraco://docs/mcp, tauraco://schemas/datasets/{code}, tauraco://referentiels/statuts/{domaine}, tauraco://exports/formats, tauraco://guides/{slug} : documentation et schémas seulement, jamais de donnée d'entreprise.
Garanties
- Isolation : l'entreprise vient de l'octroi ; un argument
tenant_idou toute clé hors schéma est refusé. Un outil applique exactement le même contrôle d'accès que la route REST correspondante. - Droits de l'utilisateur : relus à chaque appel ; un rôle retiré ou un octroi révoqué coupe l'accès à l'appel suivant.
- Textes externes : les textes libres (descriptions, libellés saisis, avis relayés) sont préfixés
[donnée externe non vérifiée]et tronqués à 500 caractères, pour qu'un modèle ne les prenne pas pour des instructions. - Débit : même seau et même quota que l'API publique pour l'application ; sans le service de débit,
503. Concurrence plafonnée, corps limité à 4 Mo. - Journal : chaque appel est journalisé (outil, empreinte des arguments, durée, nombre de lignes) ; la demande d'export et les refus entrent dans l'audit.
- Hôtes et origines :
Hostadmisapi.tauraco.io,mcp.tauraco.ioetmcp.tauraco.ai(sinon421) ;Originadmiseshttps://claude.aiethttps://claude.com.
Connecter un client
Ces procédures sont celles des clients. Le serveur est ouvert depuis le 2026-11-05 et répond comme elles l'exigent (401, métadonnées de la ressource protégée, enregistrement dynamique) ; aucune n'a encore été vérifiée de bout en bout contre Tauraco. Utilisez l'URL https://api.tauraco.io/mcp.
Claude.ai (plans individuels : Customize › Connectors › Add custom connector ; Team et Enterprise : un propriétaire passe par Organization settings › Connectors) : saisir l'URL du serveur, choisir l'enregistrement automatique du client OAuth, puis se connecter avec son compte Tauraco et choisir l'entreprise. Le trafic de Claude arrive de 160.79.104.0/21.
Claude Code :
claude mcp add --transport http tauraco https://api.tauraco.io/mcp
claude mcp list # état de la connexion
claude mcp login tauraco # ou /mcp dans une session interactive
MCP Inspector : --protocol-era legacy, auto ou modern permet d'éprouver chaque ère ; sans jeton, la ligne de commande sort avec le code 3 (authentification requise).
Cursor et autres clients : non vérifiés. Leur adresse de retour OAuth doit figurer dans la liste admise, sinon ils doivent utiliser un identifiant pré-enregistré par Tauraco.
Découverte en ligne de commande
#!/usr/bin/env sh
# Découverte MCP : sans jeton, le serveur répond 401 avec l'adresse des métadonnées (RFC 9728).
# MCP discovery: without a token the server answers 401 with the metadata URL (RFC 9728).
set -eu
MCP="https://api.tauraco.io/mcp"
# 1) Ère moderne (2026-07-28) : sans état, en-têtes MCP-Protocol-Version et Mcp-Method.
curl -si -X POST "${MCP}" -H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" -H "Mcp-Method: server/discover" \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' \
| sed -n '1p;/^[Ww][Ww][Ww]-[Aa]uthenticate/p'
# 2) Métadonnées de la ressource protégée, puis du serveur d'autorisation.
curl -sS "https://api.tauraco.io/.well-known/oauth-protected-resource/mcp"
curl -sS "https://api.tauraco.io/.well-known/oauth-authorization-server"
# 3) Ère historique (2025-11-25, celle de Claude.ai) : poignée de main initialize, avec jeton.
if [ -n "${TAURACO_MCP_TOKEN:-}" ]; then
curl -sS -X POST "${MCP}" -H "Authorization: Bearer ${TAURACO_MCP_TOKEN}" \
-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
fi
Erreurs
| Situation | Réponse |
|---|---|
| aucun jeton, jeton invalide ou expiré | 401 + WWW-Authenticate avec resource_metadata |
| octroi révoqué, compte supprimé | 401 (grant_revoked) |
| scope de l'outil manquant | 403 insufficient_scope avec scope= complet |
Host non admis | 421 |
| débit dépassé | 429 avec Retry-After |
| service de débit indisponible | 503 |
| refus métier dans un outil | résultat d'outil isError: true avec un message, sans détail interne |