MCP Server

Zarządzaj contentem cmssy z poziomu agentów AI przez MCP - połącz Claude z hostowanym serwerem, logując się, albo uruchom `@cmssy/mcp-server` przez stdio z tokenem API.

9 października 2026

Przegląd

@cmssy/mcp-server to serwer Model Context Protocol, który łączy agentów AI (Claude Code, Claude Desktop, dowolne narzędzie wspierające MCP) z workspace'em Cmssy. Po skonfigurowaniu agent może listą i edytować strony, dodawać i usuwać bloki, publikować draftów, zarządzać formularzami i więcej — bez wychodzenia z edytora.

Działa na dwa sposoby: Claude łączy się z hostowanym serwerem pod https://api.cmssy.io/mcp po zalogowaniu do cmssy, a dowolny klient MCP może uruchomić paczkę npm przez stdio z tokenem API. Żaden nie wymaga Twojego własnego, stale działającego serwera.

Czym różni się od HTTP API

  • Scope'owany do workspace'u — para token + workspace ID, wszystko egzekwowane po stronie serwera
  • Wysokopoziomowe narzędzia — add_block_to_page, publish_page, patch_block_content, nie surowy GraphQL
  • Izolacja tenant wbudowana — każde zapytanie jest filtrowane po Twoim workspace; nie dotkniesz przypadkiem innego tenanta

Połącz Claude (bez tokena)

Claude w przeglądarce, Claude Desktop i Claude Code łączą się z hostowanym serwerem pod https://api.cmssy.io/mcp. Logujesz się do cmssy i wybierasz workspace'y, z których Claude może korzystać - nie ma tokena do kopiowania ani niczego do instalowania.

Claude w przeglądarce lub na desktopie

  1. Otwórz Settings → Connectors i wybierz Add custom connector.
  2. Wklej https://api.cmssy.io/mcp i dodaj.
  3. Kliknij Connect, zaloguj się do cmssy, zaznacz workspace'y dla Claude i wybierz Tylko odczyt albo Odczyt i zapis.

Konektor dodany na claude.ai działa też w Claude Desktop.

Claude Code

claude mcp add --transport http cmssy https://api.cmssy.io/mcp

Potem uruchom /mcp w Claude Code i się uwierzytelnij: to samo logowanie i wybór workspace'ów otworzą się w przeglądarce.

W adminie Konto → Połączone aplikacje → Połącz z Claude pokazuje ten sam URL i komendę z przyciskami kopiowania.

Co może Claude

  • Twoja rola, per workspace - Claude działa jako Ty, z rolą, którą masz w każdym zaznaczonym workspace. Tylko odczyt ogranicza go do czytania, nawet gdy Twoja rola pozwala pisać.
  • Kilka workspace'ów naraz - każde narzędzie przyjmuje argument workspace (org-slug/workspace-slug), a list_workspaces wypisuje te, które udostępniłeś. Workspace, do którego dołączysz później, nie dochodzi sam - połącz się ponownie, żeby go dodać.
  • Narzędzia niszczące pytają najpierw - Claude pyta Cię przed narzędziem, które usuwa lub publikuje, a potwierdzenie po stronie serwera (niżej) nadal obowiązuje.
  • Audyt na Ciebie - zmiana wprowadzona przez Claude trafia do logu audytu workspace'u pod Twoim nazwiskiem, tak jak zmiana zrobiona w adminie.

Rozłączanie

Konto → Połączone aplikacje → Rozłącz odcina Claude od wszystkich workspace'ów naraz. Admin workspace'u może usunąć jeden workspace z aplikacji członka w Ustawienia → Połączone aplikacje; pozostałe workspace'y członka działają dalej. Utrata dostępu do workspace'u usuwa go z Twoich połączeń.

Co trafia do Claude

Tylko treść zaznaczonych workspace'ów i tylko to, co zwróci wywołanie narzędzia. cmssy przechowuje samo połączenie (która aplikacja, które workspace'y, odczyt czy zapis) i zahashowane tokeny - nigdy kopii rozmowy.

