Model Context Protocol (MCP) entwickelt sich schnell zum Standard, wenn KI-Clients kontrolliert auf Tools und Daten zugreifen sollen. MCP server entstehen gerade en masse, zahlreiche MCP registries bieten Suchfunktionen und Beschreibungen für Ihren maßgeschneiderten MCP Server.
Oracle bietet inzwischen vier unterschiedliche MCP-Server-Ansätze für Oracle Database – je nach Betriebsmodell und Einsatzgebiet:
- Oracle Autonomous AI Database MCP Server: integrierte, mandantenfähige Funktion für Autonomous AI Database Serverless.
- Database Tools MCP Server in OCI: ein vollständig gemanagter Cloud-Service, der MCP-Clients sicheren Zugriff auf Oracle AI Database ermöglicht.
- Oracle SQLcl MCP Server: Bestandteil von SQLcl und damit auch im Oracle-Plugin für Visual Studio Code nutzbar; ideal für den lokalen Entwicklerarbeitsplatz.
- ORDS MCP Server: seit ORDS 26.2 als neue Funktion in ORDS Standalone verfügbar. Er stellt einen
/mcp-Endpunkt bereit und verbindet MCP-Clients über OAuth 2.0/JWT kontrolliert mit ausgewählten Datenbank-Pools. Oracle MCP · ORDS 26.2 Dokumentation
In diesem Beitrag konfigurieren wir den ORDS 26.2 MCP Server mit Keycloak als Identity Provider. Prinzipiell ist jedes Identity Management System mit Unterstützung für das OAuth Protokoll denkbar, beispielsweise MS Entra ID, OCI IAM, der meist freie auth0 Dienst uvm. Keycloak gilt als umfassend, ist nicht nur in Cloud Umgebungen verfügbar und spielt gerade in Kubernetes Umgebungen oftmals eine wichtige Rolle als Identity Broker, als Vermittler zwischen lokalen Umgebungen und unternehmensweiten Identity Lösungen.
Das Ziel: Nur angemeldete Benutzer mit der Keycloak-Realm-Rolle saleshistory erhalten Zugriff auf einen dafür vorgesehenen MCP-Datenbank-Pool.
Hinweis: Die unten verwendeten Zugangsdaten sind ausschließlich für eine Demo geeignet. In produktiven Umgebungen gehören Passwörter in einen Secret Store, MFA und restriktive Client-Registration-Regeln sind Pflicht.
Zielarchitektur
Der MCP-Client – beispielsweise MCPJam – ruft den ORDS-Endpunkt /mcp auf. ORDS verweist den Client auf Keycloak, der Benutzer authentifiziert und ein Access Token ausstellt. ORDS prüft anschließend Signatur, Issuer, Audience, den globalen MCP-Scope sowie die Rolle des Benutzers.
Der entscheidende Punkt dabei: ORDS führt die per MCP bereitgestellten Tools über einen direkten Datenbank-Pool aus. Die Pool-Credentials bestimmen also, als welcher Datenbankbenutzer SQL ausgeführt wird; die Keycloak-Rolle entscheidet, ob der Benutzer den Pool überhaupt sehen und nutzen darf. Die Rolle kann innerhalb der Datenbank in deren Session Kontaxt abgefragt werden, so daß noch weitere Sicherheitsbestimmungen festgelegt werden können.
Voraussetzungen
- ORDS 26.2 als Standalone Deployment bzw Docker Container. Der MCP-Endpunkt ist nicht für Tomcat- oder WebLogic-Deployments verfügbar.
- Ein erreichbarer Keycloak-Server, Version 27.0 oder neuer.
- Ein direkter ORDS-Datenbank-Pool für die Sales-History-Daten.
- Ein MCP-fähiger Client, etwa MCPJam.
- Beispieladressen:
- ORDS:
https://ords.example.com - Keycloak:
https://keycloak.example.com - Keycloak Realm:
ordsmcp
- ORDS:
ORDS MCP aktivieren und mit Keycloak verbinden
Zunächst aktivieren wir den neuen MCP-Endpunkt in ORDS:
ords --config /path/to/conf config set --global feature.mcp true
Als Nächstes konfigurieren wir ORDS für die JWT-Prüfung als Teil einer OAuth Anmeldung. Die Werte müssen exakt zu den später in Keycloak erzeugten Token passen.
ords --config /path/to/conf config set --global \
mcp.security.jwt.profile.issuer \
https://keycloak.example.com/realms/ordsmcp
ords --config /path/to/conf config set --global \
mcp.security.jwt.profile.audience \
https://ords.example.com/mcp
ords --config /path/to/conf config set --global \
mcp.security.jwt.profile.jwk.url \
https://keycloak.example.com/realms/ordsmcp/protocol/openid-connect/certs
ords --config /path/to/conf config set --global \
mcp.security.jwt.profile.authorization.server.url \
https://keycloak.example.com/realms/ordsmcp
ords --config /path/to/conf config set --global \
mcp.security.jwt.profile.role.claim.name /roles
Mit mcp.security.jwt.profile.role.claim.name /roles arbeitet ORDS im Role Mode. ORDS erwartet damit im Access Token eine einfache Rollenliste wie:
"roles": [
"saleshistory"
]
Der globale Scope urn:oracle:dbtools:ords:mcpserver:all bleibt zusätzlich obligatorisch: Ohne ihn akzeptiert ORDS keinen Zugriff auf den MCP-Endpunkt.
Datenbank-Pool nur für die Rolle saleshistory freigeben
Legen Sie zunächst einen direkten ORDS-Pool an bzw. verwenden Sie einen bestehenden direkten Pool. Dieser Pool sollte mit einem dedizierten, minimal berechtigten Datenbankkonto arbeiten – beispielsweise einem reinen Reporting-Benutzer für das Sales-History-Schema.
Danach ordnen Sie den Pool der Keycloak-Rolle saleshistory zu:
ords --config /path/to/conf config --db-pool mcp-sh set \
mcp.role saleshistory
ords --config /path/to/conf config --db-pool mcp-sh set \
db.description "Sales History MCP Reporting Database"
Die üblichen weiteren Parameter für den Pool werden hier der Vollständikeit halber mit angegeben:
ords config --db-pool mcp-sh set db.connectionType basic
ords config --db-pool mcp-sh set db.hostname mydatabase-host
ords config --db-pool mcp-sh set db.port 1521
ords config --db-pool mcp-sh set db.servicename freepdb1
ords config --db-pool mcp-sh set db.username SH
ords config --db-pool mcp-sh secret db.password <<EOF
PwdForSH1234#
PwdForSH1234#
EOF
Wichtig: Ein Pool mit den Parametern mcp.role oder mcp.scope ist gänzlich für MCP reserviert und wird nicht mehr für das reguläre ORDS-REST-URL-Mapping eingesetzt. Verwenden Sie daher einen separaten Pool.
Starten Sie ORDS nach den Änderungen neu. Ein erster Test sollte nun eine OAuth-Challenge (“www-authenticate”) im Header liefern:
$ curl -i https://ords.example.com/mcp
HTTP/2 401
date: Fri, 24 Jul 2026 14:37:15 GMT
content-type: text/html;charset=iso-8859-1
content-length: 411
www-authenticate: Bearer error="invalid_request", resource_metadata="https://ords.example.com/.well-known/oauth-protected-resource/mcp", scope="urn:oracle:dbtools:ords:mcpserver:all"
cache-control: must-revalidate,no-cache,no-store
strict-transport-security: max-age=31536000; includeSubDomains
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 401 Unauthorized</title>
</head>
<body><h2>HTTP ERROR 401 Unauthorized</h2>
<table>
<tr><th>URI:</th><td>/mcp</td></tr>
<tr><th>STATUS:</th><td>401</td></tr>
<tr><th>MESSAGE:</th><td>Unauthorized</td></tr>
<tr><th>SERVLET:</th><td>oracle.dbtools.ords.mcp.McpServlet-1800a575</td></tr>
</table>
</body>
</html>
Bei vollständiger Konfiguration antwortet ORDS mit 401 Unauthorized und verweist im WWW-Authenticate-Header auf seine OAuth-Resource-Metadaten. Wichtig hier: ORDS erzeugt eine sogenannte well-known URL und fügt das Protokoll (http oder https) vorne an, abhängig davon ob ORDS im “plain” Modus gestartet ist oder mit den Parametern für Zertifikaten, https port und https hostname.
Realm und Demo-Benutzer in Keycloak anlegen
Melden Sie sich in der Keycloak Admin Console an und legen Sie einen Realm an:
- Öffnen Sie die Realm-Auswahl und wählen Sie Create realm.
- Geben Sie als Namen
ordsmcpein. - Speichern Sie den Realm.

