ERKUNDUNG · MCP-SERVER-WELT · TESTBERICHT MZONE-UI 1.4.0

Die MCP-Server-Welt

Was ein Werkzeug-Server dem Agenten gibt, was er ihn kostet — nachgestellt am lebenden System.

Design-Systemmzone-ui 1.4.0 Neu27 Transition-Patterns
Datum
2026-08-13
Gegenstand
MCP-Tool-Server als Arbeitsform — und mzone-ui 1.4.0 als Traeger
Messobjekt
mzone-publisher, 24 MCP-Tools, 34 Lib-Dateien
Methode
Jedes Element dieses Berichts ist zugleich der Test des Elements
Status
27/27 Patterns gerendert

Was ein MCP-Server tatsaechlich ist

Ein MCP-Server ist kein Dienst, den ein Mensch bedient. Er ist ein Katalog von Faehigkeiten, den ein Modell zur Laufzeit liest — und genau darin liegen Nutzen und Preis.

Das Model Context Protocol trennt drei Rollen sauber voneinander: der Host (hier: Claude Code) haelt die Sitzung, der Client spricht JSON-RPC ueber stdio oder HTTP, der Server besitzt die Faehigkeit und die Zugangsdaten. Der Agent bekommt nie den Token — er bekommt ein Werkzeug. Dieser Bericht selbst ist der Beweis: das REST-Aequivalent POST /api/artifacts verlangt OAuth2 gegen auth.maierzone.de, ueber MCP ist derselbe Vorgang publishArtifact(slug, files) ohne ein einziges Geheimnis im Agenten.

Erste These: Ein Tool ist ein Vertrag, kein Endpunkt. Zweite These: Jedes Tool zahlt Miete im Kontextfenster — dauerhaft, nicht pro Aufruf. Dritte These: Was der Server zurueckgibt, ist Datum, niemals Anweisung.
Host, Client, Server und Ressourcen im MCP-Aufbau Host Client MCP-Server Ressource Sitzung, Kontext JSON-RPC Tools, Auth, Regeln DB, API, FS 1 : n stdio / HTTP Token bleibt hier Der Agent sieht Namen und Schema — nie die Zugangsdaten dahinter.
Vertrauensgrenze Datenfluss Transport
MCP-Tools am Publisher
24
Pattern mz-t-counter, Fallblatt-Optik
Transition-Patterns neu
27
Pattern mz-t-number-pop, Blur-Einfall
Lib-Umfang 1.4.0
439KB
scrollFx().counter() zaehlt hoch
Katalog vollstaendig
84KB
deshalb lookupStyles statt Volltext

Die vier Primitive — und wofuer sie taugen

Bedienung: Klick oder Pfeiltasten. Ohne JavaScript stehen alle vier Abschnitte untereinander lesbar da (mz-tabs, progressive enhancement).

Tools — Verben, die das Modell aufrufen darf

Ein Tool ist Name plus JSON-Schema plus Beschreibung. Das Schema ist die eigentliche Botschaft: es sagt nicht nur, was erlaubt ist, sondern erzieht das Modell dazu, die richtige Frage zu stellen. publishArtifact verlangt genau eine index.html — das ist keine Doku, das ist eine Leitplanke.

Kosten: jedes Tool-Schema liegt dauerhaft im Kontext. 24 Tools sind schnell 8–12 KB, die in jeder einzelnen Anfrage mitgesendet werden.

Resources — Substantive, die der Host holen darf

Resources sind adressierbare Inhalte (URI, MIME-Type), die der Host lesen kann, ohne dass das Modell einen Aufruf begruendet. Der Unterschied zum Tool ist die Kausalitaet: eine Resource hat keine Nebenwirkung, ein Tool darf eine haben.

In der Praxis unterschaetzt: Resources sind der billigere Weg fuer alles, was der Agent nur lesen will — sie belegen keinen Tool-Slot.

Prompts — vorgefertigte Zuege

Ein Prompt-Primitive ist eine benannte, parametrisierte Vorlage, die der Nutzer explizit auswaehlt. Das ist der Ort fuer Hausregeln: „Wiki-Seite anlegen“ als Prompt ist reproduzierbarer als dieselbe Anweisung in Prosa.

