Communitygithub.com

Paper App (Deutsch)

Arbeiten Sie in der Paper Design App (paper.design) über deren lokalen MCP-Server. Verwenden Sie dies, wenn Sie in Paper Designs, Mockups oder Varianten erstellen, Artboards oder Folien auf einer Paper-Leinwand bearbeiten, Screenshots oder Exporte (PNG, PDF, Videos) erstellen, Paper-Dateien verschieben oder klonen, benutzerdefinierte Schriftarten oder lokale Bilder in Paper verwenden oder ein Paper-Design in Code umwandeln möchten.

Was ist Paper App (Deutsch)?

Diese Fähigkeit beschreibt die Integration von KI-Agenten (wie Claude Code, Cursor, Codex) mit der Design-App "Paper" (paper.design). Paper ist ein Design-Tool, dessen Leinwand echtes HTML und CSS ist. Der lokale MCP-Server des Paper-Desktops ermöglicht es Agenten, die Leinwand zu lesen und HTML als Design-Knoten darauf zu schreiben. Die in diesem Skill enthaltene SKILL.md-Dokumentation geht weit über die offizielle Anleitung hinaus und fasst die in realen Sitzungen gesammelten Erkenntnisse zusammen, die als "hard way" bezeichnet werden. Sie behandelt wichtige Aspekte wie die korrekte Einrichtung der Verbindung (Überprüfung der Tool-Verfügbarkeit mit `describeNamespace`), die sequenzielle Ausführung von Aufrufen (Parallelaufrufe führen zu Fehlern), die Verwendung von Hilfsfunktionen zur Ergebnisverarbeitung und den Umgang mit Screenshots und Exporten (inklusive Bereinigung von `~/Downloads`). Die Dokumentation geht auch auf die Besonderheiten beim Schreiben von HTML in Paper ein (z.B. leere `<div>`s werden zu Rechtecken ohne Kinder), die Verwendung von Schriftarten und die Organisation der Leinwand durch Duplizieren und Positionieren von Artboards. Schließlich werden die Grenzen des MCP-Servers aufgezeigt, etwa dass er keine Dateien freigeben, in Ordner verschieben oder Knoten zwischen Dateien verschieben kann.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/zeke/paper-app-skill/tree/HEAD/skills/paper-app

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Vorschau

Aus dem Skill-README

Paper App (Deutsch) preview

Dokumentation

Paper App

Paper ist ein Design-Tool, dessen Leinwand echtes HTML und CSS ist. Die Paper-Desktop-App führt einen lokalen MCP-Server aus, der es Agenten ermöglicht, die Leinwand zu lesen und HTML als Design-Knoten darauf zu schreiben.

Der Server bringt eine eigene Anleitung mit. Diese Fähigkeit deckt ab, was diese Anleitung auslässt: Dinge, die auf die harte Tour in echten Sitzungen gelernt wurden.

Vorbereitung

  1. Überprüfen Sie, ob die Tools existieren: await describeNamespace("mcp__paper") im Codemode. Wenn der Namespace leer ist oder ALL_TOOLS keine mcp__paper__*-Einträge enthält, war die Sitzung nicht verbunden, normalerweise, weil Paper nicht geöffnet war, als die Sitzung startete. Der Server läuft unter http://127.0.0.1:29979/mcp und antwortet nur, solange Paper geöffnet ist. pi mcp list (aus bash ausgeführt) zeigt, ob der Server selbst fehlerfrei ist. Wenn ja, kann sich die Sitzung nicht von selbst neu verbinden: Bitten Sie den Benutzer, /mcp reconnect paper in pi auszuführen, oder /reload, falls das nicht funktioniert.
  2. Laden Sie die offizielle Anleitung einmal pro Sitzung: get_guide({ topic: "paper-mcp-instructions" }). Folgen Sie ihr: Posten Sie ein Design-Briefing vor neuen Designs, schreiben Sie eine visuelle Gruppe pro write_html-Aufruf, überprüfen Sie mit Screenshots und rufen Sie finish_working_on_nodes auf, wenn Sie fertig sind. Weitere Themen: mobile-status-bar, figma-import, image-generation.
  3. Finden Sie die Datei. list_resources({ limit: 200 }) listet Dateien auf, ohne dass eine geöffnet ist. Übergeben Sie fileId an jeden dateibezogenen Aufruf. get_basic_info({ fileId }) funktioniert mit einer Datei, die nicht im Vordergrund-Tab ist, daher benötigen Sie selten open_file, das einen Tab in der App des Benutzers öffnet.
  4. Wenn das Projekt eine AGENTS.md hat, suchen Sie dort zuerst nach der Paper-Datei-ID und den Leinwand-Konventionen.

