MCP Server

API Reference →

Drive Pinwing from any MCP client — setup, the 37-tool reference, and prompt examples

Contents
OverviewQuick start (hosted)Local install (stdio)Authentication and keysToolsRender settingsExamplesHTTP transport (self-hosting)Troubleshooting

Overview

The MCP server is a thin wrapper over the Pinwing /v1 REST API — it forwards your bearer token and exposes 37 tools covering the full pipeline: import/upload models, quote costs, create single and batch renders, poll status, manage overlays/textures/ environments, and download results (streamed or via presigned direct-from-storage URLs).

It runs in two transports:

Everything the tools can do is scoped by your API key. The key implies the workspace — a personal key operates on your personal library and bills you; a workspace-bound key (editor role or above) operates on that team workspace and bills its owner. There is no workspace parameter on any tool.

Quick start (hosted)

  1. In Studio, open the account menu → API → Keys, and create a key. It looks like pinwing_sk_... — copy it now; it is shown once.
  2. Add the server to your MCP client. For a streamableHttp-capable client (e.g. Claude Code, Claude Desktop):
{
  "mcpServers": {
    "pinwing": {
      "type": "streamableHttp",
      "url": "https://mcp.pinwing.ai/",
      "headers": {
        "Authorization": "Bearer pinwing_sk_..."
      }
    }
  }
}
  1. Restart the client. Ask it something like "Import the GLB at <url> and render a 4K turntable on a white background" — the agent handles the tool calls.

The hosted server stores no key — each request carries its own Authorization header, so one endpoint serves every user. mcp.pinwing.ai is the canonical endpoint; the original mcp.dx.gl host remains fully supported — same server, same keys.

Local install (stdio)

Use the stdio transport when you want the agent to upload models straight from local file paths (upload_model with filePath), which the hosted transport can't reach.

git clone https://github.com/harrimy/dxgl
cd dxgl/api/mcp
npm install

Configure your client to launch it. Claude Desktop — edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "pinwing": {
      "command": "node",
      "args": ["/absolute/path/to/dxgl/api/mcp/index.js"],
      "env": {
        "DXGL_API_KEY": "pinwing_sk_..."
      }
    }
  }
}
Variable Required Default Description
DXGL_API_KEY Yes — Your pinwing_sk_... bearer token
DXGL_API_BASE No https://api.dx.gl/v1 API base URL

The stdio server sets allowLocalFiles: true, enabling upload_model to read a GLB from a path on the same machine. The hosted transport disables this for safety.

Authentication and keys

Every tool call forwards your key as Authorization: Bearer pinwing_sk_... to the REST API, which validates it and applies scope and role checks. Mint and revoke keys in Studio → account menu → API → Keys.

Tools

37 tools, grouped.

Models

Tool Description
ingest_model Import a 3D model from a URL (GLB only), optionally starting a render immediately
upload_model Upload a GLB from bytes — local filePath (stdio) or base64; staged presigned-PUT under the hood
list_models List models — tag filter, updatedSince delta polling, cursor pagination
get_model Get model details and render history
update_model Update a model's title, SKU, and/or tags
archive_model / unarchive_model Hide / restore a model in the library
delete_model Soft-delete a model
check_hash Dedup pre-flight — does this SHA-256 already exist?
get_model_file API-streamed download URL for a model's original GLB
get_model_file_url Presigned direct-from-bucket GLB URL — no auth header needed

Renders

Tool Description
create_render Create a video or dataset render (costs credits; idempotent per call)
create_batch_renders Create multiple renders atomically (max 100)
list_renders List render jobs — status/model filters, updatedSince delta polling, cursor pagination
get_render Check render status (poll until done)
cancel_render Cancel a still-queued render and refund its credits
dismiss_render Acknowledge an errored render (no refund)
delete_render Permanently delete a terminal render and its stored assets
quote Estimate credit cost before committing

Billing

Tool Description
get_account Check credit balance (paid / free / total) + token scopes and workspace binding
list_products List purchasable credit packs (name, credits, price)
get_purchases Credit ledger — purchases, render spends, refunds, grants

Downloads — each returns a URL. API-streamed URLs need your Authorization header; the presigned tools don't.