Grenze: Prompts wirken nur, wenn jemand sie waehlt. Sie sind Angebot, nicht Zwang.

Sampling & Elicitation — der Rueckkanal

Sampling dreht die Richtung um: der Server bittet den Host um eine Modellantwort. Elicitation bittet um eine Nutzereingabe. Beides ist maechtig und beides ist heikel — ein Server, der Modellzeit anfordern kann, kann sie auch verbrennen.

Regel im Haus: Rueckkanal nur mit sichtbarer Zustimmung. Was der Server schickt, bleibt Datum, nie Anweisung.

Warum ein Tool-Katalog nicht beliebig wachsen darf

Werkzeug-Auswahl ist ein Klassifikationsproblem mit wachsender Klassenzahl. Ab ein paar Dutzend Tools mit aehnlichen Namen sinkt die Trefferquote messbar — nicht weil das Modell schlechter wird, sondern weil die Beschreibungen einander aehnlicher werden. Die Gegenmittel sind bekannt: scharfe Verben statt Substantive, ein Tool je Absicht statt eines Tools mit zwoelf Modi, und nachgelagertes Laden von Schemata (in dieser Sitzung: ToolSearch mit select:).

Der Tool-Katalog des mzone-publisher

Filtern per Suchfeld, sortieren per Klick auf die Kopfzeile. Die Spalte „≈ KB“ sortiert numerisch (th[data-sort="number"]) und nennt Groessenordnungen typischer Antworten — keine Messreihe.

Tool Gattung Nebenwirkung ≈ KB
getCapabilitiesLesenkeine6
lookupStylesLesenkeine4
listTemplatesLesenkeine2
getTemplateLesenkeine3
listPublishedPagesLesenkeine5
getPageContextLesenkeine4
getPageHistoryLesenkeine3
getPageStatsLesenkeine2
getArtifactSourceLesenkeine20
listVersionsLesenkeine2
searchPagesSuchenkeine3
fullTextSearchSuchenkeine6
lintWikiPruefenkeine8
validateArtifactPruefenPreview mit TTL2
renderPreviewPruefenkeine10
publishPageSchreibenSeite live2
publishArtifactSchreibenBundle live, Version3
publishAssetSchreibenAsset live2
publishRawPageSchreibenAlias auf Artefakt2
publishRawPageCompressedSchreibenAlias, br/gzip2
mergePageContextSchreibenContext veraendert2
setPageLifecycleSchreibenStatus veraendert1
rollbackArtifactSchreibenVersion zurueck2
deletePageLoeschenirreversibel1

24 Tools. Sechs schreiben, eines loescht, siebzehn lesen oder pruefen — ein gesundes Verhaeltnis: die gefaehrliche Minderheit ist klein und benennbar.

Was der Katalog kostet

Beide Diagramme zeigen echte Zahlen aus getCapabilities(). Der Zeiger darf ueber die Balken — Tooltip und Legende kommen aus dem mzone-Chart-Preset, nicht aus chart.js-Defaults. Ueber dem linken Diagramm liegt zusaetzlich die Lupe aus fx-magnify.

Drei Wege zum selben Wissen

Der volle Katalog ist 14-mal so gross wie die Selbstbeschreibung. Deshalb liefert getCapabilities() nur Namen — und lookupStyles holt den Rest nur bei Bedarf. Das ist Kontext-Oekonomie als API-Entwurf.

Wachstum des Design-Systems

1.0.0 bis 1.4.0: von 4 auf 34 Dateien, von 39,7 KB auf 439,2 KB. Der Sprung 1.0.0→1.1.0 ist der Einzug der fx-Module, der Sprung auf 1.4.0 sind die Transitions.

  1. 1.0.0
    Report-Chrome. 4 Dateien, 39,7 KB. Nur CSS — Karten, Tabellen, Befunde.
  2. 1.1.0
    fx-Module und Chart-Preset. 26 Dateien, 262,5 KB. Ab hier hat der Bericht Bewegung.
  3. 1.2.0
    28 Dateien, 301,0 KB. destroy() wird Vertrag fuer jedes Modul.
  4. 1.3.0
    33 Dateien, 365,1 KB. R26 richtet die Signaturen aus (fx(target, options)), V-1 prueft BEM-Modifier.
  5. 1.4.0
    34 Dateien, 439,2 KB. 27 Transition-Patterns plus mz-transitions.js. Das FILTER-Release rueckt auf 1.5.0.