Anschließend erstellen Sie die benötigte Realm-Rolle:
- Wechseln Sie zu Realm roles.
- Wählen Sie Create role.
- Legen Sie die Rolle
saleshistoryan.

Nun erzeugen Sie den Demo-Benutzer:
- Öffnen Sie Users und wählen Sie Add user.
- Setzen Sie Benutzername und E-Mail auf
ordsmcp@demo.com. - Öffnen Sie nach dem Speichern den Reiter Credentials.
- Setzen Sie das Passwort auf
Welcome1234#. - Deaktivieren Sie Temporary, damit Keycloak beim ersten Login keinen Passwortwechsel erzwingt.
- Wechseln Sie zu Role mapping und weisen Sie die Realm-Rolle
saleshistoryzu.


ORDS-MCP-Scope und Token-Mapping konfigurieren
Damit ORDS den Zugriff akzeptiert, muss das Access Token den Scope urn:oracle:dbtools:ords:mcpserver:all sowie die passende Audience und Rollenliste enthalten.
Client Scope anlegen
- Wechseln Sie zu Client scopes.
- Wählen Sie Create client scope.
- Verwenden Sie als Namen:
urn:oracle:dbtools:ords:mcpserver:all
- Setzen Sie den Typ auf Optional.
- Speichern Sie den Client Scope.
Audience Mapper hinzufügen
- Öffnen Sie den neuen Client Scope und wählen Sie den Reiter Mappers.
- Klicken Sie auf Configure a new mapper.
- Wählen Sie Audience.
- Vergeben Sie beispielsweise den Namen
ords-mcp-audience. - Tragen Sie als Custom Audience den ORDS-MCP-Endpunkt ein:
https://ords.example.com/mcp
- Aktivieren Sie Add to access token.
- Speichern Sie.
Die Audience muss exakt mit mcp.security.jwt.profile.audience in der ORDS-Konfiguration übereinstimmen.
Realm-Rollen als flache Liste ausgeben
- Erstellen Sie im selben Client Scope einen weiteren Mapper.
- Wählen Sie User Realm Role.
- Verwenden Sie beispielsweise den Namen
realm-roles-for-ords. - Setzen Sie Token Claim Name auf:
roles
- Setzen Sie Claim JSON Type auf
String. - Aktivieren Sie Multivalued.
- Aktivieren Sie Add to access token.
- Speichern Sie.
Das Ergebnis ist bewusst nicht die übliche, verschachtelte Keycloak-Struktur unter realm_access.roles, sondern eine einfache Liste:
{
"scope": "openid urn:oracle:dbtools:ords:mcpserver:all",
"aud": "https://ords.example.com/mcp",
"roles": [
"saleshistory"
]
}
Genau diese flache Claim-Struktur passt zu der ORDS-Einstellung:
mcp.security.jwt.profile.role.claim.name=/roles
Dynamic Client Registration für den Aufbau vorbereiten
MCP-Clients wie in unserem Fall MCPJam oder auch VSCode können sich dynamisch registrieren. Keycloak schützt diese Funktion standardmäßig absichtlich stark. Für einen abgeschotteten Demo- oder Testaufbau deaktivieren wir daher zwei Client-Registration-Policies.
- Öffnen Sie im Realm
ordsmcpden Bereich Clients. - Öffnen Sie den Reiter Client registration und danach Client Registration Policies.
- Wählen Sie die Policies für anonyme Registrierungen.
- Löschen Sie Trusted Hosts Policy.
- Löschen Sie Full Scope Policy.

