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