Token导航 LogoToken导航

Agent Skill · 研究检索

meshy-3d-generation(网格 3d 生成)

meshy-3d-generation 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

meshy-3d-generation 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描有提醒项,按安装量在研究检索类的 73,675 个 Skill 里排第 24,311。

总安装 4,048周安装 167GitHub Stars 14下载 1,323核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:meshy-3d-generation(网格 3d 生成)
来源仓库:https://github.com/meshy-dev/meshy-3d-agent
仓库路径:skills/meshy-3d-generation
安装命令:
npx skills add https://github.com/meshy-dev/meshy-3d-agent --skill meshy-3d-generation
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/meshy-dev/meshy-3d-agent --skill meshy-3d-generation

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于查找、检索和筛选相关信息,适合根据关键词快速定位候选结果。适用于 Codex、Claude、Cursor、Gemini CLI 中需要信息聚合的任务场景。通过 GitHub 安装,具体用法需结合来源仓库 README 进一步核验。安装前应确认权限范围、维护状态及是否触发联网或命令执行。

建议在使用前评估对本地资源和外部 API 的调用影响。

来源仓库内路径:skills/meshy-3d-generation

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/meshy-dev/meshy-3d-agent --skill meshy-3d-gene…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

meshy-3d-generation 怎么安装?

在终端执行 npx skills add https://github.com/meshy-dev/meshy-3d-agent --skill meshy-3d-generation。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

meshy-3d-generation 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

meshy-3d-generation 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

meshy-3d-generation 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

meshy-3d-generation 用的人多吗?

公开数据是累计安装 4,048 次,近一周安装 167 次,下载 1,323 次,GitHub 14 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

meshy-3d-generation 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
meshy-3d-generation

网格 3d 生成 · 本页

4,04814接触敏感数据未明确有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Meshy 3D Generation

Directly communicate with the Meshy AI API to generate 3D assets. This skill handles the complete lifecycle: environment setup, API key detection, task creation, polling, downloading, and chaining multi-step pipelines.

For full endpoint reference (all parameters, response schemas, error codes), read reference.md.


IMPORTANT: 3D Printing → Use meshy-3d-printing Skill

If the user's request involves 3D printing (keywords: print, 3d print, slicer, slice, bambu, orca, prusa, cura, multicolor, 3mf, figurine, miniature, statue, physical model), use the meshy-3d-printing skill instead of this one for the entire workflow. The printing skill handles generation with correct print-optimized parameters (e.g. target_formats with "3mf" for multicolor), slicer detection, coordinate conversion, and slicer launch — all in one pipeline.

This skill's create_task/poll_task/download template functions are reused by the printing skill, but the workflow orchestration (what to generate, which formats, what to do after) must come from the printing skill when printing is involved.

Do NOT generate a model with this skill and then hand off to the printing skill — the printing skill needs to control parameters from the start (e.g. target_formats, should_texture).


IMPORTANT: First-Use Session Notice

When this skill is first activated in a session, inform the user:

All generated files will be saved to meshy_output/ in the current working directory. Each project gets its own folder ({YYYYMMDD_HHmmss}_{prompt}_{id}/) with model files, textures, thumbnails, and metadata. History is tracked in meshy_output/history.json.

This only needs to be said once per session, at the beginning.

IMPORTANT: File Organization

All downloaded files MUST go into a structured meshy_output/ directory in the current working directory. Do NOT scatter files randomly.

  • Each project gets its own folder: meshy_output/{YYYYMMDD_HHmmss}_{prompt_slug}_{task_id_prefix}/
  • For chained tasks (preview → refine → rig), reuse the same project_dir
  • Track tasks in metadata.json per project, and global history.json
  • Auto-download thumbnails alongside models

The Reusable Script Template below includes get_project_dir(), record_task(), and save_thumbnail() helpers.


IMPORTANT: Shell Command Rules

Use only standard POSIX tools in shell commands. Do NOT use rg (ripgrep), fd, or other non-standard CLI tools — they may not be installed. Use these standard alternatives instead:

Do NOT useUse instead
rggrep
fdfind
batcat
exa / ezals

IMPORTANT: Run Long Tasks Properly

