KI-Features
Jede KI-Aktion in cmssy ist eine berechtigungsgeprüfte Tool-Definition, geteilt von MCP-Server und In-App-Assistent.
cmssy hat zwei Wege, eine KI auf deine Inhalte wirken zu lassen: den MCP-Server, mit dem sich externe Clients wie Claude verbinden, und den Assistenten im cmssy-Dashboard.
Das sind keine zwei Implementierungen. Beide sind Transporte über demselben Tool-Kern - eine einmal ergänzte Fähigkeit erscheint also in beiden, mit gleichem Verhalten und gleichen Berechtigungsprüfungen.
Was ein Tool ist
Ein Tool ist ein einfaches Objekt. Hier ein echtes, vollständig:
import { z } from "zod";
import type { AiTool, PageSummary } from "../types.js";
const inputSchema = z.object({
search: z
.string()
.optional()
.describe("Optional text to filter pages by name or slug"),
});
export const listPagesTool: AiTool<Input, Output> = {
name: "list_pages",
description:
"List the workspace's pages (id, name, slug, published), optionally filtered by a search string.",
inputSchema,
requiredPermissions: ["pages:view"],
execute: async ({ search }, ops) => {
const items = await ops.pages.list(search);
return { count: items.length, items };
},
};Fünf Felder, jedes verdient seinen Platz:
name- was das Modell aufruft.description- was das Modell liest, um zu entscheiden, ob es aufruft. Das ist Prompt-Fläche, kein Codekommentar; eine vage Beschreibung ergibt ein Tool, das niemand korrekt nutzt.inputSchema- ein zod-Schema. Es validiert den Aufruf und dient zugleich als JSON Schema für den Client, beide können also nie auseinanderlaufen.requiredPermissions- geprüft, bevorexecuteläuft.execute- die eigentliche Arbeit, mit validiertem Input und einemops-Objekt.
Warum ops injiziert wird
execute importiert nie einen Client, öffnet nie eine Verbindung und liest nie eine Umgebungsvariable. Es bekommt ops und ruft darauf Methoden auf.
Diese eine Entscheidung macht den Kern transportneutral. Der MCP-Server liefert ein ops auf Basis eines API-Tokens; der In-App-Assistent eines auf Basis der Sitzung der angemeldeten Person. Das Tool merkt den Unterschied nicht - und keines von beiden bekommt versehentlich Fähigkeiten, die dem anderen fehlen.
Berechtigungen greifen hier, nicht am Rand
requiredPermissions steht am Tool, die Prüfung passiert also an einer Stelle, egal wer aufruft.
Das zählt, weil sich die beiden Transporte unterschiedlich authentifizieren. Ein MCP-Client legt ein Token mit Scopes vor; der Assistent handelt als angemeldetes Mitglied mit einer Rolle. Trüge jeder Transport eigene Berechtigungslogik, würden sie auseinanderlaufen - und dieses Auseinanderlaufen wäre eine Rechteausweitung, kein Rendering-Bug.
Die praktische Folge: ein KI-Client kann nie mehr als die Credential dahinter. Gib Claude ein Nur-Lese-Token, und es listet und liest; es verweigert das Veröffentlichen, weil das Tool verweigert - nicht weil man das Modell höflich gebeten hat.
Was die Tools abdecken
Die Registry ist breit - Seiten und Blöcke, Modelle und Records, Medien und Ordner, Formulare und Einsendungen, Mitglieder und Rollen, Webhooks sowie die gesamte Commerce-Fläche aus Produkten, Warenkörben, Bestellungen, Rabatten und Bestell-Pipelines.
Die Form ist konsistent: list_* und get_* zum Lesen, create_* / update_* / delete_* zum Schreiben, dazu Verben für Zustandsübergänge wie publish_page, unpublish_page, revert_to_published und promote_dev_draft.
Nichts davon berührt deinen Code. Es gibt kein Tool, das eine Datei schreibt, eine Komponente ändert oder einen Pull Request öffnet - KI bearbeitet Inhalte, Block-Schemas bleiben im Repo unter Review.
Dev-Entwürfe
Für ein spezifisches Problem - einen noch nicht deployten Blocktyp ausprobieren - gibt es einen Parameter und ein Tool.
Schreib-Tools akzeptieren ein target von "devDraft", das dein persönliches Overlay statt des geteilten Seitenentwurfs bearbeitet. Bei niemand anderem ändert sich die Vorschau. Sobald der Block ausgeliefert ist, verschiebt promote_dev_draft dein Overlay auf den geteilten Entwurf.
Ohne das hieße Experimentieren mit einem undeployten Block, Inhalte auf einen geteilten Entwurf zu legen, die für jede Kollegin als nichts rendern.
Nächste Schritte
- MCP-Server - einen externen KI-Client anbinden.
- API-Tokens - die Scopes hinter
requiredPermissions. - Mitglieder und Rollen - was der In-App-Assistent erbt.