Aller au contenu principal

API MCP Gateway

Référence complète des endpoints MCP du STOA Gateway.

Configure your environment

The examples below use environment variables. Set them for your STOA instance:

export STOA_API_URL="https://api.gostoa.dev"       # Replace with your domain
export STOA_AUTH_URL="https://auth.gostoa.dev" # Keycloak OIDC provider
export STOA_GATEWAY_URL="https://mcp.gostoa.dev" # MCP Gateway endpoint

Self-hosted? Replace gostoa.dev with your domain.

Vue d'Ensemble​

Le STOA Gateway implémente la spécification Model Context Protocol (MCP) version 2025-03-26, avec compatibilité ascendante pour 2024-11-05.

Deux modes d'accès :

ModeTransportCas d'usage
RESTHTTP POSTScripts, intégrations simples, appels ponctuels
Protocole MCPSSE (JSON-RPC)Agents IA, streaming, sessions

Authentification​

Tous les endpoints (sauf la découverte) nécessitent un Bearer token JWT depuis Keycloak :

# Obtenir un token
TOKEN=$(curl -s -X POST "${STOA_AUTH_URL}/realms/stoa/protocol/openid-connect/token" \
-d "client_id=my-app" \
-d "client_secret=${CLIENT_SECRET}" \
-d "grant_type=client_credentials" | jq -r '.access_token')

# Utiliser le token
curl -H "Authorization: Bearer ${TOKEN}" "${STOA_GATEWAY_URL}/mcp/v1/tools"

Endpoints publics (aucune authentification requise) : initialize, ping et la découverte OAuth.


Endpoints REST​

Endpoints HTTP simples pour les opérations sur les outils.

Lister les Outils​

POST /mcp/v1/tools
Authorization: Bearer <token>
Content-Type: application/json

Réponse :

{
"tools": [
{
"name": "get-weather",
"description": "Returns current weather for a given city",
"inputSchema": {
"type": "object",
"properties": {
"q": { "type": "string", "description": "City name" }
},
"required": ["q"]
},
"annotations": {
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
}
]
}

Invoquer un Outil​

POST /mcp/v1/tools/invoke
Authorization: Bearer <token>
Content-Type: application/json

{
"name": "get-weather",
"arguments": { "q": "Paris" }
}

Réponse :

{
"content": [
{
"type": "text",
"text": "{\"location\":{\"name\":\"Paris\"},\"current\":{\"temp_c\":12.0}}"
}
],
"isError": false
}

Endpoints du Protocole MCP (JSON-RPC sur SSE)​

Conformité complète à la spécification MCP via le transport Server-Sent Events.

Initialiser une Session​

Handshake avec négociation de version du protocole :

POST /mcp/sse
Authorization: Bearer <token>
Content-Type: application/json

{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {
"tools": {}
},
"clientInfo": {
"name": "my-agent",
"version": "1.0.0"
}
},
"id": 1
}

Réponse :

{
"jsonrpc": "2.0",
"result": {
"protocolVersion": "2025-03-26",
"capabilities": {
"tools": { "listChanged": true },
"tokenOptimization": {
"supported": true,
"levels": ["none", "moderate", "aggressive"]
},
"elicitation": {}
},
"serverInfo": {
"name": "stoa-gateway",
"version": "0.1.0"
}
},
"id": 1
}

Lister les Outils (JSON-RPC)​

POST /mcp/sse
Content-Type: application/json

{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 2
}

Appeler un Outil (JSON-RPC)​

POST /mcp/sse
Content-Type: application/json

{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-weather",
"arguments": { "q": "London" }
},
"id": 3
}

Requêtes Batch (MCP 2025-03-26)​

Envoyer plusieurs requêtes JSON-RPC en un seul appel :

POST /mcp/sse
Content-Type: application/json

[
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "get-weather", "arguments": { "q": "Paris" } },
"id": 1
},
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "get-weather", "arguments": { "q": "London" } },
"id": 2
}
]

Toutes les requêtes sont traitées de manière concurrente. La réponse est un tableau de résultats JSON-RPC.

Ping​

POST /mcp/sse
Content-Type: application/json

{ "jsonrpc": "2.0", "method": "ping", "id": 99 }

Fermer une Session​

DELETE /mcp/sse?sessionId=<session-id>

Flux SSE (Héritage)​

GET /mcp/sse?sessionId=<session-id>

Ouvre une connexion SSE persistante pour les réponses en streaming.

Méthodes JSON-RPC Supportées​

MéthodeAuth RequiseDescription
initializeNonHandshake + négociation de version
pingNonMaintien de connexion
notifications/initializedNonAccusé de réception client (sans réponse)
tools/listOuiLister les outils disponibles
tools/callOuiExécuter un outil
resources/listOuiLister les ressources (retourne [])