Meshy generation tasks take 1–5 minutes. When running Python scripts that poll for completion:

  • Write the entire create → poll → download flow as ONE Python script and execute it in a single Bash call. Do NOT split into multiple commands. This keeps the API key, task IDs, and session in one process context.
  • Use python3 -u script.py (unbuffered) so progress output is visible in real time.
  • Be patient with long-running scripts — do NOT interrupt or kill them prematurely. Tasks at 99% for 30–120s is normal finalization, not a failure.

Step 0: Environment Detection (ALWAYS RUN FIRST)

Before any API call, detect whether the environment is ready:

echo "=== Meshy API Key Detection ==="

# 1. Check current env var
if [ -n "$MESHY_API_KEY" ]; then
  echo "ENV_VAR: FOUND (${MESHY_API_KEY:0:8}...)"
else
  echo "ENV_VAR: NOT_FOUND"
fi

# 2. Check .env files in workspace
for f in .env .env.local; do
  if [ -f "$f" ] && grep -q "MESHY_API_KEY" "$f" 2>/dev/null; then
    echo "DOTENV($f): FOUND"
    export $(grep "MESHY_API_KEY" "$f" | head -1)
  fi
done

# 3. Check shell profiles
for f in ~/.zshrc ~/.bashrc ~/.bash_profile ~/.profile; do
  if [ -f "$f" ] && grep -q "MESHY_API_KEY" "$f" 2>/dev/null; then
    echo "SHELL_PROFILE: FOUND in $f"
  fi
done

# 4. Final status
if [ -n "$MESHY_API_KEY" ]; then
  echo "READY: key=${MESHY_API_KEY:0:12}..."
else
  echo "READY: NO_KEY_FOUND"
fi

# 5. Python requests check
python3 -c "import requests; print('PYTHON_REQUESTS: OK')" 2>/dev/null || echo "PYTHON_REQUESTS: MISSING (run: pip install requests)"

echo "=== Detection Complete ==="

Decision After Detection

  • Key found → Proceed to Step 1.
  • Key NOT found → Go to Step 0a.
  • Python requests missing → Run pip install requests.

Step 0a: API Key Setup (Only If No Key Found)

Tell the user:

To use the Meshy API, you need an API key. Here's how to get one: 1. Go to https://www.meshy.ai/settings/api 2. Click "Create API Key", give it a name, and copy the key (it starts with msy_) 3. The key is only shown once — save it somewhere safe Note: API access requires a Pro plan or above. Free-tier accounts cannot create API keys. If you see "Please upgrade to a premium plan to create API tasks", you'll need to upgrade at https://www.meshy.ai/pricing first.

Once the user provides their key, set it and verify:

macOS (zsh):

export MESHY_API_KEY="msy_PASTE_KEY_HERE"

# Verify
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 "Key valid. $BALANCE"
  echo 'export MESHY_API_KEY="msy_PASTE_KEY_HERE"' >> ~/.zshrc
  echo "Persisted to ~/.zshrc"
else
  echo "Key invalid (HTTP $STATUS). Check the key and try again."
fi

Linux (bash):

export MESHY_API_KEY="msy_PASTE_KEY_HERE"

# Verify (same as above), then persist to ~/.bashrc
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 "Key valid. $BALANCE"
  echo 'export MESHY_API_KEY="msy_PASTE_KEY_HERE"' >> ~/.bashrc
  echo "Persisted to ~/.bashrc"
else
  echo "Key invalid (HTTP $STATUS). Check the key and try again."
fi

Windows (PowerShell):

$env:MESHY_API_KEY = "msy_PASTE_KEY_HERE"

# Verify
$status = (Invoke-WebRequest -Uri "https://api.meshy.ai/openapi/v1/balance" -Headers @{Authorization="Bearer $env:MESHY_API_KEY"} -UseBasicParsing).StatusCode
if ($status -eq 200) {
    Write-Host "Key valid."
    # Persist permanently
    [System.Environment]::SetEnvironmentVariable("MESHY_API_KEY", $env:MESHY_API_KEY, "User")
    Write-Host "Persisted to user environment variables. Restart terminal to take effect."
} else {
    Write-Host "Key invalid (HTTP $status). Check the key and try again."
}

Alternative (all platforms): Create a .env file in your project root:

