Communitygithub.com

meshy-dev/meshy-3d-agent

KI-Agent-Fähigkeiten für die Meshy-KI-3D-Generierungsplattform

Was ist meshy-3d-agent?

Dieses Skill ist ein leistungsstarkes Werkzeug für Entwickler und KI-Agenten, um direkt mit der Meshy-KI-API zu interagieren und 3D-Assets wie Modelle, Texturen und Animationen zu generieren, herunterzuladen und für den 3D-Druck vorzubereiten. Es deckt den gesamten Lebenszyklus ab: von der API-Schlüsselverwaltung (Umgebungsvariable oder `.env`-Datei) über die Aufgabenerstellung, das exponentielle Backoff-Polling bis hin zu mehrstufigen Pipelines. Es funktioniert auf jeder Plattform mit Python und der `requests`-Bibliothek und erzeugt automatisch strukturierte Projektverzeichnisse im Ordner `meshy_output/`. Die Dokumentation legt großen Wert auf Sicherheit (kein Leaken von API-Keys) und Benutzerkontrolle (Kostenbestätigung vor jeder Ausgabe).

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add meshy-dev/meshy-3d-agent

In Ihrer bevorzugten KI fragen

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

Dokumentation

Meshy 3D — Generierung + Druck

Direkte Kommunikation mit der Meshy-KI-API zur Generierung und zum Druck von 3D-Assets. Deckt den gesamten Lebenszyklus ab: API-Schlüsseleinrichtung, Aufgabenerstellung, exponentielles Backoff-Polling, Herunterladen, mehrstufige Pipelines und 3D-Druckvorbereitung mit Slicer-Integration.


SICHERHEITSMANIFEST

Zugriff auf Umgebungsvariablen:

  • MESHY_API_KEY – API-Authentifizierungstoken, das nur im HTTP-Authorization: Bearer-Header gesendet wird. Wird nie protokolliert, nie in eine andere Datei als .env im aktuellen Arbeitsverzeichnis geschrieben, nur wenn der Benutzer es ausdrücklich anfordert.

Externe Netzwerkendpunkte:

  • https://api.meshy.ai – Meshy-KI-API (Aufgabenerstellung, Statusabfrage, Modell-/Bilddownloads)

Dateisystemzugriff:

  • Lesen: .env nur im aktuellen Arbeitsverzeichnis (API-Key-Suche)
  • Schreiben: .env nur im aktuellen Arbeitsverzeichnis (API-Key-Speicherung, nur auf Benutzeranfrage)
  • Schreiben: ./meshy_output/ im aktuellen Arbeitsverzeichnis (heruntergeladene Modelldateien, Metadaten)
  • Lesen: Dateien, die der Benutzer explizit bereitstellt (z. B. lokale Bilder für Bild-zu-3D-Konvertierung), die nur unter dem genauen Pfad zugegriffen werden, den der Benutzer angibt
  • Kein Zugriff auf Home-Verzeichnisse, Shell-Profile oder Pfade außerhalb der oben genannten

Von diesem Rechner abgehende Daten:

  • API-Anfragen an api.meshy.ai enthalten den MESHY_API_KEY im Authorization-Header sowie vom Benutzer bereitgestellte Text-Prompts oder Bild-URLs. Es werden keine anderen lokalen Daten übertragen. Heruntergeladene Modelldateien werden nur lokal gespeichert.

WICHTIG: Hinweis zur ersten Nutzung einer Sitzung

Wenn dieses Skill zum ersten Mal in einer Sitzung aktiviert wird, informieren Sie den Benutzer:

Alle generierten Dateien werden in meshy_output/ im aktuellen Arbeitsverzeichnis gespeichert. Jedes Projekt bekommt seinen eigenen Ordner ({YYYYMMDD_HHmmss}_{prompt}_{id}/) mit Modelldateien, Texturen, Vorschaubildern und Metadaten. Der Verlauf wird in meshy_output/history.json verfolgt.

Dies muss nur einmal pro Sitzung gesagt werden.


WICHTIG: Dateiorganisation