Die erste Änderung erlaubt Redirect-URIs beziehungsweise Hosts außerhalb einer vordefinierten Vertrauensliste. Die zweite erlaubt neu registrierten Clients den vollständigen Scope und damit die Realm-Rollen des angemeldeten Benutzers.
Sicherheitswarnung: Diese Konfiguration ist nur für eine kontrollierte Demo geeignet. In Produktion sollten Sie mindestens vertrauenswürdige Hosts explizit einschränken und bevorzugt Initial Access Tokens oder einen dedizierten, minimal berechtigten Service Account für die Client-Registrierung verwenden. Keycloak dokumentiert die Auswirkungen beider Policies ausdrücklich. Keycloak Client Registration
Damit die automatische Registrierung Ihres MCP Tools an keycloak funktioniert, sollte vorzugsweise Keycloak Version 27.0 oder neuer installiert sein. Dann sind mehrere Bugs in dem Umfeld behoben wie falsche CORS header. Auch die “well known” Informationsseite mit Links zum Login, Logout, Token, Refresh, verwendete Algorithmen uvm. steht nun am richtigen, von RFC8414 vorgeschriebenen Platz. Das funktionierte mit früheren Versionen wie 26.4.0 nur teilweise.
Alternative NON dynamic clients:
Selbstverständlich können Sie sich auch ohne dynamische Registrierung Ihrer Anwendungen (Clients) an keykloak anmelden. Der Konfigurationsaufwand steigt dann nur ein wenig. Dazu legen Sie explizit einen neuen Client an mit sprechendem Namen. Tragen Sie dann alle erlaubten Server Namen und Redirect-URLs Ihrer Anwendung(en) ein. Im Tab “Keys” tragen Sie die URL des Keycloak servers ein, welche Java WebKeys zum Download anbietet damit ORDS die Token validieren kann, die nach dem Login versandt werden. Unter dem Tab “Credentials” merken Sie sich noch das Kennwort für Ihren Client für später: das MCP Tool benötigt Namen des Clients und dessen Credential, wenn KEINE dynamische Registrierung erfolgen soll. Und fügen Sie bitte noch unter dem Tab “Client Scopes” den Scope hinzu, der im nachfolgenden Abschnitt angelegt wird.