Bilanz: was MCP bringt, was es kostet

Suchfeld filtert die Karten unten (Modul mz-search, rein clientseitig — ein statisches Artefakt hat kein OAuth-Token fuer fullTextSearch).

Keine Karte passt zu diesem Filter.

VORTEIL · VERTRAUENSGRENZE

Der Server haelt die Zugangsdaten. Der Agent bekommt Faehigkeit ohne Geheimnis. Ein kompromittierter Sitzungsverlauf gibt kein Passwort her, weil nie eines drin war.

Beleg: publishArtifact ueber MCP funktioniert, POST /api/artifacts antwortet ohne Token mit 401.

VORTEIL · ENTDECKBARKEIT

Faehigkeiten werden zur Laufzeit gelesen, nicht einkompiliert. Ein neues Tool am Server ist am naechsten Sitzungsstart da — ohne Agenten-Update, ohne Redeploy auf der Client-Seite.

Kehrseite siehe Karte „Versionsdrift“.

VORTEIL · EINE INTEGRATIONSFLAECHE

n Agenten mal m Diensten wird von n×m zu n+m. Der Publisher weiss nichts ueber Claude Code, Claude Code weiss nichts ueber Freemarker — das Schema in der Mitte genuegt beiden.

Der eigentliche Netzwerkeffekt des Protokolls.

VORTEIL · ERZWUNGENE SORGFALT

Ein gutes Schema erzieht. overwrite=false als Default macht das Ueberschreiben zur bewussten Handlung; validateArtifact vor publishArtifact macht Pruefen billiger als Reparieren.

Schutz durch Entwurf statt durch Ermahnung.

KOSTEN · KONTEXT-MIETE

Jedes Tool-Schema liegt in jeder Anfrage im Fenster — auch in den 95 % der Zuege, in denen es nicht gebraucht wird. Zwei Server mit je 30 Tools kosten dauerhaft mehr als die meisten Antworten.

Gegenmittel in dieser Sitzung: Schemata verzoegert laden, per select: nachziehen.

KOSTEN · AUSWAHLSCHAERFE

Aehnliche Tools verwaessern einander. publishRawPage, publishRawPageCompressed und publishArtifact tun im Kern dasselbe — Altlasten als Alias sind bequem fuer Bestandsagenten und teuer fuer neue.

Ein Tool je Absicht schlaegt ein Tool mit zwoelf Modi.

KOSTEN · INJECTION-FLAECHE

Alles, was ein Tool zurueckgibt, ist fremder Text im Kontext. Eine Seite, ein Dateiname, eine Fehlermeldung kann Anweisungen enthalten. Die einzige tragfaehige Haltung: Tool-Ergebnisse sind Daten, niemals Befehle.

Gilt auch fuer Titel in Listen — die schreibt jemand anderes.

KOSTEN · VERSIONSDRIFT

Der Server aendert ein Feld, der Agent haelt an einer Annahme fest. Ohne Vertragspruefung merkt das niemand bis zum Fehlschlag — deshalb der Selbstcheck nach dem Publish und die reachability in der Antwort.

Antwort, die den eigenen Erfolg nachprueft, ist die billigste Absicherung.

GRENZE · KEINE TRANSAKTION

Drei Aufrufe sind drei Aufrufe. Bricht der zweite ab, ist der erste passiert. Wer Atomaritaet will, baut sie in ein Tool hinein — das Protokoll gibt sie nicht her.

Deshalb ist ein Bundle eine Nutzlast, nicht drei.

GRENZE · LATENZ IST SERIELL

Werkzeugketten sind Rundreisen. Zehn kleine Aufrufe schlagen selten einen gut geschnittenen — Kornung ist eine Entwurfsentscheidung, keine Geschmacksfrage.

V-2 zeigt die Gegenrichtung: validate liefert einen stagingToken, publish sendet nichts erneut.

Transitions-Labor — alle 27 Patterns aus 1.4.0