Alle heruntergeladenen Dateien MÜSSEN in ein strukturiertes meshy_output/-Verzeichnis im aktuellen Arbeitsverzeichnis abgelegt werden. Streuen Sie Dateien NICHT wahllos herum.

  • Jedes Projekt: meshy_output/{YYYYMMDD_HHmmss}_{prompt_slug}_{task_id_prefix}/
  • Verkettete Aufgaben (Vorschau → Verfeinern → Riggen) verwenden dasselbe project_dir
  • Aufgaben in metadata.json pro Projekt und globaler history.json verfolgen
  • Vorschaubilder automatisch zusammen mit Modellen herunterladen

WICHTIG: Shell-Befehlsregeln

Verwenden Sie nur standardmäßige POSIX-Werkzeuge. Verwenden Sie NICHT rg, fd, bat, exa/eza.


WICHTIG: Lange Aufgaben richtig ausführen

Die Meshy-Generierung dauert 1–5 Minuten. Schreiben Sie den gesamten Erstellen → Abfragen → Herunterladen-Ablauf als EIN Python-Skript und führen Sie es in einem einzigen Bash-Aufruf aus. Verwenden Sie python3 -u script.py für ungepufferte Ausgabe. Aufgaben, die 30–120s bei 99% stehen, sind normale Finalisierung – NICHT unterbrechen.


Schritt 0: API-Key-Erkennung (IMMER ZUERST AUSFÜHREN)

Überprüfen Sie nur die aktuelle Sitzungsumgebung und die .env-Datei im aktuellen Arbeitsverzeichnis. Scannen Sie NICHT Home-Verzeichnisse oder Shell-Profil-Dateien.

echo "=== Meshy API-Key-Erkennung ==="

# 1. Aktuelle Umgebungsvariable prüfen
if [ -n "$MESHY_API_KEY" ]; then
  echo "UMGEBUNGSVARIABLE: GEFUNDEN (${MESHY_API_KEY:0:8}...)"
else
  echo "UMGEBUNGSVARIABLE: NICHT_GEFUNDEN"
fi

# 2. .env nur im aktuellen Arbeitsverzeichnis prüfen
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): GEFUNDEN"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"\''" )
fi

# 3. Endstatus
if [ -n "$MESHY_API_KEY" ]; then
  echo "BEREIT: key=${MESHY_API_KEY:0:8}..."
else
  echo "BEREIT: KEY_NICHT_GEFUNDEN"
fi

# 4. Python-requests-Prüfung
python3 -c "import requests; print('PYTHON_REQUESTS: OK')" 2>/dev/null || echo "PYTHON_REQUESTS: FEHLT (führen Sie aus: pip install requests)"

echo "=== Erkennung abgeschlossen ==="

Entscheidung nach der Erkennung

  • Key gefunden → Fahren Sie mit Schritt 1 fort.
  • Key NICHT gefunden → Gehen Sie zu Schritt 0a.
  • Python requests fehlt → Führen Sie pip install requests aus.

Schritt 0a: API-Key-Einrichtung (Nur wenn kein Key gefunden wurde)

Teilen Sie dem Benutzer mit:

Um die Meshy-API zu nutzen, benötigen Sie einen API-Key:

  1. Gehen Sie zu https://www.meshy.ai/settings/api
  2. Klicken Sie auf "Create API Key", geben Sie einen Namen ein und kopieren Sie den Schlüssel (beginnt mit msy_)
  3. Der Schlüssel wird nur einmal angezeigt – bewahren Sie ihn sicher auf

Hinweis: Der API-Zugriff erfordert einen Pro-Plan oder höher. Konten mit kostenlosem Tarif können keine API-Schlüssel erstellen.

Sobald der Benutzer den Schlüssel bereitstellt, setzen Sie ihn für die aktuelle Sitzung und optional für die dauerhafte Speicherung in .env:

# Nur für die aktuelle Sitzung setzen
export MESHY_API_KEY="msy_KEY_HIER_EINFÜGEN"

# Schlüssel verifizieren
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $MESHY_API_KEY" \
  https://api.meshy.ai/openapi/v1/balance)