Konfiguracja z tokenem API (stdio)

Dla CI, skryptów albo agenta bez przeglądarki uruchom paczkę npm z tokenem API.

1. Stwórz token API

Workspace Settings → API Tokens → Create token. Skopiuj wartość cs_… od razu — tokeny wyświetlane są tylko raz. Scope to wyłącznie authn; co token może zrobić zależy od Twojej roli oraz flagi isSuperAdmin.

Bez przeglądarki? Agent może utworzyć konto, organizację, workspace i token przez API - zobacz Tworzenie tokena bez przeglądarki.

2. Znajdź ID workspace'u

Workspace Settings → General ma przycisk copy obok ID. To ten sam workspace, do którego przypisany jest Twój token API.

3. Dodaj do konfiguracji MCP edytora

Dla Claude Code edytuj .mcp.json w root projektu (albo zarejestruj go dla wszystkich projektów przez claude mcp add --scope user):

{
  "mcpServers": {
    "cmssy": {
      "command": "npx",
      "args": [
        "-y",
        "@cmssy/mcp-server@latest",
        "--token", "cs_your_token_here",
        "--workspace-id", "507f1f77bcf86cd799439011"
      ]
    }
  }
}

Wspierane są też ekwiwalenty env: CMSSY_API_TOKEN, CMSSY_WORKSPACE_ID, CMSSY_API_URL. Przydatne gdy nie chcesz trzymać tokena w commitowanym configu.

--api-url (lub CMSSY_API_URL) to origin API, domyślnie https://api.cmssy.io; serwer sam dokleja /graphql, więc go nie dopisuj.

4. Zrestartuj edytor

Claude Code podepnie serwer przy następnym starcie sesji. Powinien pojawić się wpis cmssy w MCP z listą narzędzi.

Dostępne narzędzia

Pełna lista, z uprawnieniem, którego wymaga każde narzędzie, to Narzędzia MCP - generuje ją serwer przy każdym wydaniu, więc zawsze odpowiada temu, co wystawia Twoja wersja. Narzędzia mają jeden kształt nazw - list_* i get_* do odczytu, create_* / update_* / delete_* do zapisu, plus czasowniki dla przejść stanu - i dzielą się na grupy:

  • Strony i bloki - drzewo stron, bloki, regiony layoutu, typy stron i publikacja: get_page, add_block_to_page, patch_block_content, publish_page. Przed dodaniem bloku wywołaj list_block_types: zwraca typy bloków, które Twoja strona naprawdę rejestruje.
  • Modele i rekordy - schematy i ich wpisy, w tym masowy import_records. delete_record odmawia, dopóki rekord jest używany w bloku, i podaje strony, które go używają; przekaż force: true, żeby usunąć mimo to.
  • Media - uploady i foldery.
  • Formularze - formularze i ich zgłoszenia.
  • Commerce - produkty, zamówienia (ręczne zamówienia, płatności, faktury, zwroty, realizacja, pipeline zamówień), koszyki, rabaty i klienci.
  • Webhooki - subskrypcje, dostawy i sekrety podpisu. list_webhook_event_types to allow-lista subskrybowalnych zdarzeń; sekret podpisu wraca raz, przy utworzeniu i przy rotacji.
  • Workspace - get_workspace_info (plan, limity, zużycie), get_site_config, zespół i role.

Pełnotekstowe search_content nie jest zbindowane w serwerze MCP; jest dostępne z asystenta w adminie. Nic w tym zestawie nie dotyka Twojego kodu: żadne narzędzie nie zapisuje pliku, nie edytuje komponentu ani nie otwiera pull requesta - AI edytuje treść, a schematy bloków zostają w Twoim repozytorium, pod review.

Potwierdzenie przed operacjami niszczącymi