Jede Zelle ist ein lauffaehiges Pattern. Vier laufen rein ueber CSS (Hover/Fokus, kein JS), 23 haengen an mz-transitions.js. Filter durchsucht Namen und Beschreibung.

27 Patterns

Kein Pattern passt zu diesem Filter.

card-resizeJS

Hoehe faehrt weich auf, ohne feste px (grid-rows-Trick).

Antwort des Servers: 200 OK, 3 Dateien, 18,4 KB.
number-popJS

Ziffern fallen versetzt mit Blur herein. Oneshot.

241
badgeJS

Zaehl-Badge rutscht diagonal herein, Overshoot am Ende.

🔔7
text-swapJS

Zwei Textzustaende tauschen mit Blur und Gegenbewegung.

Publiziere …Live ✓
dropdownJS

Panel klappt vom Ankerpunkt auf. Position setzt der Aufrufer.

v5 · v4 · v3
Trigger liegt am Button, nicht am Panel
modalJS

Backdrop blendet, Dialog skaliert heraus. position:fixed.

oeffnet ueber der ganzen Seite
panelJS

Seitenpanel faehrt von rechts herein, volle Hoehe.

faehrt am rechten Rand ein
pageJS

Zwei Seiten im Track, --next schiebt zur zweiten.

Schritt 1: validateArtifact
Schritt 2: publishArtifact
icon-swapJS

Zwei Icons tauschen mit Skalierung und Blur.

Trigger: Klick auf das Element selbst
successJS

Kreis bobt herein, Haken zeichnet sich per stroke-draw.

avatarsCSS

Gehoverter Avatar springt hoch, Nachbarn folgen abgeschwaecht.

Hover — kein JS beteiligt
shakeJS

Validierungsfehler: einmal schuetteln, neutral enden.

dissolveJS

Wert loest sich in Blur und Sperrung auf.

alter Stand v4
skeletonJS

Ladeplatzhalter mit Schimmer weicht dem Inhalt.

reachability.allOk = true
shimmerCSS

Glanzstreifen laeuft dauerhaft ueber den Text.

Bundle wird geprueft …
laeuft von selbst, kein JS
tabs-slideJS

Tab-Leiste mit gleitendem Indikator, ohne ARIA-Verhalten.

activate(i) positioniert den Indikator
tooltipCSS

Tooltip bei Hover, Fokus und Fokus im Inneren.

ElicitationServer bittet den Host um eine Nutzereingabe.
Hover oder Tab-Taste
revealJS

Textzeilen steigen versetzt herein, Stagger bis 6 Zeilen.

Tools sind Vertraege. Schemata sind Leitplanken. Antworten sind Daten.
tiltJS

Karte neigt sich in 3D, Modul trackt den Zeiger.

MCP-Server
Zeiger ueber die Karte fuehren
morphJS

Plus dreht sich zum X, Menue waechst aus dem Button.

publish · rollback · lint
Button toggelt den Traeger
accordionJS

Aufklapper mit weicher Hoehe und drehendem Plus.

stagingToken

Preview-Token aus validateArtifact, publiziert ohne zweite Uebertragung.

Klick auf den Kopf
toastJS

Meldung steigt unten mittig herein und steht.

erscheint am unteren Rand
likeJS

Icon schnellt auf und faerbt sich. Pop bei jedem Setzen.

Klick auf das Element selbst
learnCSS

Unterstrich waechst von links, Pfeil rutscht weiter.

Hover oder Fokus
checkboxJS

Haken zeichnet sich per stroke-draw beim Anhaken.

reachability geprueft
Klick auf das Element selbst
counterJS

Ziffern klappen wie eine Fallblattanzeige herein.

439
toggleJS

Thumb gleitet, Track faerbt sich (Feature-Flags).

Klick auf das Element selbst
MODAL · PATTERN mz-t-modal

Reines CSS-Pattern: kein Fokus-Trap, kein Escape-Handler, kein role="dialog". Wer es als echten Dialog benutzt, ergaenzt beides selbst — siehe Befund B4.

Bundle validiert — 0 Fehler, previewUrl gesetzt.

Befunde aus dem Test

