Routes MCP (Streamable HTTP)
Le transport MCP de la plateforme suit le protocole Streamable HTTP, révision
2025-03-26 (constante MCP_PROTOCOL_VERSION dans forge-mcp). Les échanges
sont du JSON-RPC 2.0. La route est déclarée dans
crates/forge-api/src/router.rs et ses gardes d'authentification dans
crates/forge-api/src/routes/mcp.rs.
Désactivation. Le groupe
/api/v1se coupe avecAPI_ENABLED=false, et le transport MCP avecMCP_ENABLED=false(ouAPI_ENABLED=false). Une surface coupée répond un404JSON, jamais un403.
Transport principal
| Méthode | Route | Rôle |
|---|---|---|
POST | /api/v1/mcp | Requête JSON-RPC (un objet par requête) |
GET | /api/v1/mcp | Flux SSE d'une session |
DELETE | /api/v1/mcp | Fermer une session (204) |
Les trois exigent un jeton (Authorization: Bearer <token> ou cookie jwt). <hote-api> est défini dans Swagger.
Une session est liée à l'utilisateur qui l'a ouverte : l'identité passée dans
les paramètres d'initialize est écrasée par celle du jeton, et une session
qui n'appartient pas à l'appelant répond 404 avec le code JSON-RPC -32600
(« session inconnue »).
Figure 4 : une session MCP, de initialize à DELETE.
POST /api/v1/mcp
En-têtes : Content-Type: application/json, et Mcp-Session-Id: <session-id>
pour toutes les méthodes sauf initialize et ping.
Un seul objet JSON-RPC par requête. Le corps est désérialisé en une requête unique : un tableau (batch JSON-RPC) n'est pas accepté. Pour enchaîner plusieurs appels, envoyez plusieurs requêtes.
Méthodes JSON-RPC traitées (liste du match de mcp_post_handler) :
| Méthode | Rôle |
|---|---|
initialize | Ouvre une session, renvoie les capacités et l'en-tête Mcp-Session-Id |
ping | Test de vie |
tools/list | Outils disponibles (connecteurs autorisés pour la plateforme) |
tools/call | Exécute un outil |
resources/list, resources/read | Ressources MCP |
prompts/list, prompts/get | Modèles de prompts |
completion/complete | Complétion d'arguments |
logging/setLevel | Niveau de journalisation |
Toute autre méthode répond -32601 (« method not found »). Un corps qui n'est
pas une requête JSON-RPC valide répond 400 avec -32700.
initialize
curl -i -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"mon-client","version":"1.0.0"}}}'
La réponse contient protocolVersion, les capabilities (tools,
resources, prompts, completion, logging) et serverInfo
(name: "chatbotaurus-forge"). L'identifiant de session est dans l'en-tête
de réponse mcp-session-id. Copiez-le dans une variable (export SESSION=<session-id>) : les appels suivants le renvoient dans l'en-tête Mcp-Session-Id.
tools/list
curl -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Mcp-Session-Id: <session-id>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
La réponse porte result.tools, une liste d'objets name, description, inputSchema et connector_id. Les noms d'outils ont la forme {id-du-connecteur}.{outil}. Prenez les noms
exacts dans la réponse de tools/list, jamais dans un exemple de document.
tools/call
curl -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Mcp-Session-Id: <session-id>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"data-europa.search_datasets","arguments":{"q":"energie","limit":5}}}'
Réponse : statut HTTP 200 et un objet JSON-RPC. En cas de succès, result.type vaut success et result.content est une liste de blocs (type, text). Avant l'exécution, un échec est un objet error à la place de result, et error.code reprend le code HTTP de l'échec tout en gardant le statut HTTP 200 : 401 session expirée, 403 serveur absent de la liste autorisée, 404 outil inconnu. Si le connecteur lui-même échoue, result.type vaut error et result porte code et message, toujours avec le statut HTTP 200.
Sans Mcp-Session-Id, la réponse est 400 (-32600, « missing
Mcp-Session-Id »). Une session expirée ou inconnue répond 401 : en statut HTTP pour tools/list, dans error.code pour tools/call.
GET /api/v1/mcp
Ouvre un flux text/event-stream pour la session désignée par
Mcp-Session-Id. Le flux envoie un événement open ({"sessionId": ...})
puis un commentaire de maintien de connexion toutes les 30 secondes.
Capacité en sommeil. Les capacités annoncent
tools.listChanged, mais aucune notification n'est poussée aujourd'hui sur ce flux : seuls l'événementopenet les signaux de maintien sont émis (commentaire du code dansmcp_get_handler). Ne bâtissez pas de logique client sur des notifications serveur.
DELETE /api/v1/mcp
Ferme la session de Mcp-Session-Id, libère ses ressources et inscrit la
fermeture au journal d'audit. Réponse 204 No Content.
Sessions
- Chaque session est un UUID, stocké dans Valkey.
- Durée de vie par défaut : 30 minutes (
DEFAULT_SESSION_TTLdansforge-mcp/src/session.rs). Chaquetools/callrafraîchit ce délai. - La session est vérifiée à chaque requête ; si le magasin de sessions est
indisponible, la réponse est
503(-32603).
Catalogue des connecteurs
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/mcp/catalogue | Connecteurs du registre |
GET | /api/v1/mcp/catalogue/{id} | Un connecteur |
GET | /api/v1/mcp/catalog | Alias de /mcp/catalogue |
GET | /api/v1/mcp/connectors | Alias de /mcp/catalogue |
Ces routes exigent un jeton. GET /api/v1/mcp/catalogue renvoie
{"catalogue": [{"id", "display_name", "compliance": {...}}], "total": N}.
curl "https://<hote-api>/api/v1/mcp/catalogue" -H "Authorization: Bearer <token>"
La fiche descriptive des serveurs business (catégorie, fournisseur, pays,
certifications) est servie par /api/v1/mcp/catalog-business, décrit dans le
chapitre « Routes du catalogue métier ».
Documentation de l'API
Il n'existe pas de serveur de documentation séparé. Le contrat OpenAPI est
servi par forge-api lui-même (voir le chapitre « Swagger »).
Voir aussi
- API-as-a-Service EU souverain : appeler un connecteur par session ou par appel direct
- Créer votre premier connecteur MCP : ajouter un connecteur, puis le tester par ce transport
- Connecter Odoo à la passerelle MCP : une session et un premier appel d'outil, pas à pas
- Diagnostics et signalement : ouvrir une session et consulter le catalogue en dépannage
- Gestion des erreurs : codes JSON-RPC du transport et enveloppe d'erreur de l'API
- Conception des connecteurs MCP : cycle de vie des connecteurs derrière tools/list et tools/call