Endpoints de Découverte​

Découverte du Serveur MCP​

GET /mcp

Retourne les métadonnées du serveur : nom, version, version du protocole, endpoints disponibles.

Capacités MCP​

GET /mcp/capabilities

Retourne des informations détaillées sur les capacités, y compris les fonctionnalités supportées.

Santé MCP​

GET /mcp/health

Retourne la santé spécifique MCP : nombre d'outils, sessions actives, statut.


Découverte OAuth 2.1​

STOA implémente la découverte OAuth 2.1 selon la RFC 9728, permettant aux agents IA de s'authentifier automatiquement.

Métadonnées de la Ressource Protégée (RFC 9728)​

GET /.well-known/oauth-protected-resource
{
"resource": "https://mcp.<YOUR_DOMAIN>",
"authorization_servers": ["https://auth.<YOUR_DOMAIN>/realms/stoa"],
"scopes_supported": ["stoa:read", "stoa:write", "stoa:execute"]
}

Métadonnées du Serveur d'Autorisation (RFC 8414)​

GET /.well-known/oauth-authorization-server

Découverte OpenID Connect​

GET /.well-known/openid-configuration

Proxy de Token​

POST /oauth/token

Proxy transparent vers l'endpoint de token Keycloak. Permet aux agents IA d'obtenir des tokens sans connaître l'URL de Keycloak.

Enregistrement Dynamique de Client​

POST /oauth/register

Proxy vers l'endpoint DCR de Keycloak pour l'enregistrement automatique de clients.


Pipeline d'Exécution​

Chaque invocation d'outil passe par ce pipeline :

  1. Auth JWT — Bearer token validé contre les JWKS de Keycloak
  2. Rate Limit — Vérification du quota par consumer (si configuré)
  3. Politique OPA — Contrôle d'accès basé sur les rôles avec scopes
  4. Exécution d'outil — Appel HTTP vers l'endpoint backend
  5. Metering Kafka — Événement émis pour l'analytique (optionnel, géré par feature flag)

Correspondance des Scopes RBAC​

RôleScopes
cpi-adminadmin, read, write, execute, deploy, audit
tenant-adminread, write, execute
devopsread, write, deploy
viewerread

Optimisation des Tokens​

Réduire la consommation de tokens LLM avec l'en-tête X-Token-Optimization :

curl -X POST "${STOA_GATEWAY_URL}/mcp/tools/call" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Token-Optimization: aggressive" \
-H "Content-Type: application/json" \
-d '{"name": "get-weather", "arguments": {"q": "Paris"}}'
NiveauEffet
noneRéponse complète (par défaut)
moderateSuppression des champs redondants
aggressiveRéponse minimale, optimisée pour le contexte LLM

Gestion des Sessions​

Les sessions SSE ont un TTL configurable (par défaut : 30 minutes). Les sessions sont automatiquement nettoyées par une tâche de fond.

Statistiques des Sessions (Admin)​

GET /admin/sessions/stats
Authorization: Bearer <admin-token>
{
"active_sessions": 12,
"zombie_sessions": 0,
"total_created": 1543
}

Réponses d'Erreur​

StatutErreurCause
401UnauthorizedToken JWT manquant ou expiré
403ForbiddenPolitique OPA a refusé l'action
404Tool not foundNom d'outil absent du registre
429Rate limitedQuota consumer dépassé
500Tool execution failedL'endpoint backend a retourné une erreur
502Backend unreachableL'endpoint backend est indisponible

Les erreurs JSON-RPC suivent la spécification MCP :

{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Tool not found: unknown-tool"
},
"id": 3
}

Exemples​

Client Python​

import os
import requests

STOA_AUTH_URL = os.environ['STOA_AUTH_URL']
STOA_GATEWAY_URL = os.environ['STOA_GATEWAY_URL']

# Authentification
auth = requests.post(
f'{STOA_AUTH_URL}/realms/stoa/protocol/openid-connect/token',
data={
'client_id': 'my-app',
'client_secret': os.environ['STOA_CLIENT_SECRET'],
'grant_type': 'client_credentials'
}
)
token = auth.json()['access_token']

# Invoquer un outil
response = requests.post(
f'{STOA_GATEWAY_URL}/mcp/tools/call',
headers={'Authorization': f'Bearer {token}'},
json={'name': 'get-weather', 'arguments': {'q': 'Paris'}}
)

result = response.json()
print(result['content'][0]['text'])

Client JavaScript​

const STOA_GATEWAY_URL = process.env.STOA_GATEWAY_URL;

const response = await fetch(`${STOA_GATEWAY_URL}/mcp/tools/call`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'get-weather',
arguments: { q: 'Paris' }
})
});

const result = await response.json();
console.log(result.content[0].text);

Voir Aussi​