Tool Description
download_render API-streamed video URL for a completed render (quality=web for the light variant)
get_download_url Presigned direct-from-bucket URL for any render asset (video/web/poster/full_poster/thumb/dataset)
get_poster Poster image (PNG) URL (quality=full for full-res)
get_thumb Thumbnail loop video (MP4) URL
download_bundle ZIP of all assets for a completed render
download_dataset ZIP of a dataset render's multi-view images
get_hls HLS streaming status + playback URLs

For large files, prefer the presigned tools: get_download_url (render assets) and get_model_file_url (source GLB) return short-lived URLs that download directly from storage with no Authorization header — ideal for ProRes videos and dataset ZIPs that run to tens of GB, and for handing a download to another system.

Overlays

Tool Description
upload_overlay Upload a PNG/JPEG/WebP as a reusable asset (≤8 MB via MCP) — layer background/foreground/decal/texture
list_overlays List overlay assets (yours + system) — ids feed bgImageId, decals[].imageAssetId, materialEdits.<name>.mapAssetId
delete_overlay Permanently delete an overlay asset you own

Textures and environments

Tool Description
upload_texture Upload a diffuse-replacement texture — id feeds materialEdits.<name>.mapAssetId (≤8 MB via MCP; content-sha deduped)
upload_env Upload a custom HDRI as the pre-encoded gainmap triple — id feeds envId
list_assets List the workspace's texture or environment assets
delete_asset Delete an owned texture/environment asset
resolve_asset_sha Content-sha pre-flight — reuse an existing asset instead of re-uploading

Render settings

Render settings are passed to create_render / create_batch_renders / quote. The schema mirrors the server validator 1:1, so anything the Studio UI can author is reachable.

Video quality tiers

JSON value Display label Resolution Credits/sec Output
share Standard 960×540 1 MP4
standard (server default) HD 1920×1080 4 MP4
4k 4K 3840×2160 16 MP4
pro ProRes 4444 3840×2160 64 ProRes 4444 .mov (alpha)

The JSON enum values are frozen for API stability; the display labels were renamed and no longer match one-to-one. Pass the JSON value as quality.

When quality is omitted the server defaults to standard (HD, 4 credits/sec) — a bare 6-second render bills 24 credits, not 6. Always pass quality explicitly.

Dataset tiers

Tier Views Resolution Credits
100x800 100 800×800 40
196x1024 196 1024×1024 160
400x2048 400 2048×2048 640

Camera paths

turntable (default), hero-spin, showcase, zoom-orbit, reveal, keyframes — passed as the effect field.

Full surface

All optional; see each tool's input schema for exact ranges:

Examples

"Import the GLB at https://example.com/chair.glb and render a 4K turntable video with a white background."

The agent calls ingest_model with the URL, create_render with { quality: "4k", bgColor: "#ffffff" }, polls get_render until done, and returns the URL from download_render.

"How much would it cost to render 50 models at 4K?"

The agent calls quote with 50 entries of { quality: "4k" } and reports 4,800 credits (fifty 6-second 4K turntables at 16 credits/second).

"Render the chair facing the label, leaning slightly toward the camera, with the packaging hidden."

The agent calls create_render with:

{ "quality": "share", "panX": 35, "tiltX": -12, "zoom": 1.3, "hiddenMeshNames": ["Packaging"] }

panX/tiltX/rollZ rotate the model (yaw first, then pitch, then roll); rotateY instead offsets where the camera's orbit starts. hiddenMeshNames needs exact case-sensitive mesh names from the GLB — unknown names silently hide nothing.

HTTP transport (self-hosting)

The hosted mcp.pinwing.ai endpoint is the same code you can run yourself. Serve multiple users without local installs by running the HTTP transport:

cd api/mcp
node http.js
Variable Required Default Description
DXGL_API_BASE No https://api.dx.gl/v1 API base URL
PORT No 3300 HTTP server port

DXGL_API_KEY is not set on the server — each client sends its own key on every request. The endpoint is Streamable HTTP (stateless: a fresh MCP session per request, bound to the caller's key). A legacy SSE transport is also served at GET /sse + POST /messages for older clients. Health check: GET /health.

Troubleshooting