Teraz z AI - twórz strony przez serwer MCP

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 odpali execute.
  • execute - właściwa robota, biorąca zwalidowany input i obiekt ops.

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