Paper aus dem Codemode aufrufen

  • Führen Sie abhängige Paper-Aufrufe in einem Skript mit await oder in sequenziellen Schritten aus. Geben Sie sie niemals als parallele Tool-Aufrufe im selben Schritt aus. Parallele Aufrufe haben in der Vergangenheit die meisten Fehler verursacht, und jeder wurde als Paper-Bug fehlinterpretiert: "Node not found" für einen Knoten, den ein paralleler Aufruf gerade erstellt hatte, Kinder landeten in durcheinandergebrachter Reihenfolge, Exporte fehlten bei kürzlichen Schreibvorgängen, und read schlug mit ENOENT fehl, weil der Export noch nicht geschrieben war.
  • Jedes dateibezogene Tool erfordert fileId in seiner Codemode-Deklaration, auch wenn die Anleitung des Servers sagt, dass man es weglassen kann. Das Weglassen schlägt bei der Validierung fehl. Nur get_basic_info und get_selection akzeptieren kein fileId.
  • Führen Sie describeTool("mcp__paper__<name>") vor der ersten Verwendung eines Tools aus. Argumentstrukturen sind nicht erratbar: get_font_family_info nimmt familyNames: string[] entgegen, set_text_content und update_styles nehmen ein updates-Array, und export nimmt eine nodes-Map.
  • Dateibezogene Tools geben einen einfachen String zurück: einen JSON-Header { file, contentHash }, dann den Body. Tools ohne Datei (list_resources, create_file, open_file, get_guide) geben { content: [{ type: "text", text }] } zurück. Extrahieren Sie nicht das erste "id" aus einem Ergebnis: Es ist die Datei-ID, und die Übergabe als Knoten-ID schlägt fehl mit "Node not found".
  • Dateibezogene Fehler und Validierungsfehler werfen Ausnahmen. Einige Fehler ohne Datei (wie "Open a Paper file to use this tool.") werden stattdessen mit isError: true aufgelöst. Umwickeln Sie Paper-Aufrufe nicht mit .catch(() => {}): Ein falsches Argument führt dann zu einem stillen Fehler, und die Bearbeitung wird nie angezeigt.
  • "Your Paper file is currently disconnected from the server" bedeutet, dass Schreibvorgänge fehlschlagen, während Lesevorgänge noch funktionieren. In früheren Sitzungen halfen Schlafen und erneutes Versuchen nicht. Bitten Sie den Benutzer, die Paper-Datei wieder in den Vordergrund zu bringen, und versuchen Sie es dann erneut.
  • get_screenshot gibt im Codemode kein Bild zurück: Sein Ergebnis wird auf den Header-String reduziert. Verwenden Sie den unten stehenden shot()-Helfer, der ein PNG exportiert und im selben Skript liest. Wenn ein Aufrufer MCP-Tools direkt anstelle des Codemodes aufruft, werden get_screenshot-Bilder jedoch durchgereicht.

Nützliche Ergebnisstrukturen nach Parsen des Bodys:

ToolBody
create_artboard{ id, name, worldX, worldY, width, height }
write_html{ createdNodes: [{ id, name, component }] }, nur Top-Level-Knoten
get_tree_summary{ summary }, ein eingerückter Textbaum mit Type "name" (id) W×H
get_children{ children: [{ id, name, component, childCount, x, y }], count }
find_nodes{ nodes: [{ id, name, component, matched: [{ styleName, styleValue }] }] }
duplicate_nodes{ duplicatedNodes: [{ sourceId, newId, descendantIdMap }] }
export{ exports: [{ nodeId, filePath }] }
update_stylesListet ignoredStyles auf, wenn ein Stil in diesem Kontext wirkungslos ist. Prüfen Sie es.

Helfer

Fügen Sie diese am Anfang eines Codemode-Skripts ein oder speichern Sie sie einmal und werten Sie sie in späteren Aufrufen mit eval aus:

var F = "<fileId>";
var txt = r => typeof r === "string" ? r : (r?.content ?? []).map(c => c.text ?? "").join("\n");
// Entfernt den { file, contentHash }-Header, den dateibezogene Tools voranstellen.
var body = r => { const t = txt(r); const i = t.indexOf("\n}\n"); return t.startsWith('{\n  "file"') && i > -1 ? t.slice(i + 3) : t; };
var json = r => JSON.parse(body(r));
var w = async (target, html, mode = "insert-children") =>
  json(await tools.mcp__paper__write_html({ fileId: F, targetNodeId: target, mode, html })).createdNodes;
