Krita
Ein Modell steuert Krita 5.2.9 über den Hub, um auf zwei Ebenen eine Postkarte zu malen und als .kra-Datei zu speichern. Das erste Skript funktionierte. Die Seite nennt den Text, das Skript, die Antworten des Hubs und die Aufnahme und sagt, wie die Brücke gestartet wurde: nicht aus Scripter, das nicht ausprobiert wurde.
Auf dieser Seite
Krita mit seiner Brücke starten
Der Leitfaden lässt den Bediener die Brückendatei aus Scripter ausführen. Dieser Lauf nutzte dieses Vorgehen nicht. Er startete Krita auf einem virtuellen X-Display, in einem neuen Profil, mit einer Startup-Erweiterung, deren gesamte __init__.py die Brückendatei ausführt:
xvfb-run -a krita --nosplash
exec(open('/usr/share/libremodular-mcp/bridges/krita_bridge.py', encoding='utf-8').read())
Die Kodierung ist nicht optional. Das eingebettete Python von Krita liest Dateien in der Kodierung des Locales, unter dem es gestartet wurde, und die Brückendatei enthält Zeichen mit Akzent: Unter dem Locale C brach ein Befehl ohne encoding='utf-8' mit UnicodeDecodeError ab, wie die Seite Kompatibilität festhält. Der Lauf nutzte in config.toml den Port 9312 und ein neues Token. Der Port lauschte 10,4 s nach dem Start, und get_state für hub listete Krita als verbunden auf:
{
"app": "hub",
"app_version": "0.1.0",
"bridge_version": null,
"captured_at": "2026-10-21T12:47:48.951Z",
"connected": true,
"content_origin": "hub",
"screenshot": null,
"state": {
"modules": [
{
"app_version": "5.2.9",
"bridge_version": "1",
"connected": true,
"mode": "tcp",
"name": "krita"
}
]
},
"warnings": []
}Dem Modell gegebener Text
Vor dem Schreiben rief das Modell get_state für krita auf: "document": null. Das Dokument existiert noch nicht, das Skript muss es also anlegen und in einem Fenster öffnen, bevor es malen kann.
Geschriebenes Skript
Ein Modell, Claude Sonnet 5.5, schrieb dieses Skript nach dem Leitfaden und nach diesem Zustand. Es ist kein Skript aus den Tests des Projekts. Das Skript schreibt Pixelbytes in der Reihenfolge Blau, Grün, Rot, Alpha; die Farben der Aufnahme unten zeigen, dass Krita diese Reihenfolge für dieses Dokument erwartet. Das Skript setzt vor saveAs den Stapelmodus; was ohne ihn geschieht, wurde nicht ausprobiert.
import os
krita = Krita.instance()
document = krita.createDocument(600, 400, "Postcard", "RGBA", "U8", "", 72.0)
krita.activeWindow().addView(document)
root = document.rootNode()
def lerp(a, b, t):
return round(a + (b - a) * t)
top, bottom = (0x1c, 0x38, 0x5c), (0x29, 0xa1, 0x96)
sky_pixels = bytearray()
for y in range(400):
t = y / 399
r, g, b = (lerp(top[i], bottom[i], t) for i in range(3))
sky_pixels += bytes((b, g, r, 255)) * 600
sky = document.createNode("Sky", "paintlayer")
root.addChildNode(sky, None)
sky.setPixelData(bytes(sky_pixels), 0, 0, 600, 400)
hill_pixels = bytearray()
for y in range(400):
for x in range(600):
inside = ((x - 300) / 260) ** 2 + ((y - 400) / 120) ** 2 <= 1
hill_pixels += bytes((0x38, 0x54, 0xC2, 255)) if inside else bytes((0, 0, 0, 0))
hill = document.createNode("Hill", "paintlayer")
root.addChildNode(hill, None)
hill.setPixelData(bytes(hill_pixels), 0, 0, 600, 400)
document.refreshProjection()
document.setBatchmode(True)
path = os.path.join(LMM_WORK_DIR, "postcard.kra")
saved = document.saveAs(path)
result = {"saved": saved, "kra_bytes": os.path.getsize(path), "layers": [node.name() for node in document.topLevelNodes()]}Antwort des Hubs
{
"app": "krita",
"duration_ms": 1060,
"error": null,
"result": {
"kra_bytes": 110725,
"layers": [
"Background",
"Sky",
"Hill"
],
"saved": true
},
"status": "ok",
"stderr": "",
"stdout": "",
"truncated": false
}Das Skript lief in 1,06 s. Das Dokument hat drei Ebenen, weil ein neues Krita-Dokument mit einer Ebene Background beginnt, die das Skript unberührt ließ, unter Sky und Hill. get_state beschrieb danach das Dokument und gab eine Aufnahme seiner Projektion zurück:
{
"app": "krita",
"app_version": "5.2.9",
"bridge_version": "1",
"captured_at": "2026-10-21T12:47:50.526Z",
"connected": true,
"content_origin": "document",
"screenshot": "$XDG_RUNTIME_DIR/libremodular-mcp/captures/krita-20261021T124750502Z.png",
"state": {
"document": {
"active_layer": "{727e9cd9-e6e1-423c-ade7-1bf29d6d5289}",
"color_depth": "U8",
"color_model": "RGBA",
"color_profile": "sRGB-elle-V2-srgbtrc.icc",
"height": 400,
"layers": [
{
"id": "{69f5540d-2916-4771-8df7-1fcad46b677f}",
"name": "Background",
"opacity": 255,
"type": "paintlayer",
"visible": true
},
{
"id": "{ed307be8-5a93-4b16-8739-7508916ea687}",
"name": "Sky",
"opacity": 255,
"type": "paintlayer",
"visible": true
},
{
"id": "{727e9cd9-e6e1-423c-ade7-1bf29d6d5289}",
"name": "Hill",
"opacity": 255,
"type": "paintlayer",
"visible": true
}
],
"name": "Postcard",
"width": 600
}
},
"warnings": []
}Erzeugtes Bild
Die Aufnahme ist das zusammengefügte Bild, das Krita anzeigt, 600 × 400 Pixel. Die darin gelesenen Pixel sind #1C385C oben, #29A196 unten und #C25438 im Hügel, die drei Farben, die der Text verlangt hat. Die vom Skript gespeicherte .kra-Datei hat 110 725 Bytes.