Narzędzia, których skutek najtrudniej cofnąć - na przykład delete_page, publish_page, refund_order, bulk_delete_products - nie działają przy pierwszym wywołaniu. Odpowiadają needsConfirmation: true, jednozdaniowym summary tego, co by się stało, i ref - i nic się nie zmienia. Agent pokazuje Ci podsumowanie; po Twojej zgodzie wywołuje to samo narzędzie jeszcze raz, z tymi samymi argumentami plus _confirm: "<ref>".

  • Ref działa raz, przez czas podany w expiresInSeconds, i tylko z argumentami, dla których został wydany - zmień dowolny argument, a serwer zapyta ponownie.
  • Narzędzie, które wymaga potwierdzenia, ma parametr _confirm w schemacie wejścia, więc klient rozpozna je z tools/list.
  • Ta sama zasada działa w asystencie AI w adminie, gdzie zatwierdzasz przyciskiem w czacie.

Dev drafty: blok, który nie jest jeszcze wdrożony

Każde narzędzie zapisu przyjmuje opcjonalny target. "draft" (domyślny) edytuje wspólny draft strony; "devDraft" edytuje Twoją własną nakładkę per użytkownik, która startuje od bieżącej strony i nie zmienia podglądu nikomu innemu.

To dlatego można bezpiecznie składać stronę wokół typu bloku, który na razie istnieje tylko na Twojej maszynie. Gdy blok pojedzie na produkcję, promote_dev_draft przenosi nakładkę na wspólny draft. get_page z target: "devDraft" zwraca nakładkę obok wspólnego draftu albo null, gdy żadnej nie masz.

patch_block_content — surgical edits

Do precyzyjnych edycji na contencie liczącym wiele KB (artykuły docs, długie wpisy blog), patch_block_content wysyła tylko diff — nie pełny string. W środku MongoDB findOneAndUpdate z $set + arrayFilters, tenant-scoped, atomowe. Typowo ~10× taniej w tokenach niż przesyłanie całego HTML przez update_block_content.

Trzy typy operacji

insert_before / insert_after

Wstaw HTML bezpośrednio przed/po unikalnym markerze. Marker MUSI pasować do dokładnie jednej lokalizacji — zero lub wiele dopasowań odrzuca operację z BAD_USER_INPUT.

{
  "op": "insert_after",
  "marker": "<h2>Cennik</h2>",
  "html": "<p>Plany od 0 zł/msc.</p>"
}

replace_section

Zastąp wszystko od startMarker (włącznie) do endMarker (wyłącznie). Oba markery muszą być unikalne.

{
  "op": "replace_section",
  "startMarker": "<h2>Cennik</h2>",
  "endMarker": "<h2>FAQ</h2>",
  "html": "<h2>Cennik</h2><p>Nowe plany.</p>"
}

Wiele operacji w jednym wywołaniu

Operacje wykonują się po kolei na running result. Każde niepowodzenie (brakujący marker, niejednoznaczny itp.) przerywa cały patch — brak stanu połowicznie zastosowanego.

{
  "pageId": "...",
  "blockId": "...",
  "locale": "pl",
  "operations": [
    {
      "op": "insert_before",
      "marker": "<h2>Załącznik</h2>",
      "html": "<h2>Nowa sekcja</h2><p>…</p>"
    },
    {
      "op": "replace_section",
      "startMarker": "<h2>Cennik</h2>",
      "endMarker": "<h2>FAQ</h2>",
      "html": "<h2>Cennik</h2><p>Zaktualizowane.</p>"
    }
  ]
}

Kiedy operacja zawodzi

  • 0 dopasowań — marker nie znaleziony. Sprawdź pasowanie znak po znaku; whitespace i kolejność atrybutów ma znaczenie.
  • 2+ dopasowań — marker nie jest unikalny. Dodaj otoczenie HTML do disambiguation. Nakładające się dopasowania też liczą ("aa" w "aaa" liczy się jako 2), więc unikaj ultra-krótkich markerów.
  • Pole nie jest stringiem — docelowy fieldPath wskazuje na tablicę lub obiekt. Użyj update_block_content dla pól strukturalnych.
  • Bloki layoutu nie są wspierane — header/footer i inne bloki layoutu lecą przez update_block_content.