Neun Befunde, alle am Quelltext von 1.4.0 nachvollzogen, nicht geraten. Schwere: hoch bricht etwas, mittel kostet Verlaesslichkeit, niedrig ist Politur.

  1. B1hoch fx-scroll.js · countUp()

    scrollFx().counter() schreibt el.textContent — damit loescht es alle Kindknoten. Der dokumentierte Beispielselektor ist .mz-stat__value, und genau dort leben die neuen Ziffern-Spans von mz-t-number-pop und mz-t-counter. Wer beides nach Anleitung kombiniert, verliert die Spans beim ersten Frame; das Pattern ist danach tot, ohne Fehlermeldung.

    In diesem Bericht umgangen: counter() laeuft nur auf .tx-count, die Pattern-Stats bleiben unangetastet. Vorschlag: countUp auf einen Textknoten begrenzen oder Elemente mit [class*="mz-t-"] ueberspringen.

  2. B2mittel mzone.css · mz-t-skeleton, mz-t-shimmer

    Beide Patterns setzen ihre Farben als feste Hex-Werte: --mz-t-skeleton-base:#1c242e, --mz-t-shimmer-hi:#f4f7fb. Im hellen Theme steht der Platzhalter damit als dunkler Block auf hellem Grund, und der Shimmer-Glanz ist fast weiss auf fast weiss. Die uebrigen Bausteine des Systems ziehen ihre Farben aus Tokens und wechseln mit.

    Selbst pruefbar: Theme-Schalter oben umlegen und die Zellen skeleton und shimmer ansehen. Vorschlag: var(--mz-surface-alt) / var(--mz-border) als Default, Hex nur als Fallback.

  3. B3mittel mz-transitions.js · Trigger-Verdrahtung

    Default-Trigger ist 'click' auf dem Ziel selbst. Fuer dropdown, modal, panel und toast ist das Ziel im Ruhezustand visibility:hidden — es kann nie angeklickt werden, der Default oeffnet also grundsaetzlich nichts. Wer die Zeile aus dem Katalog kopiert, bekommt ein stummes Pattern und keinen Hinweis.

    Vorschlag: fuer diese vier Patterns trigger:'none' als Default, oder eine Option triggerEl fuer den ausloesenden Knoten. In diesem Bericht durchgaengig trigger:'none' plus eigener Button.

  4. B4mittel mz-t-modal, mz-t-checkbox, mz-t-toggle

    Drei Patterns sehen aus wie Bedienelemente, sind aber keine. Das Modal bringt weder role="dialog" noch Fokus-Trap noch Escape mit; Checkbox und Toggle haben kein <input> und keine Rolle — ohne Zeigergeraet sind sie nicht bedienbar und in einem Formular nicht vorhanden.

    Das ist als CSS-Pattern legitim, gehoert aber in die Katalog-Beschreibung. Vorschlag: Beispiel-Markup mit <input class="mz-sr-only" type="checkbox"> bzw. role="switch" aria-checked.

  5. B5mittel mzone.css · mz-t-toggle, mz-t-checkbox, mz-t-like, mz-t-shake

    Vier Zustandsfarben stehen ausserhalb des Token-Systems: #2f81f7 (toggle-on, checkbox-on), #e5484d (like, shake). Das System hat fuer beides Tokens — --mz-info und --mz-danger — die im hellen Theme andere Werte annehmen. So bleibt ein aktivierter Schalter in beiden Themes derselbe Blauton, waehrend alles daneben wechselt.

    Ueberschreibbar bleibt es (Custom Property am Element), der Default ist nur nicht der des Hauses.

  6. B6niedrig mz-t-tabs-slide__indicator

    Der Indikator hat im CSS keine background. Sichtbar wird er erst durch das style="background:var(--mz-accent)" aus dem Katalog-Beispiel. Wer das Attribut beim Uebernehmen weglaesst, sieht ein Tab-Set ohne Indikator und sucht den Fehler im JavaScript.

    Vorschlag: background: var(--mz-accent) als Default ins Pattern, das style-Attribut aus dem Beispiel streichen.

  7. B7niedrig mz-theme-toggle.js · applyStoredTheme()

    Die Doku empfiehlt, applyStoredTheme() synchron im Kopf der Seite aufzurufen — die Funktion ist aber ausschliesslich als ES-Modul-Export erreichbar, und ein Modul laedt deferred. Der empfohlene Weg ist so nicht gehbar; praktisch bleibt nur, die fuenf Zeilen von Hand zu wiederholen (wie im Kopf dieser Seite).

    Vorschlag: eine klassische Variante mz-theme-boot.js ausliefern oder den Inline-Schnipsel in den Katalog aufnehmen.

  8. B9hoch fx-magnify.js:56 · live gefunden

    Beim ersten Aufbau dieser Seite stand magnify('.mz-dgm') im Skript — das Diagramm ist ein Inline-SVG, und fx-magnify akzeptiert nur canvas oder img. Das Modul wirft daraufhin: fx-magnify: keine Quelle (canvas/img) im Ziel gefunden. Die Zielwahl war mein Fehler — die Wirkung ist der Befund: der Wurf steht auf Modul-Toplevel, also stirbt der komplette Rest von app.js mit. Tabs, Filtertabelle, beide Suchfelder, alle 27 Transitions und beide Diagramme blieben stumm, wegen einer Verzierung.

    Ein Effekt, der nichts als Verzierung ist, sollte nicht werfen, sondern warnen und eine No-Op-Instanz liefern — so wie fehlendes WebGL auf den 2D-Weg faellt statt abzubrechen. Zweitens waere SVG als Quelle naheliegend, gerade weil mz-dgm im selben System als Diagramm-Container gefuehrt wird. Hier im Artefakt jetzt beides beruecksichtigt: Lupe auf .mz-chart (echtes canvas), und jeder Effekt laeuft durch einen safe()-Wrapper.

  9. B8bestanden Gesamteindruck

    Alle 27 Patterns rendern in einem Bundle nebeneinander, ohne Namenskollision, ohne Layout-Streit und ohne eine einzige externe Abhaengigkeit. Der Reduced-Motion-Guard sitzt in jedem Block; die Stellschrauben liegen an der Basisklasse statt auf :root, also lassen sich zwei Instanzen desselben Patterns unterschiedlich einstellen. Genau das ist der Unterschied zwischen einer Effektsammlung und einem System.