// Exportiert einen Knoten als PNG, zeigt ihn an und löscht die Datei aus ~/Downloads.
var shot = async (id, scale = "1x") => {
  const { exports } = json(await tools.mcp__paper__export({ fileId: F, nodes: { [id]: [{ format: "png", scale }] } }));
  const p = exports[0].filePath;
  image(await tools.read({ path: p, offset: null, limit: null }));
  await tools.bash({ command: `rm -f "${p}"`, timeout: 5 });
};

Um Helfer über Aufrufe hinweg wiederzuverwenden: store("paper", helperSource), dann eval(load("paper")) am Anfang jedes späteren Skripts. Deklarieren Sie Helfer mit var, da const und let innerhalb von eval nicht nach außen dringen. store() behält Werte nur, wenn das Skript erfolgreich ist. Speichern Sie Helfer daher in einem Skript, das nichts anderes tut.

Screenshots und Exporte

  • Machen Sie Screenshots in einem separaten Codemode-Aufruf von den Bearbeitungen. Ein Export im selben Skript wie die Schreibvorgänge kann ausgeführt werden, bevor Paper sie rendert, sodass das PNG fehlende oder veraltete Inhalte zeigt.
  • export schreibt nach ~/Downloads/<artboard name>.png, mit @2x oder @0.5x für andere Skalierungen und (1), (2)-Suffixen, wenn eine Datei mit diesem Namen bereits existiert. Zeichen wie ? und : werden zu _. Verwenden Sie immer den zurückgegebenen filePath. Wählen Sie Dateien nicht mit ls -t ~/Downloads oder Namens-Globs aus: Das hat bereits veraltete Exporte aus früheren Läufen aufgegriffen.
  • Verschieben oder löschen Sie Exporte nach dem Lesen, damit sie sich nicht in ~/Downloads ansammeln. Lassen Sie Dateien in Ruhe, die Sie nicht erstellt haben.
  • Verwenden Sie 0.5x für Screenshots zur Überprüfung, um Tokens zu sparen, 2x für Liefergegenstände (1920×1080-Artboards werden zu 3840×2160).
  • export_combined_pdf fasst Artboards in einem PDF zusammen, geordnet nach Leinwand-Position. export erstellt auch mp4-/webm-Videos sowie svg für SVG-Knoten, jpg, webp, avif und pdf.
  • Informationen zum Umwandeln von Artboards in Google Slides finden Sie in references/slides-export.md.

HTML schreiben