if [ "$STATUS" = "200" ]; then
  BALANCE=$(curl -s -H "Authorization: Bearer $MESHY_API_KEY" https://api.meshy.ai/openapi/v1/balance)
  echo "Schlüssel gültig. $BALANCE"
else
  echo "Schlüssel ungültig (HTTP $STATUS). Bitte überprüfen Sie den Schlüssel und versuchen Sie es erneut."
fi

Zum dauerhaften Speichern des Schlüssels (nur aktuelles Projekt):

# In .env im aktuellen Arbeitsverzeichnis schreiben
echo 'MESHY_API_KEY=msy_KEY_HIER_EINFÜGEN' >> .env
echo "In .env gespeichert"

# WICHTIG: .env zu .gitignore hinzufügen, um ein Leaken des Schlüssels zu vermeiden
grep -q "^\.env" .gitignore 2>/dev/null || echo ".env" >> .gitignore
echo ".env zu .gitignore hinzugefügt"

Sicherheitserinnerung: Der Schlüssel wird nur in .env in Ihrem aktuellen Projektverzeichnis gespeichert. Übertragen Sie diese Datei niemals in die Versionskontrolle. .env wurde automatisch zu .gitignore hinzugefügt.


Schritt 1: Plan mit dem Benutzer bestätigen, bevor Credits ausgegeben werden

KRITISCH: Bevor Sie eine Aufgabe erstellen, präsentieren Sie dem Benutzer eine Kostenübersicht und warten Sie auf Bestätigung:

Ich werde ein 3D-Modell von "<prompt>" mit folgendem Plan erstellen:

  1. Vorschau (Netzgenerierung) — 20 Credits
  2. Verfeinern (Texturierung mit PBR) — 10 Credits
  3. Herunterladen als .glb

  Gesamtkosten: 30 Credits
  Aktuelles Guthaben: <N> Credits

  Soll ich fortfahren?

Für mehrstufige Pipelines (Text-zu-3D → Riggen → Animieren) zeigen Sie die VOLLEN Pipeline-Kosten im Voraus an.

Hinweis: Das Riggen beinhaltet automatisch Geh- + Laufanimationen ohne zusätzliche Kosten. Fügen Sie Animieren (3 Credits) nur für benutzerdefinierte Animationen über diese hinaus hinzu.

Absichts-zu-API-Zuordnung

Benutzer möchte...APIEndpunktCredits
3D-Modell aus TextText zu 3DPOST /openapi/v2/text-to-3d5–20 (Vorschau) + 10 (Verfeinern)
3D-Modell aus einem BildBild zu 3DPOST /openapi/v1/image-to-3d5–30
3D-Modell aus mehreren BildernMulti-Bild zu 3DPOST /openapi/v1/multi-image-to-3d5–30
Neue Texturen auf vorhandenem ModellNeu texturierenPOST /openapi/v1/retexture10
Netzformat/Topologie ändernRemeshPOST /openapi/v1/remesh5
Modell in andere Formate konvertieren (kein Remesh)KonvertierenPOST /openapi/v1/convert1
Modell auf reale Größe skalierenGröße ändernPOST /openapi/v1/resize1
Neue UVs generieren (GLB, ≤40k Faces) vor externer TexturierungUV EntfaltenPOST /openapi/v1/uv-unwrap5
Skelett zu Charakter hinzufügenAutomatisches RiggenPOST /openapi/v1/rigging5
Geriggten Charakter animierenAnimationPOST /openapi/v1/animations3
2D-Bild aus Text (empfohlener vorbereitender Schritt vor Bild-zu-3D)Text zu BildPOST /openapi/v1/text-to-image3 / 6 / 9 / 9
2D-Bild optimieren/bearbeiten (empfohlener vorbereitender Schritt vor Bild-zu-3D)Bild zu BildPOST /openapi/v1/image-to-image3 / 6 / 9 / 12
Foto → stilisiertes physisches Produkt (Figur/Lampe/Schlüsselanhänger/Kühlschrankmagnet)KreativlaborPOST /openapi/creative-lab/{product}/v1/prototype dann .../build6 + 30
FDM-Druckbarkeit prüfenDruckbarkeit analysierenPOST /openapi/v1/print/analyze0 (kostenlos)
Nicht-wasserdichte/ degenerierte-Flächen/Löcher-Topologie reparierenDruckbarkeit reparierenPOST /openapi/v1/print/repair10
Mehrfarbiger 3D-DruckMehrfarbiger DruckPOST /openapi/v1/print/multi-color10 (+ Generierung)
3D-Druck eines Modells (weiß)→ Siehe Abschnitt Druck-Pipeline—20
Guthaben prüfenGuthabenGET /openapi/v1/balance0

Schritt 2: Den Workflow ausführen

Wiederverwendbare Skriptvorlage

Verwenden Sie dies als Grundlage für ALLE Workflows. Es lädt den API-Key sicher aus der Umgebung oder .env nur im aktuellen Verzeichnis:

#!/usr/bin/env python3
"""Meshy API-Aufgabenausführer. Handhabt Erstellen → Abfragen → Herunterladen."""
import requests, time, os, sys, re, json
from datetime import datetime

# --- Sicheres Laden des API-Keys ---
def load_api_key():
    """Lädt MESHY_API_KEY aus der Umgebung, dann .env nur im cwd."""
    key = os.environ.get("MESHY_API_KEY", "").strip()
    if key:
        return key
    env_path = os.path.join(os.getcwd(), ".env")
    if os.path.exists(env_path):
        with open(env_path) as f:
            for line in f:
                line = line.strip()
                if line.startswith("MESHY_API_KEY=") and not line.startswith("#"):
                    val = line.split("=", 1)[1].strip().strip('"').strip("'")
                    if val:
                        return val
    return ""

API_KEY = load_api_key()
if not API_KEY:
    sys.exit("FEHLER: MESHY_API_KEY nicht gesetzt. Führen Sie Schritt 0a aus, um ihn zu konfigurieren.")

# Niemals den vollständigen Schlüssel protokollieren – nur die ersten 8 Zeichen zur Rückverfolgbarkeit
print(f"API-Key geladen: {API_KEY[:8]}...")

BASE = "https://api.meshy.ai"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
SESSION = requests.Session()
SESSION.trust_env = False  # System-Proxy-Einstellungen umgehen

def create_task(endpoint, payload):
    resp = SESSION.post(f"{BASE}{endpoint}", headers=HEADERS, json=payload, timeout=30)
    if resp.status_code == 401:
        sys.exit("FEHLER: Ungültiger API-Key (401). Führen Sie Schritt 0a erneut aus.")
    if resp.status_code == 402:
        try:
            bal = SESSION.get(f"{BASE}/openapi/v1/balance", headers=HEADERS, timeout=10)
            balance = bal.json().get("balance", "unbekannt")
            sys.exit(f"FEHLER: Nicht genügend Credits (402). Guthaben: {balance}. Aufladen unter https://www.meshy.ai/pricing")
        except Exception:
            sys.exit("FEHLER: Nicht genügend Credits (402). Guthaben prüfen unter https://www.meshy.ai/pricing")
    if resp.status_code == 429:
        sys.exit("FEHLER: Rate Limited (429). Warten und erneut versuchen.")
    resp.raise_for_status()
    task_id = resp.json()["result"]
    print(f"AUFGABE_ERSTELLT: {task_id}")
    return task_id

def poll_task(endpoint, task_id, timeout=300):
    """Abfragen mit exponentiellem Backoff (5s→30s, feste 15s ab 95%+)."""
    elapsed, delay, max_delay, backoff, finalize_delay, poll_count = 0, 5, 30, 1.5, 15, 0
    while elapsed < timeout:
        poll_count += 1
        resp = SESSION.get(f"{BASE}{endpoint}/{task_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        task = resp.json()
        status = task["status"]
        progress = task.get("progress", 0)
        bar = f"[{'█' * int(progress/5)}{'░' * (20 - int(progress/5))}] {progress}%"
        print(f"  {bar} — {status} ({elapsed}s, Abfrage #{poll_count})", flush=True)
        if status == "SUCCEEDED":
            return task
        if status in ("FAILED", "CANCELED"):
            msg = task.get("task_error", {}).get("message", "Unbekannt")
            sys.exit(f"AUFGABE_{status}: {msg}")
        current_delay = finalize_delay if progress >= 95 else delay
        time.sleep(current_delay)
        elapsed += current_delay
        if progress < 95:
            delay = min(delay * backoff, max_delay)
    sys.exit(f"ZEITÜBERSCHREITUNG nach {timeout}s ({poll_count} Abfragen)")

def download(url, filepath):
    """Lädt eine Datei in ein Projektverzeichnis herunter (innerhalb von cwd/meshy_output/)."""
    os.makedirs(os.path.dirname(filepath), exist_ok=True)
    print(f"Lade herunter {filepath}...", flush=True)
    resp = SESSION.get(url, timeout=300, stream=True)
    resp.raise_for_status()
    with open(filepath, "wb") as f:
        for chunk in resp.iter_content(chunk_size=8192):
            f.write(chunk)
    print(f"HERUNTERGELADEN: {filepath} ({os.path.getsize(filepath)/1024/1024:.1f} MB)")

# --- Dateiorganisations-Hilfsfunktionen ---
OUTPUT_ROOT = os.path.join(os.getcwd(), "meshy_output")
os.makedirs(OUTPUT_ROOT, exist_ok=True)
HISTORY_FILE = os.path.join(OUTPUT_ROOT, "history.json")

def get_project_dir(task_id, prompt="", task_type="model"):
    slug = re.sub(r'[^a-z0-9]+', '-', (prompt or task_type).lower())[:30].strip('-')
    folder = f"{datetime.now().strftime('%Y%m%d_%H%M%S')}_{slug}_{task_id[:8]}"
    project_dir = os.path.join(OUTPUT_ROOT, folder)
    os.makedirs(project_dir, exist_ok=True)
    return project_dir

def record_task(project_dir, task_id, task_type, stage, prompt="", files=None):
    meta_path = os.path.join(project_dir, "metadata.json")
    meta = json.load(open(meta_path)) if os.path.exists(meta_path) else {
        "project_name": prompt or task_type, "folder": os.path.basename(project_dir),
        "root_task_id": task_id, "created_at": datetime.now().isoformat(), "tasks": []
    }
    meta["tasks"].append({"task_id": task_id, "task_type": task_type, "stage": stage,
                          "files": files or [], "created_at": datetime.now().isoformat()})
    meta["updated_at"] = datetime.now().isoformat()
    json.dump(meta, open(meta_path, "w"), indent=2)
    history = json.load(open(HISTORY_FILE)) if os.path.exists(HISTORY_FILE) else {"version": 1, "projects": []}
    folder = os.path.basename(project_dir)
    entry = next((p for p in history["projects"] if p["folder"] == folder), None)
    if entry:
        entry.update({"task_count": len(meta["tasks"]), "updated_at": meta["updated_at"]})
    else:
        history["projects"].append({"folder": folder, "prompt": prompt, "task_type": task_type,
            "root_task_id": task_id, "created_at": meta["created_at"],
            "updated_at": meta["updated_at"], "task_count": len(meta["tasks"])})
    json.dump(history, open(HISTORY_FILE, "w"), indent=2)

def save_thumbnail(project_dir, url):
    path = os.path.join(project_dir, "thumbnail.png")
    if os.path.exists(path): return
    try:
        r = SESSION.get(url, timeout=15)
        r.raise_for_status()
        with open(path, "wb") as f:
            f.write(r.content)
        print(f"THUMBNAIL: {path}")
    except Exception as e:
        print(f"Thumbnail-Fehler: {e}")

Die restlichen Schritte (3D-Druckvorbereitung, Creative Lab, etc.) würden hier folgen – konsultieren Sie die Meshy-API-Dokumentation für Details.


Sicherheitshinweise

  • Verwenden Sie für jede Sitzung einen separaten API-Key mit minimalen Berechtigungen.
  • Überprüfen Sie regelmäßig die Protokolle auf unbefugte Zugriffe.
  • Aktualisieren Sie die Abhängigkeiten (requests, python3) regelmäßig.
  • Löschen Sie nicht benötigte Modelle und .env-Dateien sicher.

Fehlerbehebung

  • 401 Unauthorized: API-Key ungültig oder abgelaufen. Führen Sie Schritt 0a erneut aus.
  • 402 Payment Required: Guthaben aufgebraucht. Laden Sie unter https://www.meshy.ai/pricing auf.
  • 429 Rate Limited: Warten Sie 60 Sekunden und wiederholen Sie den Vorgang.
  • Timeout: Erhöhen Sie das timeout-Argument in poll_task() oder führen Sie das Skript zu einer anderen Zeit aus.

Lizenz

MIT

Verwandte Skills