Documentation complète · de zéro à un agent IA qui interroge Oracle
Ce site documente le dépôt jpic/ords-mcp-example : Oracle Free, ORDS (le serveur REST d’Oracle) exposé en serveur MCP, Auth0 pour l’identité, et OpenCode comme client IA. La pièce centrale — la moins connue — est la séquence OAuth 2.0 + PKCE. Elle est expliquée ici pas à pas, comme si on n’avait jamais vu OAuth.
Le projet
C’est un « lab » qui reproduit une configuration de bureau réaliste : des données Oracle d’exemple
(RH HR et finance FIN), protégées par des rôles. Un assistant de code
(OpenCode) peut poser des questions en langage naturel (« liste les factures ») et reçoit les résultats —
mais uniquement sur les bases que son compte Auth0 l’autorise à voir, sans jamais manipuler les
mots de passe de la base.
Une base gratuite FREEPDB1 avec deux schémas d’exemple : HR (employés) et FIN (factures), créés au premier démarrage par sql/01_lab_schemas.sql.
Le serveur REST d’Oracle, monté en serveur MCP streamé sur /mcp. Il valide les jetons, filtre les pools, exécute le SQL.
Connexion (Google ou compte local), rôles, permissions API et signature des JWT. C’est le « portier ».
L’agent de code : client MCP qui fait le login OAuth dans le navigateur et appelle ORDS.
Sommaire
Chaque page reprend, en français et enrichie, l’une des docs du dépôt — pour couvrir toute la plage, de la théorie OAuth au runbook de production.
roles2, utilisateurs.
docs/LAB_WALKTHROUGH.md🚀 Démarrage de zéroLe chemin validé phase par phase, de l’environnement au premier « connected (OAuth) » + commandes de vérification.
docs/OPENCODE.md🤖 Côté OpenCodeConfig opencode.json, login, contrôle du jeton, URL d’authorize, fallback bearer.
docs/ARCHITECTURE.md🧱 Architecture & sécuritéSchéma d’ensemble, autorisation en deux étapes, pourquoi roles2, pourquoi l’API Identifier = URL MCP.
docs/TROUBLESHOOTING.md🧯 DépannageCarte erreur → correctif complète : Auth0, OpenCode, ORDS, base, config — des vraies erreurs du lab.
docs/REVERSE_PROXY.md🌐 Reverse proxyExposer ORDS MCP derrière un proxy : URL publique = audience, pièges du préfixe /ords, nginx.
docs/WORK_REPRODUCTION.md🏢 Reproduire au travailLe même modèle de sécurité en Kubernetes + IdP d’entreprise (Entra / Okta) : mapping, déploiement, socle de sécurité.
docs/PRODUCTION.md + PRODUCTION_IMAGE_PLAN.md📦 Image de productionBuild yourlabs/ords épinglé et audité, CI (Trivy, SBOM, cosign), Helm/K8s, plan en phases.
Données d’exemple
FREEPDB1)
Chaque « base logique » est un pool ORDS, relié à un rôle Auth0 (roles2)
et à un utilisateur Oracle en lecture seule.
| Pool ORDS | Rôle Auth0 (roles2) | Utilisateur DB | SQL d’exemple |
|---|---|---|---|
mcp-hr | POOL.HR | HR_MCP_RO | SELECT * FROM employees |
mcp-fin | POOL.FIN | FIN_MCP_RO | SELECT * FROM invoices |
Vue d’ensemble
Utilisateur humain Auth0 (portier, signe les jetons)
┌─────────────┐ ┌───────────────────────────────┐
│ login Google│ │ API Identifier = │
│ / compte DB │ │ http://127.0.0.1:8080/mcp │
└──────┬──────┘ │ rôles POOL.HR / POOL.FIN │
│ │ permission mcpserver:all │
│ ┌───────────────────────────│ Action post-login → roles2 │
│ ▼ └──────────────┬────────────────┘
┌──────────────┐ access token (JWT RS256) │
│ OpenCode │◄────────────────────────────────────┘
│ (client MCP)│ Authorization: Bearer <jwt>
│ port 19876 │──────────────────────────────► ┌──────────────────────┐
└──────────────┘ appels MCP /mcp │ ORDS standalone │
│ :8080/mcp │
│ valide signature & │
│ claims, filtre pools │
└──────┬────────┬───────┘
▼ ▼
pool mcp-hr pool mcp-fin
role POOL.HR role POOL.FIN
user HR_MCP_RO user FIN_MCP_RO
│ │
└───┬────┘
▼
Oracle Free FREEPDB1
(schémas HR + FIN)
| Élément | Où |
|---|---|
| Issuer, audience, JWKS URL, claim des rôles | Config ORDS (volume /etc/ords/config) |
Hôte/identifiants pool, mcp.role, mcp.scope | Config ORDS + wallet |
| Utilisateurs, rôles, permissions API | Auth0 |
Noms de rôles sur le JWT (roles2) | Action Auth0 (post-login) |
| Tables d’exemple | Schémas Oracle HR, FIN |
| Jetons OpenCode | Fichier local ~/.local/share/opencode/mcp-auth.json (jamais dans git) |
iss =
https://<domaine>/ (avec le slash final), aud = l’API Identifier
(http://127.0.0.1:8080/mcp), et le jeton porte la permission
urn:oracle:dbtools:ords:mcpserver:all (dans permissions et/ou scope).
roles2 (JSON pointer /roles2) et la compare au mcp.role
de chaque pool. Ex. : roles2: ["POOL.FIN"] → l’utilisateur ne voit/peut utiliser que
mcp-fin. Pas de rôle pour un pool → 403.
roles2 et pas roles ?
Auth0 réserve le nom de claim roles et n’y mettra jamais une liste personnalisée.
Le lab copie donc les rôles dans roles2 via l’Action post-login, et ORDS pointe dessus avec
MCP_ROLE_CLAIM=/roles2.
resource=http://127.0.0.1:8080/mcp dans sa requête d’authorize. Auth0 fait
correspondre ce resource à un API Identifier — il faut donc qu’une API Auth0 ait
exactement cet Identifier (schéma, hôte, port, chemin). Une autre URL (https://ords.lab/mcp)
ne satisferait pas la requête d’OpenCode.
Aperçu
| Lab | Travail | |
|---|---|---|
| Bases | Un Oracle Free, deux schémas en guise de « bases » | Un pool MCP par vraie base/service |
| IdP | Tenant Auth0 gratuit | Entra / Okta / Auth0 Enterprise (même forme de JWT) |
| URL MCP / audience | http://127.0.0.1:8080 en HTTP | URL publique HTTPS = API Identifier = aud (hôte dédié /mcp, voir reverse proxy) |
| Exécution | Docker Compose | Kubernetes + secrets |
jpic/ords-mcp-example (MIT) : code, SQL, compose, scripts et les docs originales.
ORDS MCP (Oracle) · MCP dans OpenCode · billet de Jeff Smith sur ORDS en serveur MCP.
Lire la page OAuth pas à pas, suivre le setup Auth0 puis le démarrage.