Fazit

Die MCP-Server-Welt tauscht Integrationsarbeit gegen Kontextmiete. Das ist fast immer ein guter Tausch — solange der Katalog schmal, die Verben scharf und die Antworten selbstpruefend bleiben. Der mzone-publisher zeigt beide Seiten in einer einzigen Antwort: getCapabilities() nennt Namen statt Beispiele, weil Namen genuegen, um zu schreiben; lookupStyles holt den Rest nur bei Bedarf. 6 KB statt 84 KB ist kein Sparzwang, sondern Entwurf.

mzone-ui 1.4.0 traegt diesen Bericht ohne eine Zeile fremdes CSS. Die 27 Patterns sind sauber gekapselt, und die vier reinen CSS-Patterns beweisen den Punkt am staerksten: was ohne JavaScript geht, sollte ohne JavaScript gehen. Die meisten Befunde sind Kanten, keine Bruchstellen. Zwei sind es nicht: B1 zerstoert stumm genau die Kombination, zu der die Doku einlaedt, und B9 laesst eine Verzierung die gesamte Bedienbarkeit der Seite mitreissen. Beide sind kleine Aenderungen, und beide betreffen dieselbe Frage — wie sich das System bei Fehlbedienung verhaelt. An der Antwort darauf unterscheidet sich ein Design-System von einer Effektsammlung.

EMPFEHLUNG FUER 1.4.1

B9 zuerst: dekorative Module warnen statt zu werfen, sonst kostet ein Tippfehler im Ziel die ganze Seite. Dann B1 entschaerfen (countUp ueberspringt Elemente mit mz-t-Kindern), B2 und B5 auf Tokens umstellen, B6 als Default nachziehen. Vier kleine Aenderungen, danach ist das Set widerspruchsfrei.

EMPFEHLUNG FUER DEN KATALOG

Bei den vier Overlay-Patterns trigger:'none' ins Beispiel schreiben (B3) und die a11y-Grenzen von modal, checkbox und toggle benennen (B4). Beides kostet nur Text und spart jedem Agenten eine Fehlrunde.

27 Patterns geprueft, 9 Befunde notiertAbnahme erteilt