MESHY_API_KEY=msy_PASTE_KEY_HERE

Step 1: Confirm Plan With User Before Spending Credits

CRITICAL: Before creating any task, present the user with a summary and get confirmation:

I'll generate a 3D model of "<prompt>" using the following plan:

  1. Preview (mesh generation) — 5-20 credits (meshy-6/lowpoly: 20, others: 5)
  2. Refine (texturing with PBR) — 10 credits
  3. Download as .glb

  Total cost: 30 credits
  Current balance: <N> credits

  Shall I proceed?

For multi-step pipelines (e.g., text-to-3d → rig → animate), present the FULL pipeline cost upfront:

StepAPICredits
PreviewText to 3D20
RefineText to 3D10
RigAuto-Rigging5
Total35
Note: Rigging automatically includes basic walking + running animations for free (in result.basic_animations). Only add Animate (3 credits) if the user needs a custom animation beyond walking/running.

Wait for user confirmation before executing.

Intent → API Mapping

User wants to...APIEndpointCredits
3D model from textText to 3DPOST /openapi/v2/text-to-3d5–20 (preview) + 10 (refine)
3D model from one imageImage to 3DPOST /openapi/v1/image-to-3d5–30
3D model from multiple imagesMulti-Image to 3DPOST /openapi/v1/multi-image-to-3d5–30
New textures on existing modelRetexturePOST /openapi/v1/retexture10
Change mesh format/topologyRemeshPOST /openapi/v1/remesh5
Add skeleton to characterAuto-RiggingPOST /openapi/v1/rigging5 (includes walking + running)
Animate a rigged character (custom)AnimationPOST /openapi/v1/animations3
2D image from textText to ImagePOST /openapi/v1/text-to-image3–9
Transform a 2D imageImage to ImagePOST /openapi/v1/image-to-image3–9
Check credit balanceBalanceGET /openapi/v1/balance0
Multi-color 3D printMulti-Color PrintPOST /openapi/v1/print/multi-color10

Step 2: Execute the Workflow

CRITICAL: Async Task Model

All generation endpoints return {"result": "<task_id>"}, NOT the model. You MUST poll.

NEVER read model_urls from the POST response.

Reusable Script Template

Use this as the base for ALL generation workflows:

#!/usr/bin/env python3
"""Meshy API task runner. Handles create → poll → download."""
import requests, time, os, sys

API_KEY = os.environ.get("MESHY_API_KEY", "")
if not API_KEY:
    sys.exit("ERROR: MESHY_API_KEY not set")

BASE = "https://api.meshy.ai"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
SESSION = requests.Session()
SESSION.trust_env = False  # bypass any system proxy settings

def create_task(endpoint, payload):
    resp = SESSION.post(f"{BASE}{endpoint}", headers=HEADERS, json=payload, timeout=30)
    if resp.status_code == 401:
        sys.exit("ERROR: Invalid API key (401)")
    if resp.status_code == 402:
        try:
            bal = SESSION.get(f"{BASE}/openapi/v1/balance", headers=HEADERS, timeout=10)
            balance = bal.json().get("balance", "unknown")
            sys.exit(f"ERROR: Insufficient credits (402). Current balance: {balance}. Top up at https://www.meshy.ai/pricing")
        except Exception:
            sys.exit("ERROR: Insufficient credits (402). Check balance at https://www.meshy.ai/pricing")
    if resp.status_code == 429:
        sys.exit("ERROR: Rate limited (429). Wait and retry.")
    resp.raise_for_status()
    task_id = resp.json()["result"]
    print(f"TASK_CREATED: {task_id}")
    return task_id