Login und MCP-Client verbinden
Die eigentliche Anmeldung und die Verbindung mit MCPJam erfolgen anschließend über den OAuth-Flow. Der Client entdeckt den geschützten ORDS-Endpunkt, registriert sich bei keycloak – sofern Dynamic Client Registration erlaubt ist – und leitet zur Anmeldungsseite in keycloak weiter.
In MCPJam definieren Sie zum Test eine neue Connection zum ORDS MCP Server. Ob mit oder ohne dynamic client registration entscheiden Sie an dieser Stelle, indem Sie beim Login per OAuth entweder “Automatic” wählen oder “Preregistration”. Bei “Automatic” versucht MCPJam selbst herauszufinden, wie es sich anmelden kann indem es beim ORDS verschiedene URLS abruft. Bei “Preregistration” sind einige Parameter mehr vonnöten, nämlich der Name des Clients, das Passwort bzw. Secret des Clients (haben Sie das von vorhin noch noch im Clipboard?) und den zu verwendenden Scope urn:oracle:dbtools:ords:mcpserver:all

Melden Sie sich mit folgendem Demo-Benutzer an, den Sie zu Beginn in Keycloak definiert haben:
Benutzer: ordsmcp@demo.com
Passwort: Welcome1234#
Nach erfolgreichem Login erhält der Client ein Access Token mit dem ORDS-MCP-Scope, der korrekten Audience und der Rolle saleshistory. ORDS validiert das Token über den Keycloak-JWKS-Endpunkt und macht ausschließlich den Pool mcp-sh verfügbar. Bei Login Problemen bietet MCPJam einen hervorragenden OAuth und JWT debugger , der alle Login und Registrierungs Schritte visualisiert und einzeln anfahren kann.