Die write_html-Tool-Beschreibung listet die Regeln auf (Inline-Styles, Flex, kein margin, kein display: grid, keine Tabellen, layer-name für Ebenennamen). Zusätzliche Erkenntnisse:

  • Ein leeres <div> wird zu einem Rechteck-Knoten, selbst mit display: flex, und Rechtecke können keine Kinder haben. Das Schreiben in einen solchen Knoten schlägt fehl mit "cannot have children". Schreiben Sie einen Container zusammen mit seinem ersten Kind, oder ersetzen Sie das Rechteck mit write_html im Modus replace.
  • Rich-Text wird nicht unterstützt. Für syntax-hervorgehobenen Code oder einen Satz mit einem farbigen Wort bauen Sie eine Flex-Zeile aus separaten Text-Knoten, einen pro Token, jeweils mit white-space: pre. Code wird zu einer Zeile pro Code-Zeile. Generieren Sie das HTML mit einem Helfer, anstatt es von Hand zu schreiben.
  • Ein background mit Farbverlaufsebenen ignoriert backgroundColor. Fügen Sie die Grundfarbe als letzte Ebene hinzu: linear-gradient(#F6F7F9, #F6F7F9).
  • Inline-<svg> funktioniert für Symbole, Logos und Verbindungslinien und akzeptiert fill-/stroke-Farben und Token-Variablen. Betten Sie das SVG eines Markenlogos anstatt es zu verlinken.
  • SVG-Pfad-Füllungen sind für find_nodes und get_computed_styles unsichtbar (was {} für sie zurückgibt). Finden Sie die SVGVisualElement "Path"-Knoten in get_tree_summary und färben Sie sie mit update_styles({ styles: { fill } }) um, was funktioniert.
  • Lokale Bilder benötigen einen absoluten Pfad mit dem paper-asset://-Schema: <img src="paper-asset:///private/tmp/spec/foo.png">.
  • Gleich breite Spalten in einer Flex-Zeile benötigen flex: 1; flex-basis: 0. Andernfalls macht Padding in einer Spalte sie breiter als ihre Geschwister.
  • Wenn Inhalte abgeschnitten werden, setzen Sie das Artboard mit update_styles auf height: "fit-content", anstatt eine neue Höhe zu erraten.

Schriftarten

  • get_font_family_info({ fileId, familyNames: [...] }) prüft auf dem Rechner installierte Schriftarten und Google Fonts. Rufen Sie es vor der ersten typografischen Gestaltung in einer Sitzung auf.
  • Schriftarten, die während einer Sitzung installiert werden (z. B. in ~/Library/Fonts auf macOS), werden erst nach einem Neustart von Paper angezeigt. Bitten Sie den Benutzer, Paper zu beenden und erneut zu öffnen. Beenden Sie es nicht selbst, da dies seinen Zustand verlieren kann.
  • Überprüfen Sie die Lizenz einer Schriftart, bevor sie auf einer öffentlichen Website erscheint. Viele Schriftarten von dafont.com sind nur für den persönlichen Gebrauch kostenlos.
  • Um viele Schriftarten zu vergleichen, ohne Paper neu zu starten, rendern Sie Schriftproben lokal als transparente PNGs (z. B. mit Pillow), platzieren Sie sie als paper-asset://-Bilder auf einem Schriftproben-Artboard und installieren Sie nur die Finalisten.

Organisation der Leinwand

  • Wenn Sie an einem Design iterieren, duplizieren Sie das Artboard und ändern Sie die Kopie. Bearbeiten Sie frühere Boards nicht direkt: Benutzer möchten den Fortschritt sehen und bitten oft darum, zu einer früheren Version zurückzukehren. Ein Benutzer musste dies in einer Sitzung zweimal anfordern.
  • create_artboard und duplicate_nodes legen neue Artboards an der besten leeren Stelle ab, was sie verstreut. Um sie anzuordnen, setzen Sie top und left auf den Artboards mit update_styles. Halten Sie mindestens 80px Abstand zwischen Artboards.
  • Halten Sie Design-Explorationen getrennt von der gewählten Richtung: in ihrem eigenen Bereich der Leinwand oder auf einer eigenen Seite (create_page, dann pageId übergeben). Sie können nicht die Seite wechseln, die der Benutzer gerade ansieht.
  • Für Folien und Variantensätze verwenden Sie ein festes Raster (z. B. vier pro Zeile, x = x0 + col × (width + gap)). Wenn ein Artboard hinzugefügt oder entfernt wird, ordnen Sie die restlichen neu an, sodass keine Lücken entstehen, und nummerieren Sie ihre Namen neu.
  • Für helle und dunkle Varianten setzen Sie die helle Reihe oben und die passende dunkle Version direkt darunter. Informationen zum Erstellen der dunklen Versionen finden Sie in references/dark-mode-variants.md.
  • Geben Sie Artboards beschreibende Namen wie Homepage · A (Editorial) oder 04 · What are Workers?. Exportdateinamen werden daraus abgeleitet.
  • Knoten-IDs überdauern die Sitzung nicht. Schreiben Sie die Datei-ID, URL, das Benennungsschema, die Rasterformel und die Stilregeln in die AGENTS.md des Projekts, damit die nächste Sitzung darauf aufbauen kann.

Design zu Code

  • Lesen Sie exakte Werte mit get_jsx (format: "inline-styles" oder "tailwind") und get_computed_styles. Messen Sie niemals Größen oder Farben aus einem Screenshot.
  • Berechnete Farben können als oklab(...) zurückkommen. Kopieren Sie sie wörtlich, anstatt sie umzuwandeln.
  • Vergleichen Sie die Seite nach dem Erstellen in einem echten Browser mit einem Paper-Export, im hellen und dunklen Modus.

Was der MCP nicht kann

  • Dateien freigeben oder Berechtigungen verwalten. Der Benutzer teilt aus der Paper-App: Laden Sie Personen zum Team ein, damit sie bearbeiten können, oder senden Sie die Datei-URL für schreibgeschützten Zugriff.
  • Dateien in Ordner verschieben. Neue Dateien von create_file landen außerhalb der Ordner des Benutzers, und der Benutzer muss sie hineinziehen.
  • Knoten zwischen Dateien verschieben. move_nodes verschiebt nur innerhalb einer Datei, zwischen Seiten. Um den gesamten Inhalt einer Datei zu verschieben, create_file({ cloneFileId, name }), überprüfen Sie, ob Knoten- und Artboard-Anzahl übereinstimmen, und löschen Sie dann die Originale mit delete_nodes. Bestätigen Sie dies mit dem Benutzer vor dem Löschen.
  • Die Seite wechseln, die der Benutzer gerade ansieht.

Verwandte Skills