Funkcje AI
Każda akcja AI w cmssy to jedna definicja narzędzia z kontrolą uprawnień, dzielona przez serwer MCP i asystenta w panelu.
cmssy ma dwie drogi, którymi AI może działać na Twojej treści: serwer MCP, do którego podłączają się zewnętrzni klienci tacy jak Claude, oraz asystent w panelu cmssy.
To nie są dwie implementacje. Oba to transporty nad tym samym rdzeniem narzędzi - więc możliwość dodana raz pojawia się w obu, z tym samym zachowaniem i tymi samymi sprawdzeniami uprawnień.
Czym jest narzędzie
Narzędzie to zwykły obiekt. Oto prawdziwe, w całości:
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 };
},
};Pięć pól i każde zarabia na swoje miejsce:
name- to, co wywołuje model.description- to, co model czyta, żeby zdecydować, czy wywołać. To powierzchnia promptu, nie komentarz w kodzie; mętny opis daje narzędzie, którego nikt nie używa poprawnie.inputSchema- schemat zod. Waliduje wywołanie i jednocześnie służy jako JSON Schema widziany przez klienta, więc oba nie mogą się rozjechać.requiredPermissions- sprawdzane, zanim odpaliexecute.execute- właściwa robota, biorąca zwalidowany input i obiektops.
Dlaczego ops jest wstrzykiwane
execute nigdy nie importuje klienta, nie otwiera połączenia ani nie czyta zmiennej środowiskowej. Dostaje ops i woła na nim metody.
Ta jedna decyzja czyni rdzeń transport-neutralnym. Serwer MCP dostarcza ops oparte na tokenie API; asystent w panelu dostarcza takie oparte na sesji zalogowanego użytkownika. Narzędzie nie widzi różnicy - i żadne z nich nie dostanie przypadkiem możliwości, których nie ma drugie.
Uprawnienia są egzekwowane tutaj, nie na brzegu
requiredPermissions siedzi na narzędziu, więc sprawdzenie dzieje się w jednym miejscu niezależnie od tego, kto woła.
To ważne, bo oba transporty uwierzytelniają się inaczej. Klient MCP przedstawia token ze scope'ami; asystent działa jako zalogowany członek z rolą. Gdyby każdy transport niosł własną logikę uprawnień, rozjechałyby się - a to rozjeżdżenie byłoby eskalacją uprawnień, nie błędem renderowania.
Praktyczna konsekwencja: klient AI nigdy nie zrobi więcej niż poświadczenie, które za nim stoi. Wskaż Claude'owi token tylko do odczytu, a będzie listował i czytał; odmówi publikacji, bo odmawia narzędzie, a nie dlatego, że model ładnie poproszono.
Co pokrywają narzędzia
Rejestr jest szeroki - strony i bloki, modele i rekordy, media i foldery, formularze i zgłoszenia, członkowie i role, webhooki oraz pełna powierzchnia commerce: produkty, koszyki, zamówienia, rabaty i pipeline'y zamówień.
Kształt jest spójny: list_* i get_* do odczytu, create_* / update_* / delete_* do zapisu, plus czasowniki na przejścia stanu jak publish_page, unpublish_page, revert_to_published i promote_dev_draft.
Nic w tym zestawie nie dotyka Twojego kodu. Nie ma narzędzia, które zapisuje plik, edytuje komponent albo otwiera pull requesta - AI edytuje treść, a schematy bloków zostają w Twoim repo, pod review.
Wersje robocze dewelopera
Dla konkretnego problemu - wypróbowania typu bloku, który nie jest jeszcze wdrożony - istnieje jeden parametr i jedno narzędzie.
Narzędzia zapisujące przyjmują target o wartości "devDraft", które edytuje Twój osobisty overlay zamiast współdzielonego draftu strony. Nikomu innemu podgląd się nie zmienia. Gdy blok trafi na produkcję, promote_dev_draft przenosi Twój overlay na współdzielony draft.
Bez tego eksperymentowanie z niewdrożonym blokiem oznaczałoby wstawianie na współdzielony draft treści, która każdemu współpracownikowi renderuje się jako nic.
Następne kroki
- Serwer MCP - podłączenie zewnętrznego klienta AI.
- Tokeny API - scope'y stojące za
requiredPermissions. - Członkowie i role - co dziedziczy asystent w panelu.