In MCPJam sollten Sie nun den neuen MCP server sehen und im Punkt “Tools” auch die vom MCP bereitgestellten Funktionen database_list , schema_information und sql_run.

Der MCP Server läßt sich nun in verschiedene von MCPJam bereitgestellte Chatbots einbinden wie ChatGPT, Claude oder auch einen eigenen, im sogenannten “Playground”.

Viel Spaß beim Testen, wie gut welcher Agent und welches LLM mit diesem MCP Server umgehen kann, ohne zuviel prompten zu müssen und ohne viele Gegenfragen.
Die verwendete Anwendungsrolle “saleshistory” kann natürlich direkt in der Datenbank Session abgefragt werden und beispielsweise bei jeder Abfrage als Filter gesetzt werden. Beispiel Abfrage:
select sys_context( 'CLIENTCONTEXT', 'OAUTH_ISSUER' ) as oauth_issuer,
sys_context( 'CLIENTCONTEXT', 'OAUTH_PRINCIPAL' ) as oauth_principal,
sys_context( 'CLIENTCONTEXT', 'OAUTH_APP_ROLES' ) as oauth_app_roles,
sys_context( 'CLIENTCONTEXT', 'OAUTH_SUB' ) as oauth_sub from dual;
Diese Abfrage in den MCPJam chatbot eingegeben und ausgeführt, gibt uns u.a. die saleshistory Rolle in einer Liste zurück. Diese Metadaten sind zur weiteren Verwendung denkbar, z.B. als Filter für alle Abfragen, als Basis für Virtual Private Database Security Policies und das DBMS_RLS Package – oder sobald von ORDS ebenfalls unterstützt unser neues Datenbank Feature Deep Data Security.

Fazit
ORDS 26.2 bringt MCP direkt in ein etabliertes Oracle-Database-Zugriffsmodell. In Verbindung mit Keycloak entsteht eine nachvollziehbare Sicherheitskette:
- Keycloak authentifiziert den Endbenutzer.
- Das Token (JSON Web Token, JWT) enthält u.a. Scope, Audience und Rollen.
- ORDS validiert das JWT kryptografisch und prüft auch dessen zeitliche Gültigkeit.
- Die Realm-Rolle begrenzt, welche MCP-Datenbank-Pools sichtbar sind.
- Der direkte Datenbank-Pool arbeitet mit dedizierten, minimalen Datenbankrechten.
- Der Datenbank Session Context enthält Anwendungsrollen , die für weitere Security Zwecke verwendbar sind wie z.B. VPD und Deep Data Security.
Damit lässt sich ein MCP-Server nicht nur technisch aktivieren, sondern auch sauber in bestehende OAuth-, SSO- und Rollenmodelle integrieren.
Links
Die für mich hilfreichsten Links bei der Einrichtung des neuen ORDS MCP Servers und Keycloak:
- Jeff Smith “ORDS: now a streaming HTTP MCP Server for Oracle Database“
- wadahiro “Protecting MCP Server with OAuth 2.1“
- Oracle Documentation: “Using ORDS Model Context Protocol“
- MCPJam OAuth debugger und MCP tester: https://app.mcpjam.com/
- Neues Feature “Deep Data Security“, um u.a. MCP und KI Anfragen in der Datenbank abzusichern
- Jeff Smith: VPD und Row Level Security Policies mit dem ORDS MCP Server