Die AI Platform ist das zentrale AddOn fuer die Integration von KI-Diensten in REDAXO. Es bietet eine einheitliche Schnittstelle zu verschiedenen LLM-Providern und stellt einen MCP-Server bereit, ueber den andere AddOns Tools fuer KI-Agenten anbieten koennen.
- Verwaltung mehrerer AI-Provider und API-Keys ueber Profile
- Pro Profil ein Typ (Text/Code, Bildgenerierung, Bildverstaendnis) mit typspezifischen Einstellungen
- Automatische Modell-Vorauswahl je nach Provider und Typ
- API-Verbindungstest direkt im Backend
- MCP-Server (Model Context Protocol) als HTTP-Endpoint auf
/mcpmit OAuth-2.1-Discovery - OAuth-2.1-Autorisierung mit PKCE + Refresh Tokens + Dynamic Client Registration, YCom als Identity-Provider
- Scope-System mit Mapping
YCom-Gruppe → Scopesueber das Backend - Eingebautes
redaxo_statusMCP-Tool (Systeminfos der REDAXO-Instanz, public) - Extension Points fuer andere AddOns (MCP-Tools, Agent-Tools, eigene Scopes)
- Basiert auf Symfony AI (v0.6)
| Provider | Text | Bildgenerierung | Bildverstaendnis |
|---|---|---|---|
| OpenAI | gpt-4o, gpt-4o-mini, o1, o3-mini |
dall-e-3, gpt-image-1 |
gpt-4o, gpt-4o-mini |
| Anthropic | claude-sonnet-4-20250514, claude-opus-4-20250514, claude-3-7-sonnet-latest |
- | claude-sonnet-4-20250514, claude-opus-4-20250514 |
gemini-2.5-flash, gemini-2.5-pro |
gemini-2.0-flash-exp |
gemini-2.5-flash, gemini-2.5-pro |
|
| Ollama | llama3.2, mistral, deepseek-r1 u.a. |
- | llava, llama3.2-vision |
Bei Ollama wird kein API-Key benoetigt, nur die Basis-URL (Standard: http://localhost:11434).
- AddOn im REDAXO-Installer herunterladen oder in
redaxo/src/addons/ai_platform/ablegen - AddOn in REDAXO installieren und aktivieren
Die Symfony-AI-Abhaengigkeiten sind im Release-Paket bereits enthalten (vendor/ ist Teil des AddOns). Wer das Repo direkt klont, statt das Paket ueber REDAXO.org zu laden, fuehrt einmalig composer install --no-dev im AddOn-Verzeichnis aus.
Unter AI Platform > Profile werden Profile fuer jeden Anwendungsfall separat angelegt. Jedes Profil hat einen Typ und ein Modell mit typspezifischen Einstellungen.
| Feld | Beschreibung |
|---|---|
| Profilname | Eindeutiger Name, z.B. "Claude Text" oder "DALL-E Bilder" |
| Typ | Text/Code, Bildgenerierung oder Bildverstaendnis |
| Provider | OpenAI, Anthropic, Google, Ollama oder Replicate |
| API-Key | API-Schluessel (wird bei Ollama ausgeblendet) |
| Basis-URL | Nur bei Ollama sichtbar (Standard: http://localhost:11434) |
| Modell | Wird automatisch passend zum Provider und Typ vorausgefuellt |
| Einstellung | Beschreibung | Standard |
|---|---|---|
| Temperature | 0 = deterministisch, 1 = normal, 2 = kreativ | 1.0 |
| Max Tokens | Maximale Antwortlaenge | 4096 |
| System-Prompt | Standard-Anweisung, z.B. "Du bist ein hilfreicher Assistent." | leer |
Der System-Prompt wird automatisch bei jedem Aufruf verwendet, kann aber per API ueberschrieben werden.
| Einstellung | Beschreibung | Standard | Nur bei |
|---|---|---|---|
| Bildgroesse | z.B. 1024x1024, 1792x1024 | 1024x1024 | alle |
| Bildqualitaet | Standard oder HD | Standard | OpenAI |
| Bildstil | Vivid oder Natural | Vivid | OpenAI |
Bildqualitaet und Bildstil sind DALL-E-spezifisch und werden bei anderen Providern ausgeblendet.
| Einstellung | Beschreibung | Standard |
|---|---|---|
| Temperature | 0 = deterministisch, 1 = normal, 2 = kreativ | 1.0 |
| Max Tokens | Maximale Antwortlaenge | 4096 |
| Detail-Level | Auto, Low oder High (High kostet mehr Tokens) | Auto |
Hinweis: Das Detail-Level wird im Profil gespeichert, aber aktuell nicht als API-Option an den Provider gesendet. Bei Symfony AI wird das Detail-Level ueber die Image-Message gesteuert.
Unter AI Platform > Einstellungen wird pro Anwendungsfall ein Standard-Profil gewaehlt. Die Dropdowns zeigen nur Profile des passenden Typs. So kann z.B. Anthropic fuer Text und OpenAI fuer Bildgenerierung verwendet werden.
Beim Bearbeiten eines Profils kann ueber den Button "API-Verbindung testen" geprueft werden, ob API-Key und Modell funktionieren. Der Test sendet einen minimalen Request an den Provider.
Alle Profil-Einstellungen (Temperature, Max Tokens, System-Prompt, Bildgroesse etc.) werden automatisch bei jedem API-Aufruf angewendet.
$service = rex_ai_platform_service::getInstance();
// Einfache Textgenerierung - nutzt Standard-Profil mit dessen Temperature,
// Max Tokens und System-Prompt
$text = $service->generateText('Beschreibe REDAXO CMS in 3 Saetzen.');
// System-Prompt ueberschreiben (ueberschreibt den im Profil hinterlegten)
$text = $service->generateText(
'Uebersetze ins Englische: Hallo Welt',
'Du bist ein professioneller Uebersetzer.'
);
// Mit bestimmtem Profil (ID)
$text = $service->generateText('Hallo', null, 2);$service = rex_ai_platform_service::getInstance();
// Nutzt automatisch Detail-Level, Temperature und Max Tokens aus dem Profil
$description = $service->understandImage(
'Beschreibe dieses Bild.',
rex_path::media('foto.jpg')
);
// Alt-Text generieren
$altText = $service->understandImage(
'Erstelle einen kurzen, beschreibenden Alt-Text fuer dieses Bild.',
rex_path::media('header.png')
);$service = rex_ai_platform_service::getInstance();
// Nutzt automatisch Bildgroesse, Qualitaet und Stil aus dem Profil
$imageUrl = $service->generateImage('Ein modernes Logo fuer ein CMS');$service = rex_ai_platform_service::getInstance();
// Alle Einstellungen eines Profils als Options-Array
$options = $service->getProfileOptions($profileId);
// Liefert z.B.: ['temperature' => 0.7, 'max_output_tokens' => 8192] (OpenAI)
// Oder: ['temperature' => 0.7, 'max_tokens' => 8192] (Anthropic, Google, Ollama)
// Profil-Daten lesen
$profile = $service->getDefaultProfile('text');
// $profile['system_prompt'], $profile['temperature'], etc.
// Profile nach Typ filtern
$textProfiles = $service->getProfiles('text');
$imageProfiles = $service->getProfiles('image_generation');use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
$service = rex_ai_platform_service::getInstance();
$profile = $service->getDefaultProfile('text');
$platform = $service->getPlatform($profile['id']);
$options = $service->getProfileOptions($profile['id']);
$messages = new MessageBag(
Message::forSystem($profile['system_prompt'] ?? 'Du bist ein hilfreicher Assistent.'),
Message::ofUser('Was ist REDAXO?'),
);
// Options enthalten Temperature, Max Tokens etc. aus dem Profil
$result = $platform->invoke($profile['model'], $messages, $options);
echo $result->asText();use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
$service = rex_ai_platform_service::getInstance();
// Agent erstellt - sammelt automatisch Tools von anderen AddOns
$agent = $service->createAgent('text');
$messages = new MessageBag(
Message::ofUser('Wie ist das Wetter in Berlin?'),
);
$result = $agent->call($messages);
echo $result->getContent();Das AddOn stellt einen MCP-Server (Model Context Protocol) als HTTP-Endpoint bereit. Damit koennen KI-Tools wie Claude Desktop, Cursor, Windsurf oder andere MCP-Clients direkt auf REDAXO-Funktionen zugreifen.
- AI Platform > MCP Server > Einstellungen oeffnen
- MCP Server aktiv auf "Aktiv" setzen
- Optional: Server-Beschreibung eintragen - diese wird als
instructionsan MCP-Clients gesendet und beschreibt, wofuer der Server gedacht ist und welche Daten die REDAXO-Instanz verwaltet - Speichern
- Den angezeigten Endpoint-URL notieren
Das Untermenue MCP Server ist im Backend in drei Tabs gegliedert:
| Tab | Inhalt |
|---|---|
| Einstellungen | MCP aktivieren, Server-Beschreibung, Discovery-URLs, Liste der registrierten Tools mit Auth-Status |
| OAuth-Clients | Liste aller (manuell oder via DCR) registrierten OAuth-Clients, Anlegen + Loeschen |
| Scope-Mapping | Welche Scopes bekommen Nutzer aufgrund ihrer YCom-Gruppenmitgliedschaft |
| Pfad | Zweck |
|---|---|
POST /mcp |
MCP JSON-RPC Endpoint |
GET /.well-known/oauth-protected-resource |
Discovery: zeigt MCP-Clients auf den Authorization-Server |
GET /.well-known/oauth-authorization-server |
Discovery: OAuth-2.1-Endpunkt-Metadaten |
GET /oauth/{authorize,token,register} |
OAuth-Flow (Phase 2, aktuell 501 Not Implemented) |
POST /index.php?rex-api-call=ai_mcp |
Deprecated-Legacy-Endpoint, bleibt aus Kompatibilitaetsgruenden erreichbar |
Bei einer lokalen Entwicklungsumgebung z.B.:
https://redaxo.localhost/mcp
Auth-Modi:
- Public Tools (
public: true) — ohne Authentifizierung aufrufbar. Das eingebauteredaxo_statusTool ist als public markiert, damit Monitoring-Tools und Discovery ohne Account funktionieren. - Geschuetzte Tools — erfordern einen gueltigen OAuth-2.1-Access-Token mit den deklarierten Scopes.
Der OAuth-2.1-Stack laeuft komplett ueber Standard-Pfade:
| Pfad | Methode | Zweck |
|---|---|---|
/.well-known/oauth-protected-resource |
GET | RFC-9728-Discovery (zeigt MCP-Clients auf den Authorization-Server) |
/.well-known/oauth-authorization-server |
GET | RFC-8414-Metadata (issuer, endpoints, supported methods) |
/oauth/authorize |
GET/POST | User-Login (gegen YCom) + Consent-Screen, gibt einen Code mit PKCE-Challenge aus |
/oauth/token |
POST | authorization_code-Exchange + refresh_token-Rotation |
/oauth/register |
POST | Dynamic Client Registration (RFC 7591, auto-approve fuer public clients) |
Beim Aufruf eines geschuetzten Tools ohne / mit ungueltigem Token antwortet /mcp mit HTTP 401 und einem RFC-6750-konformen Header:
WWW-Authenticate: Bearer realm="MCP", resource="https://example.org/.well-known/oauth-protected-resource", error="invalid_token", ...
mcp-remote und andere MCP-Clients folgen automatisch der Discovery-URL und starten den OAuth-Flow. Im Browser-Fenster meldet sich der Nutzer mit YCom-Credentials an und sieht einen Consent-Screen mit den effektiven Scopes (Schnittmenge aus angefragten Scopes und Gruppen-Mapping). Nach Zustimmung wird mcp-remote automatisch zurueckgeleitet, tauscht den Code mit PKCE-Verifier gegen ein Access+Refresh-Token-Paar ein und legt es lokal ab.
Breaking Change ab 1.0.0-beta2: Der frueher in
rex_confighinterlegte feste Bearer-Token wurde entfernt. Bestehende Claude-Desktop- / Cursor-Setups, die diesen Token nutzen, muessen die--header-Zeile aus ihrer Config streichen —mcp-remoteuebernimmt die OAuth-Negotiation jetzt selbststaendig.
Empfohlener Ablauf, wenn der MCP-Server in Produktion gehen soll:
- Gruppe(n) in YCom anlegen. Die normale YCom-Gruppen-Verwaltung. Beispielsweise eine Gruppe
mcp-usersfuer Standard-Zugriff. - Scopes pro Gruppe vergeben unter AI Platform > MCP Server > Scope-Mapping. Pro YCom-Gruppe Checkboxen fuer alle bekannten Scopes (eingebaut:
mcp:tools:read,mcp:tools:call; weitere koennen Drittaddons ueber den Extension PointAI_PLATFORM_OAUTH_SCOPESregistrieren). - YCom-Nutzer in die Gruppe(n) eintragen ueber die YCom-User-Verwaltung.
- OAuth-Client anlegen unter AI Platform > MCP Server > OAuth-Clients, falls eine feste Client-Definition gewuenscht ist. Alternativ koennen MCP-Clients sich via DCR (
POST /oauth/register) selbst registrieren —mcp-remotemacht das automatisch beim ersten Verbindungsaufbau.- public client (PKCE only): geeignet fuer mcp-remote, Cursor, Claude Desktop. Kein Secret.
- confidential client (client_secret): geeignet fuer Server-zu-Server-Setups. Das Secret wird nur einmal nach dem Anlegen angezeigt.
- Test mit curl (oder direkt mit
mcp-remote):# Discovery curl -s https://example.org/.well-known/oauth-protected-resource # Public Tool ohne Auth curl -s -X POST https://example.org/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"redaxo_status","arguments":{}}}'
Geschuetzte Tools koennen erst genutzt werden, sobald ein User per OAuth eingeloggt hat. Im Browser geht das ueber den Login-Screen unter /oauth/authorize, automatisierte Tests muessen den Flow durchspielen (siehe .claude/tests/oauth-authorize-test.sh im Repo als Referenz).
Das AddOn registriert automatisch das Tool redaxo_status (public), das folgende Informationen ueber die REDAXO-Instanz liefert:
- REDAXO-Version, PHP-Version, Datenbank-Version
- Server-URL und Server-Name
- Sprachen (alle CMS-Sprachen)
- Anzahl Artikel, Kategorien, Medien, Benutzer
- Debug- und Safe-Mode Status
- Liste aller installierten AddOns mit Versionen und Plugins
In der Claude Desktop Konfigurationsdatei (claude_desktop_config.json):
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Claude Desktop unterstuetzt HTTP-basierte MCP-Server ueber mcp-remote als Proxy. Installiere zuerst mcp-remote:
npm install -g mcp-remoteDann in der claude_desktop_config.json:
{
"mcpServers": {
"redaxo": {
"command": "npx",
"args": [
"mcp-remote",
"https://deine-domain.de/mcp"
]
}
}
}Sobald der OAuth-Flow aktiv ist, oeffnet mcp-remote beim ersten Verbindungsaufbau automatisch einen Browser-Tab fuer die YCom-Anmeldung.
Lokaler Server (z.B. https://redaxo.localhost)
Bei einem lokalen Server mit selbstsigniertem SSL-Zertifikat muss die Zertifikatspruefung deaktiviert werden:
{
"mcpServers": {
"redaxo": {
"command": "npx",
"args": [
"mcp-remote",
"https://redaxo.localhost/mcp"
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}{
"mcpServers": {
"redaxo": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8080/mcp"
]
}
}
}In der Cursor-Konfiguration (.cursor/mcp.json im Projektverzeichnis):
{
"mcpServers": {
"redaxo": {
"command": "npx",
"args": [
"mcp-remote",
"https://deine-domain.de/mcp"
]
}
}
}claude mcp add redaxo -- npx mcp-remote "https://deine-domain.de/mcp"Fuer lokale Server mit selbstsigniertem Zertifikat:
NODE_TLS_REJECT_UNAUTHORIZED=0 claude mcp add redaxo -- npx mcp-remote "https://redaxo.localhost/mcp"Der Server implementiert das MCP-Protokoll (JSON-RPC 2.0) mit folgenden Methoden:
| Methode | Beschreibung |
|---|---|
initialize |
Handshake, gibt Server-Info und Capabilities zurueck |
tools/list |
Listet alle verfuegbaren Tools |
tools/call |
Fuehrt ein Tool aus |
ping |
Health-Check |
curl -X POST "https://deine-domain.de/mcp" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'Anonyme Aufrufer sehen ueber tools/list nur Tools, die als public: true markiert sind. Geschuetzte Tools antworten beim Aufruf mit 401 plus WWW-Authenticate-Header, der den Client auf die OAuth-Discovery zeigt — Standard-Clients wie mcp-remote starten daraufhin automatisch den Login-Flow.
Andere AddOns koennen Tools ueber den Extension Point AI_PLATFORM_MCP_TOOLS bereitstellen. Diese Tools werden sowohl im MCP-Server als auch im Agent-System verfuegbar.
// In boot.php oder lib/ des eigenen AddOns:
rex_extension::register('AI_PLATFORM_MCP_TOOLS', function (rex_extension_point $ep) {
$tools = $ep->getSubject();
$tools['redaxo_article_search'] = new rex_ai_mcp_tool(
name: 'redaxo_article_search',
description: 'Sucht nach REDAXO-Artikeln anhand eines Suchbegriffs.',
inputSchema: [
'type' => 'object',
'properties' => [
'query' => [
'type' => 'string',
'description' => 'Der Suchbegriff',
],
'limit' => [
'type' => 'integer',
'description' => 'Maximale Anzahl der Ergebnisse (Standard: 10)',
],
],
'required' => ['query'],
],
handler: function (array $arguments, rex_ai_mcp_context $context): string {
// $context->getYcomUser() / $context->hasScope('...') verfuegbar,
// sobald Phase 2 die Auth aktiviert. Im Phase-1-Modus ist der
// Context anonymous und reicht durch.
$query = $arguments['query'];
$limit = $arguments['limit'] ?? 10;
$sql = rex_sql::factory();
$sql->setQuery(
'SELECT id, name FROM ' . rex::getTable('article')
. ' WHERE name LIKE ? LIMIT ?',
['%' . $query . '%', $limit]
);
$results = [];
foreach ($sql as $row) {
$results[] = [
'id' => $row->getValue('id'),
'name' => $row->getValue('name'),
];
}
return json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
},
public: false,
requiredScopes: ['mcp:tools:call'],
);
return $tools;
});| Parameter | Pflicht | Beschreibung |
|---|---|---|
name |
ja | Eindeutiger Tool-Name |
description |
ja | Beschreibung, wird MCP-Clients als Tool-Hint angezeigt |
inputSchema |
ja | JSON-Schema fuer die Argumente |
handler |
ja | function (array $arguments, rex_ai_mcp_context $context): mixed |
public |
nein | true macht das Tool ohne Authentifizierung aufrufbar (Default: false) |
requiredScopes |
nein | Liste der Scopes, die der Caller besitzen muss (greift erst mit OAuth in Phase 2) |
Im Handler kann ueber $context der angemeldete YCom-User abgefragt werden — siehe lib/rex_ai_mcp_context.php fuer die volle API.
rex_extension::register('AI_PLATFORM_MCP_TOOLS', function (rex_extension_point $ep) {
$tools = $ep->getSubject();
$tools['redaxo_media_info'] = new rex_ai_mcp_tool(
name: 'redaxo_media_info',
description: 'Gibt Informationen zu einer Mediendatei zurueck.',
inputSchema: [
'type' => 'object',
'properties' => [
'filename' => [
'type' => 'string',
'description' => 'Der Dateiname der Mediendatei',
],
],
'required' => ['filename'],
],
handler: function (array $arguments, rex_ai_mcp_context $context): string {
$media = rex_media::get($arguments['filename']);
if (!$media) {
return 'Mediendatei nicht gefunden: ' . $arguments['filename'];
}
return json_encode([
'filename' => $media->getFileName(),
'title' => $media->getTitle(),
'type' => $media->getType(),
'size' => $media->getFormattedSize(),
'width' => $media->getWidth(),
'height' => $media->getHeight(),
'url' => $media->getUrl(),
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
},
public: true,
);
return $tools;
});| Extension Point | Beschreibung | Subject |
|---|---|---|
AI_PLATFORM_MCP_TOOLS |
Tools fuer den MCP-Server registrieren | array<string, rex_ai_mcp_tool> |
AI_PLATFORM_AGENT_TOOLS |
Tools fuer den Agent registrieren | array<object> (Symfony AI Tool-Objekte) |
AI_PLATFORM_OAUTH_SCOPES |
Eigene Scopes fuer das Scope-Mapping ankuendigen | array<string, string> (scope → description) |
rex_extension::register('AI_PLATFORM_OAUTH_SCOPES', function (rex_extension_point $ep) {
$scopes = $ep->getSubject();
$scopes['redaxo:articles:read'] = 'Read REDAXO articles via MCP tools';
$scopes['redaxo:articles:write'] = 'Create/update REDAXO articles via MCP tools';
return $scopes;
});Die so registrierten Scopes erscheinen automatisch im Backend unter MCP Server > Scope-Mapping als auswaehlbare Checkboxen.
- REDAXO >= 5.18
- PHP >= 8.2
- Composer (fuer die Installation der Symfony AI Bibliotheken)
MIT License