patch_block_content vs update_block_content

 patch_block_contentupdate_block_content
Kiedy użyćPunktowe edycje na stringu HTMLPełny rewrite contentu, dowolny kształt
Koszt w tokenachProporcjonalny do diffuProporcjonalny do pełnego contentu
Typowe oszczędności~10× na contencie wielo-KB–
Typy pólTylko string (przez fieldPath)Dowolne (stringi, tablice, obiekty)
Częściowe niepowodzenieCały patch przerywany — brak stanu połowicznegoCały zapis się udaje lub zawodzi
Bloki layoutuNie wspieraneWspierane

Reguła kciuka: jeśli wcześniej wysyłałeś cały HTML tylko żeby zmienić jeden paragraf, użyj patch_block_content. W innym razie zostań przy update_block_content.

Troubleshooting

  • Każde wywołanie kończy się 404 - --api-url kończy się na /graphql. Podaj sam origin (https://api.cmssy.io, domyślny) - serwer dokleja ścieżkę sam.
  • „Workspace not found” — użytkownik stojący za tokenem nie jest członkiem podanego --workspace-id albo id jest złe. Token uwierzytelnia osobę; co wolno, wynika z roli tej osoby w tym workspace. Sprawdź parę w Workspace Settings.
  • „Not authenticated” — token wygasał lub został revoked. Stwórz nowy w Workspace Settings → API Tokens.
  • Serwer MCP niewidoczny w edytorze — zrestartuj edytor po zmianach configu. W Claude Code sprawdź Settings → MCP → cmssy dla logów startowych.
  • Limity rate / plan — serwer MCP respektuje limity planu workspace'u (max stron, storage, tokeny AI). get_workspace_info pokazuje aktualne użycie vs limity.

Tryb odpowiedzi

Każde write tool akceptuje opcjonalny parametr response: "minimal" | "full" (default "minimal"). Minimal zwraca małe compact-JSON ack (~100-200 bajtów) z samymi ID i stanem potrzebnym do następnego wywołania — nie pełny zmutowany zasób.

Kształty minimalnego ack

  • Narzędzia stron (create_page, update_page_blocks, update_page_settings, publish_page, unpublish_page, revert_to_published, update_page_layout) — {id, slug, hasUnpublishedChanges, updatedAt} (+published dla publish/unpublish)
  • Narzędzia block-on-page (add_block_to_page, update_block_content, remove_block_from_page) — {pageId, blockId, hasUnpublishedChanges, updatedAt}
  • Narzędzia formularzy (create_form, update_form) — {id, slug, status, updatedAt}
  • Narzędzia modeli (create_model, update_model) — {id, slug, updatedAt}
  • Narzędzia recordów (create_record, update_record) — {id, status, updatedAt}

Kiedy użyć full

Przekaż response: "full" gdy faktycznie potrzebujesz pełnego zmutowanego zasobu w tym samym wywołaniu — np. aby zweryfikować pełną transformację, odczytać pole generowane serwerowo lub debugować. W innym razie łańcuchuj kolejny tool odczytu (get_page / get_form / get_model / get_record).

Narzędzia które nie biorą response

Już zwracają compact ack i są bez zmian: patch_block_content, wszystkie delete_*, update_form_submission_status, import_records.

Wersja

Używaj @cmssy/mcp-server@latest w .mcp.json, żeby dostawać nowe narzędzia, gdy wychodzą; npx @cmssy/mcp-server --version wypisuje wersję, którą uruchamiasz. Każde wydanie publikuje na nowo Narzędzia MCP prosto z serwera, więc ta strona zawsze odpowiada najnowszej wersji.