def poll_task(endpoint, task_id, timeout=300):
    """Poll task with exponential backoff (5s→30s, fixed 15s at 95%+)."""
    elapsed = 0
    delay = 5            # Initial delay: 5s
    max_delay = 30       # Cap: 30s
    backoff = 1.5        # Backoff multiplier
    finalize_delay = 15  # Fixed delay during finalization (95%+)
    poll_count = 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)
        filled = int(progress / 5)
        bar = f"[{'█' * filled}{'░' * (20 - filled)}] {progress}%"
        print(f"  {bar} — {status} ({elapsed}s, poll #{poll_count})", flush=True)
        if status == "SUCCEEDED":
            return task
        if status in ("FAILED", "CANCELED"):
            msg = task.get("task_error", {}).get("message", "Unknown")
            sys.exit(f"TASK_{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"TIMEOUT after {timeout}s ({poll_count} polls)")

def download(url, filepath):
    """Download a file to the given path (within a project directory)."""
    os.makedirs(os.path.dirname(filepath), exist_ok=True)
    print(f"Downloading {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)
    size_mb = os.path.getsize(filepath) / (1024 * 1024)
    print(f"DOWNLOADED: {filepath} ({size_mb:.1f} MB)")

# --- File organization helpers (see File Organization section above) ---
import re, json
from datetime import datetime

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"):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    slug = re.sub(r'[^a-z0-9]+', '-', (prompt or task_type).lower())[:30].strip('-')
    folder = f"{timestamp}_{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")
    if os.path.exists(meta_path):
        meta = json.load(open(meta_path))
    else:
        meta = {"project_name": prompt or task_type, "folder": os.path.basename(project_dir),
                "root_task_id": task_id, "created_at": datetime.now().isoformat(),
                "updated_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)
    # Update global history
    if os.path.exists(HISTORY_FILE):
        history = json.load(open(HISTORY_FILE))
    else:
        history = {"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["task_count"] = len(meta["tasks"])
        entry["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()
        open(path, "wb").write(r.content)
    except Exception: pass

Text to 3D (Preview + Refine)

Append this to the template above and run as one script:

PROMPT = "USER_PROMPT"  # max 600 chars

# --- Preview ---
preview_id = create_task("/openapi/v2/text-to-3d", {
    "mode": "preview",
    "prompt": PROMPT,
    "ai_model": "latest",
    # "model_type": "standard",    # "standard" | "lowpoly"
    # "topology": "triangle",      # "triangle" | "quad"
    # "target_polycount": 30000,   # 100–300000
    # "should_remesh": False,
    # "symmetry_mode": "auto",     # "auto" | "on" | "off"
    # "pose_mode": "t-pose",       # "" | "a-pose" | "t-pose" (use "t-pose" if rigging/animating later)
})

task = poll_task("/openapi/v2/text-to-3d", preview_id)
project_dir = get_project_dir(preview_id, prompt=PROMPT)
download(task["model_urls"]["glb"], os.path.join(project_dir, "preview.glb"))
record_task(project_dir, preview_id, "text-to-3d", "preview", prompt=PROMPT, files=["preview.glb"])
if task.get("thumbnail_url"):
    save_thumbnail(project_dir, task["thumbnail_url"])

print(f"\nPREVIEW COMPLETE")
print(f"  Task ID: {preview_id}")
print(f"  Project: {project_dir}")
print(f"  Formats: {', '.join(task['model_urls'].keys())}")

# --- Refine ---
refine_id = create_task("/openapi/v2/text-to-3d", {
    "mode": "refine",
    "preview_task_id": preview_id,
    "enable_pbr": True,
    "ai_model": "latest",
    # "texture_prompt": "",
    # "remove_lighting": True,     # Remove baked lighting (meshy-6/latest only, default True)
})

task = poll_task("/openapi/v2/text-to-3d", refine_id)
download(task["model_urls"]["glb"], os.path.join(project_dir, "refined.glb"))
record_task(project_dir, refine_id, "text-to-3d", "refined", prompt=PROMPT, files=["refined.glb"])

print(f"\nREFINE COMPLETE")
print(f"  Task ID: {refine_id}")
print(f"  Project: {project_dir}")
print(f"  Formats: {', '.join(task['model_urls'].keys())}")
Refine compatibility: All models (meshy-5, meshy-6, latest) support both preview and refine. The preview and refine ai_model should match — mismatched models may return 400 (model mismatch).

Image to 3D

import base64

# For local files, convert to data URI:
# with open("photo.jpg", "rb") as f:
#     image_url = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode()

task_id = create_task("/openapi/v1/image-to-3d", {
    "image_url": "IMAGE_URL_OR_DATA_URI",
    "should_texture": True,
    "enable_pbr": True,            # Default is False; set True for metallic/roughness/normal maps
    "ai_model": "latest",
    # "image_enhancement": True,   # Optimize input image (meshy-6/latest only, default True)
    # "remove_lighting": True,     # Remove baked lighting from texture (meshy-6/latest only, default True)
})

task = poll_task("/openapi/v1/image-to-3d", task_id)
download(task["model_urls"]["glb"], "model.glb")

Multi-Image to 3D

task_id = create_task("/openapi/v1/multi-image-to-3d", {
    "image_urls": ["URL_1", "URL_2", "URL_3"],  # 1–4 images
    "should_texture": True,
    "enable_pbr": True,            # Default is False; set True for metallic/roughness/normal maps
    "ai_model": "latest",
    # "image_enhancement": True,   # Optimize input images (meshy-6/latest only, default True)
    # "remove_lighting": True,     # Remove baked lighting from texture (meshy-6/latest only, default True)
})
task = poll_task("/openapi/v1/multi-image-to-3d", task_id)
download(task["model_urls"]["glb"], "model.glb")

Retexture

IMPORTANT: Before calling, ask the user to provide a texture style:

  • Text prompt: e.g. "rusty metal", "cartoon style" → text_style_prompt
  • Reference image: URL of style image → image_style_url One of these is required. If both provided, image_style_url takes precedence.
# REQUIRED: ask user for text_style_prompt OR image_style_url before calling
task_id = create_task("/openapi/v1/retexture", {
    "input_task_id": "PREVIOUS_TASK_ID",      # or "model_url": "URL"
    "text_style_prompt": "wooden texture",     # REQUIRED if no image_style_url
    # "image_style_url": "URL",               # REQUIRED if no text_style_prompt (takes precedence)
    "enable_pbr": True,
    # "remove_lighting": True,     # Remove baked lighting (meshy-6/latest only, default True)
    # "target_formats": ["glb", "3mf"],  # 3mf must be explicitly requested
    # "auto_size": True,           # AI auto-estimate real-world height
})
task = poll_task("/openapi/v1/retexture", task_id)
download(task["model_urls"]["glb"], "retextured.glb")

Remesh / Format Conversion

task_id = create_task("/openapi/v1/remesh", {
    "input_task_id": "TASK_ID",
    "target_formats": ["glb", "fbx", "obj"],
    "topology": "quad",
    "target_polycount": 10000,
})
task = poll_task("/openapi/v1/remesh", task_id)
for fmt, url in task["model_urls"].items():
    download(url, f"remeshed.{fmt}")

Auto-Rigging + Animation

IMPORTANT: When the user explicitly asks to rig or animate, the generation step (text-to-3d / image-to-3d) MUST use pose_mode: "t-pose" for best rigging results. If the model was already generated without t-pose, recommend regenerating with pose_mode: "t-pose" first.

Before rigging, verify the model's polygon count is under 300,000. The script should auto-check and block if exceeded:

# Pre-rig check: verify face count (MUST be ≤ 300,000)
source_endpoint = "/openapi/v2/text-to-3d"  # adjust to match the source task's endpoint
source_task_id = "TASK_ID"
check_resp = SESSION.get(f"{BASE}{source_endpoint}/{source_task_id}", headers=HEADERS, timeout=30)
check_resp.raise_for_status()
source = check_resp.json()
face_count = source.get("face_count", 0)
if face_count > 300000:
    print(f"ERROR: Model has {face_count:,} faces (limit: 300,000). Remesh first:")
    print(f"  create_task('/openapi/v1/remesh', {{'input_task_id': '{source_task_id}', 'target_polycount': 100000}})")
    sys.exit("Rigging blocked: face count too high")
# Rig (humanoid bipedal characters only, polycount must be ≤ 300,000)
rig_id = create_task("/openapi/v1/rigging", {
    "input_task_id": "TASK_ID",
    "height_meters": 1.7,
})
rig_task = poll_task("/openapi/v1/rigging", rig_id)
download(rig_task["result"]["rigged_character_glb_url"], "rigged.glb")

# Rigging automatically includes basic walking + running animations — download them:
download(rig_task["result"]["basic_animations"]["walking_glb_url"], "walking.glb")
download(rig_task["result"]["basic_animations"]["running_glb_url"], "running.glb")

# Only call meshy_animate if you need a CUSTOM animation beyond walking/running:
# anim_id = create_task("/openapi/v1/animations", {
#     "rig_task_id": rig_id,
#     "action_id": 1,  # from Animation Library
# })
# anim_task = poll_task("/openapi/v1/animations", anim_id)
# download(anim_task["result"]["animation_glb_url"], "animated.glb")

Text to Image / Image to Image

# Text to Image
task_id = create_task("/openapi/v1/text-to-image", {
    "ai_model": "nano-banana-pro",
    "prompt": "a futuristic spaceship",
})
task = poll_task("/openapi/v1/text-to-image", task_id)
# Result: task["image_url"]

# Image to Image
task_id = create_task("/openapi/v1/image-to-image", {
    "ai_model": "nano-banana-pro",
    "prompt": "make it look cyberpunk",
    "reference_image_urls": ["URL"],
})
task = poll_task("/openapi/v1/image-to-image", task_id)

Step 3: Report Results

After task succeeds, report:

  1. Downloaded file paths and sizes
  2. Task IDs (for follow-up operations like refine, rig, retexture)
  3. Available formats (list model_urls keys — may include glb, fbx, obj, usdz, 3mf)
  4. Thumbnail URL if present
  5. Credits consumed and remaining balance (run balance check)
  6. Suggested next steps:

- Preview done → "Want to refine (add textures)?" - Model done → "Want to rig this character for animation?" - Rigged → "Want to apply an animation?" - Any model → "Want to remesh / export to another format?" - Any textured model → "Want to 3D print this? Multicolor printing is available!" (requires meshy-3d-printing skill) - Any model → "Want to 3D print this model?" (requires meshy-3d-printing skill)


Error Recovery

HTTP StatusMeaningAction
401Invalid API keyRe-run Step 0; ask user to check key
402Insufficient creditsAuto-query balance (GET /openapi/v1/balance), show current balance, link https://www.meshy.ai/pricing
422Cannot processExplain limitation (e.g., non-humanoid for rigging)
429Rate limitedAuto-retry after 5s (max 3 times)
5xxServer errorAuto-retry after 10s (once)

Task FAILED messages:

  • "The server is busy..." → retry with backoff (5s, 10s, 20s)
  • "Internal server error." → simplify prompt, retry once

Known Behaviors & Constraints

  • 99% progress stall: Tasks commonly sit at 99% for 30–120s during finalization. This is normal. Do NOT kill or restart.
  • CORS: API blocks browser requests. Always server-side.
  • Asset retention: Files deleted after 3 days (non-Enterprise). Download immediately.
  • PBR maps: Must set enable_pbr: true explicitly.
  • Format availability: Check keys in model_urls before downloading — not all formats are always present. 3MF is available from the Multi-Color Print API.
  • Download format: ALWAYS ask the user which format they need before downloading. Recommend: GLB (viewing), OBJ (white model printing), 3MF (multicolor printing), FBX (game engines), USDZ (AR). Do NOT download all formats.
  • 3MF format: 3MF is NOT included in default output of generation endpoints. To get 3MF from generate/remesh/retexture, pass "3mf" in target_formats. For multicolor 3D printing, the Multi-Color Print API outputs 3MF directly — no need to request it from generate/refine.
  • Timestamps: All API timestamps are Unix epoch milliseconds.
  • Large files: Refined models can be 50–200 MB. Use streaming downloads with timeouts.

Execution Checklist

  • Ran environment detection (Step 0)
  • API key present and verified
  • Presented cost summary and got user confirmation
  • Wrote complete workflow as single Python script
  • Ran script with python3 -u for unbuffered output
  • Reported file paths, formats, task IDs, and balance
  • Suggested next steps

Additional Resources

For the complete API endpoint reference including all parameters, response schemas, deprecated fields, and detailed error codes, read reference.md.

平台分布

Codex

36.3%
按下载量换算480

Claude

29.4%
按下载量换算389

Cursor

15.97%
按下载量换算211

Gemini CLI

8.9%
按下载量换算118

安全审计

Gen Agent Trust Hub

可疑

Socket

通过

Snyk

可疑

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills