Exemples
Brancher un hôte, écrire un agent, lancer le serveur en local, tout en gardant l'identité de l'utilisateur.
Tous les exemples vivent dans le dossier examples/ du dépôt. Ils ont tous la même règle : le modèle ne voit jamais le jeton ; le serveur le reçoit, Trino décide.
1. Un hôte à distance (Cursor, Claude Desktop, VS Code, Le Chat)
Le serveur tourne quelque part sur votre réseau, derrière HTTPS, avec MCP_TRANSPORT=streamable-http (le défaut). L’hôte envoie le jeton de l’utilisateur dans l’en-tête Authorization, et la clé du produit dans X-Agent-Key si vous en avez enregistré.
{
"mcpServers": {
"trino": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer <le jeton d'accès de l'utilisateur>",
"X-Agent-Key": "<la clé enregistrée pour ce produit, s'il y en a une>"
}
}
}
}
Avec MCP_RESOURCE_URL défini côté serveur, un hôte qui sait faire OAuth trouve le fournisseur d’identité tout seul (RFC 9728) et vous n’avez plus de jeton à coller.
2. Un hôte local en stdio (Claude Desktop, Cursor, Mistral Vibe)
L’hôte lance le serveur lui-même sur votre poste. Le jeton vient de l’environnement ; en mode strict, sans jeton valide, le serveur refuse de démarrer.
{
"mcpServers": {
"trino": {
"command": "uvx",
"args": ["akko-mcp-trino"],
"env": {
"MCP_TRANSPORT": "stdio",
"TRINO_HOST": "trino.example.internal",
"TRINO_PORT": "8080",
"MCP_AUTH_ENABLED": "true",
"MCP_AUTH_REQUIRED": "true",
"MCP_JWKS_URL": "https://idp.example.com/realms/data/protocol/openid-connect/certs",
"MCP_OIDC_ISSUER": "https://idp.example.com/realms/data",
"MCP_OIDC_AUDIENCE": "data-platform",
"MCP_USER_TOKEN": "<le jeton d'accès de l'utilisateur>"
}
}
}
}
uvx exécute le paquet publié sans rien installer ; pipx run akko-mcp-trino fait la même chose (vérifié avec la 0.2.0 publiée sur PyPI). Sur un poste sans uv, remplacez la commande par akko-mcp-trino après un pip install akko-mcp-trino.
3. Un agent complet sur un modèle compatible OpenAI (Mistral, ou autre)
examples/agent.py tient en quatre-vingts lignes : il liste les outils du serveur, les expose au modèle au format des appels de fonctions, exécute chaque appel par MCP et rend la réponse. Il marche tel quel avec Mistral sur La Plateforme, via OpenRouter ou LiteLLM, et avec tout fournisseur qui parle l’API de complétion de conversation avec outils.
pip install akko-mcp-trino openai
export LLM_BASE_URL=https://api.mistral.ai/v1
export LLM_API_KEY=...
export LLM_MODEL=mistral-small-latest
export MCP_URL=http://localhost:3000/mcp
export USER_TOKEN=<le jeton d'accès de l'utilisateur>
export AGENT_KEY=<clé X-Agent-Key, optionnelle>
python examples/agent.py "Donne-moi trois emails de clients avec leur pays"
Le prompt système de l’agent dit deux choses au modèle, et elles comptent : explorer le catalogue avant d’écrire du SQL, et prendre une valeur masquée pour ce qu’elle est, la politique d’accès, sans relancer la requête. Sans la seconde, un modèle qui reçoit ***@gmail.com peut croire à une erreur et boucler ; nous l’avons vu.
Lancé deux fois avec les jetons de deux personnes, l’agent rend deux réponses différentes sur la même question. C’est la démonstration à faire à qui demande ce que « gouverné » veut dire.
4. Depuis Python, avec le SDK officiel
import anyio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main(token: str):
headers = {"Authorization": f"Bearer {token}", "X-Agent-Key": "my-agent-key"}
async with streamablehttp_client("http://localhost:3000/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
found = await session.call_tool("search_columns", {"pattern": "%email%"})
print([t.name for t in tools.tools], found.content[0].text)
anyio.run(main, "<jeton>")
5. Vérifier depuis un terminal
# le serveur est vivant, joint Trino, expose ses métriques
curl -s localhost:3001/health ; curl -s localhost:3001/ready ; curl -s localhost:3001/metrics | head
# un hôte sans jeton apprend où se connecter
curl -si https://mcp.example.com/mcp | grep -i -e www-authenticate -e x-reason
curl -s https://mcp.example.com/.well-known/oauth-protected-resource
Ce qui est prouvé, et comment le rejouer
Les scripts de preuve tournent contre un cluster réel et sont rejouables ; ils vivent dans le dépôt de la plateforme AKKO parce qu’ils connaissent son cluster, mais leur logique est lisible par n’importe qui : un pod éphémère avec le serveur, deux comptes, les mêmes outils, deux réponses. Le tableau de la page akko-mcp-trino résume ce qu’ils vérifient.