Skip to main content
Glama

chuk-mcp-stage

3D Scene & Camera MCP Server - The director layer between physics simulation and motion rendering

Python MCP Async

🌐 Quick Install: uvx stage.chukai.io/mcp

chuk-mcp-stage is the orchestration layer that bridges:

  • chuk-mcp-physics (Rapier simulations) → Scene animations

  • chuk-motion / Remotion (video rendering) → Export targets

It's the "director + set designer" that defines what's in the 3D world, where the camera goes, and how physics drives motion.


šŸŽÆ What This Does

Core capabilities:

  1. Scene Graph - Define 3D worlds (objects, materials, lighting)

  2. Camera Paths - Cinematography (orbit, chase, dolly, static shots)

  3. Physics Bridge - Bind scene objects to physics bodies (uses public Rapier service by default)

  4. Animation Baking - Convert physics simulations → keyframes

  5. Export - Generate R3F components, Remotion projects, glTF

The full pipeline:

Physics Simulation → Stage → Motion/Video
(chuk-mcp-physics) → (chuk-mcp-stage) → (chuk-motion/Remotion)

Related MCP server: Rive MCP Server

šŸš€ Quick Start

Installation

Option 1: Install from public URL (Recommended)

# Install directly from public URL with uvx
uvx stage.chukai.io/mcp

Option 2: Install from PyPI

pip install chuk-mcp-stage

Option 3: Install from source

cd chuk-mcp-stage
pip install -e .

Physics ready out-of-the-box! Uses the public Rapier service at https://rapier.chukai.io by default. No additional setup required for physics simulations.

Run the Server

# STDIO mode (default - for MCP clients like Claude Desktop)
uv run chuk-mcp-stage

# HTTP mode (REST API on port 8000)
uv run chuk-mcp-stage http

# Streamable mode (Server-Sent Events for streaming responses)
uv run chuk-mcp-stage streamable

Transport modes:

  • stdio: Standard MCP protocol via stdin/stdout (default for Claude Desktop)

  • http: HTTP REST API server on port 8000 (used by chuk-mcp-r3f-preview)

  • streamable: SSE (Server-Sent Events) transport for streaming responses

šŸ“– Complete Transport Modes Guide - Detailed documentation, examples, and troubleshooting

Configure in Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

Option 1: Using public URL (Recommended)

{
  "mcpServers": {
    "stage": {
      "command": "uvx",
      "args": ["stage.chukai.io/mcp"],
      "env": {
        "RAPIER_SERVICE_URL": "https://rapier.chukai.io"
      }
    }
  }
}

Option 2: Using local installation

{
  "mcpServers": {
    "stage": {
      "command": "chuk-mcp-stage",
      "env": {
        "RAPIER_SERVICE_URL": "https://rapier.chukai.io"
      }
    }
  }
}

Physics Integration Configuration

chuk-mcp-stage integrates with physics simulations via chuk-mcp-physics and the Rapier physics engine.

Three Integration Methods:

  1. Direct Rapier HTTP (Default) - Fastest for simulations

    • Directly calls Rapier service HTTP API

    • Used by stage_bake_simulation tool

    • Defaults to public service: https://rapier.chukai.io

  2. Via MCP Tools - Most flexible

    • Use chuk-mcp-physics MCP server tools

    • Supports both analytic calculations and Rapier simulations

    • Requires chuk-mcp-physics server running

  3. Hybrid - Best of both worlds

    • Use MCP tools for simulation creation/setup

    • Use direct HTTP for baking trajectories

Environment Variables:

# Rapier service URL (default: https://rapier.chukai.io)
RAPIER_SERVICE_URL=https://rapier.chukai.io  # Public service
# RAPIER_SERVICE_URL=http://localhost:9000   # Local development

# Rapier timeout in seconds (default: 30.0)
RAPIER_TIMEOUT=30.0

# Physics provider type (default: auto)
PHYSICS_PROVIDER=auto  # or 'rapier', 'mcp'

Claude Desktop with Custom Rapier Service:

{
  "mcpServers": {
    "stage": {
      "command": "chuk-mcp-stage",
      "env": {
        "RAPIER_SERVICE_URL": "http://localhost:9000",
        "RAPIER_TIMEOUT": "60.0"
      }
    },
    "physics": {
      "command": "uvx",
      "args": ["chuk-mcp-physics"],
      "env": {
        "RAPIER_SERVICE_URL": "http://localhost:9000"
      }
    }
  }
}

Public Rapier Service:

  • URL: https://rapier.chukai.io

  • No authentication required

  • Rate limits may apply

  • Perfect for prototyping and demos

Local Rapier Service:

# Run locally with Docker
docker run -p 9000:9000 chuk-rapier-service

# Or from source
cd rapier-service && cargo run --release

See chuk-mcp-physics README for complete physics integration guide.

What's New in chuk-mcp-physics v0.3.1:

  • 52 physics tools (expanded from 27) - Now covers ~50% of common physics use cases

  • Rotational dynamics: Torque, moment of inertia, angular momentum calculations

  • Springs & oscillations: Simple harmonic motion, damped oscillations, pendulums

  • Circular motion: Orbital mechanics, centripetal force, escape velocity

  • Advanced collisions: 3D elastic/inelastic collisions with coefficient of restitution

  • Conservation laws: Energy and momentum verification for simulations

  • Fluid dynamics: Drag, buoyancy, terminal velocity, underwater motion


Google Drive OAuth Storage (HTTP Mode)

Store your scenes in Google Drive with OAuth 2.1 authentication for secure, persistent, user-owned storage!

When running in HTTP mode, chuk-mcp-stage supports Google Drive OAuth integration. Users authenticate via their browser, and scenes are stored in their own Google Drive under /CHUK/stage/.

Benefits:

  • āœ… Secure OAuth 2.1 - Industry-standard authentication with PKCE

  • āœ… User Owns Data - Scenes stored in user's Google Drive, not your infrastructure

  • āœ… Auto Token Refresh - Seamless authentication with automatic refresh

  • āœ… Cross-Device Access - Access scenes from any device with Drive

  • āœ… Built-in Sharing - Share scenes using Google Drive's native sharing

  • āœ… Natural Discoverability - View/edit scene files directly in Drive UI

  • āœ… No Infrastructure Cost - Zero storage costs for the provider

Setup Steps

1. Create Google Cloud Project:

  • Go to https://console.cloud.google.com/

  • Create new project (or select existing)

  • Enable Google Drive API

  • Go to OAuth consent screen:

    • User Type: External

    • Add your email as test user

  • Go to Credentials → Create OAuth 2.0 Client ID:

    • Application type: Web application

    • Authorized redirect URIs: http://localhost:8000/oauth/callback

  • Copy Client ID and Client Secret

2. Install with Google Drive Support:

pip install "chuk-mcp-stage[google_drive]"

3. Configure Environment:

# Copy example environment file
cp .env.example .env

# Edit .env and add your Google credentials:
# GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
# GOOGLE_CLIENT_SECRET=your-client-secret

4. Verify OAuth Integration (Optional but Recommended):

# Verify that OAuth setup works
python examples/verify_google_drive_oauth.py

This will verify:

  • OAuth provider initializes correctly

  • Credentials are valid

  • OAuth endpoints can be registered

  • Ready for Google Drive integration

5. Run Server in HTTP Mode:

# Load from .env file
uv run chuk-mcp-stage http

# Or set environment variables directly
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
uv run chuk-mcp-stage http

6. Authorize Access:

When Claude Desktop (or any MCP client) connects:

  1. OAuth flow automatically initiates

  2. Browser opens for Google authorization

  3. User grants access to Google Drive

  4. Tokens securely stored and auto-refreshed

OAuth Endpoints (automatically registered):

  • Authorization: http://localhost:8000/oauth/authorize

  • Token: http://localhost:8000/oauth/token

  • Discovery: http://localhost:8000/.well-known/oauth-authorization-server

  • Callback: http://localhost:8000/oauth/callback

Deployment to Fly.io

āœ… OAuth is now configured for https://stage.chukai.io and https://physics.chukai.io

See OAUTH_SETUP_COMPLETE.md for details on the production OAuth setup.

For production deployments, set secrets instead of using .env:

# Set Google OAuth credentials as Fly secrets
fly secrets set GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
fly secrets set GOOGLE_CLIENT_SECRET="your-client-secret"

# Set OAuth server URL (use your Fly.io app URL)
fly secrets set OAUTH_SERVER_URL="https://your-app.fly.dev"
fly secrets set GOOGLE_REDIRECT_URI="https://your-app.fly.dev/oauth/callback"

# Optional: Configure session backend for production
fly secrets set SESSION_PROVIDER="redis"
fly secrets set SESSION_REDIS_URL="redis://your-redis-url:6379/0"

# Deploy
fly deploy

Important: Update Google Cloud Console with production redirect URI:

  • Add https://your-app.fly.dev/oauth/callback to authorized redirect URIs

Storage Providers

chuk-mcp-stage supports multiple storage backends - see STORAGE_CONFIGURATION.md for complete details.

Quick Comparison:

Provider

Persistence

Cloud Sync

OAuth Required

Setup

Best For

vfs-filesystem (default)

āœ… Local

āŒ

āŒ

Zero

Local dev

vfs-filesystem + OAuth

āœ… Persistent

āœ… Google Drive

āœ…

Medium

Production (small)

vfs-s3

āœ… Persistent

āœ… S3

āŒ

Medium

Production (large)

vfs-memory

āŒ RAM only

āŒ

āŒ

Zero

Testing only

Environment Variables:

# Storage provider selection (default: vfs-filesystem)
STORAGE_PROVIDER=vfs-filesystem

# Session metadata storage (default: memory)
SESSION_PROVIDER=memory

# For Redis sessions (production)
SESSION_PROVIDER=redis
REDIS_URL=redis://localhost:6379/0

# For AWS S3 storage
STORAGE_PROVIDER=vfs-s3
AWS_ACCESS_KEY_ID=xxx
AWS_SECRET_ACCESS_KEY=xxx
AWS_S3_BUCKET=chuk-artifacts
AWS_REGION=us-east-1

See STORAGE_CONFIGURATION.md for:

  • Detailed provider comparison

  • Migration guides

  • Production best practices

  • Troubleshooting

Where Your Scenes Live

With vfs-filesystem (default):

~/.chuk-artifacts/
└── grid/
    └── {sandbox_id}/
        └── {session_id}/
            └── {namespace_id}/
                ā”œā”€ā”€ scene.json
                ā”œā”€ā”€ animations/
                └── export/

With Google Drive (vfs-filesystem + OAuth):

Google Drive
└── chuk-artifacts/
    └── {user_id}/
        └── {namespace_id}/
            ā”œā”€ā”€ scene.json
            ā”œā”€ā”€ animations/
            │   └── cannonball.json
            └── export/
                └── remotion/

With AWS S3 (vfs-s3):

s3://your-bucket/
└── grid/
    └── {sandbox_id}/
        └── {session_id}/
            └── {namespace_id}/
                ā”œā”€ā”€ scene.json
                └── animations/

Storage Scope Behavior:

  • SESSION scope (unauthenticated) → Local filesystem only, ephemeral

  • USER scope (authenticated) → Google Drive (if OAuth enabled) or S3, persistent


šŸ“¦ Tool Surface

Scene Management

# Create a new scene
stage_create_scene(name, author, description)

# Add 3D objects
stage_add_object(
    scene_id,
    object_id,
    object_type,  # "box", "sphere", "cylinder", "plane"
    position_x, position_y, position_z,
    radius, size_x, size_y, size_z,
    material_preset,  # "metal-dark", "glass-blue", "plastic-white"
    color_r, color_g, color_b
)

# Set environment & lighting
stage_set_environment(
    scene_id,
    environment_type,  # "gradient", "solid", "hdri"
    lighting_preset    # "three-point", "studio", "noon"
)

Camera & Shots

# Add camera shot
stage_add_shot(
    scene_id,
    shot_id,
    camera_mode,  # "orbit", "static", "chase", "dolly"
    start_time,
    end_time,
    focus_object,      # Object to orbit/chase
    orbit_radius,
    orbit_elevation,
    orbit_speed,
    easing  # "ease-in-out-cubic", "spring", "linear"
)

# Get shot details
stage_get_shot(scene_id, shot_id)

Physics Integration

# Bind object to physics body
stage_bind_physics(
    scene_id,
    object_id,
    physics_body_id  # "rapier://sim-abc/body-ball"
)

# Bake simulation to keyframes
stage_bake_simulation(
    scene_id,
    simulation_id,
    fps=60,
    duration=10.0,
    physics_server_url=None  # Optional: defaults to https://rapier.chukai.io
)

Export

# Export to R3F/Remotion/glTF
stage_export_scene(
    scene_id,
    format,  # "r3f-component", "remotion-project", "gltf", "json"
    output_path
)

# Get complete scene data
stage_get_scene(scene_id)

🧩 Core Concepts

Stage Objects

A Stage Object is an entry in the scene graph that represents a 3D visual element. Every object has:

Property

Description

Example

id

Unique identifier

"ball", "ground", "car-chassis"

type

Primitive shape

"sphere", "box", "cylinder", "plane"

transform

Position, rotation, scale

{position: [0, 5, 0], rotation: [0, 0, 0], scale: [1, 1, 1]}

material

Visual appearance

"glass-blue", "metal-dark", custom PBR

physics_binding

Optional physics link

"rapier://sim-abc/body-ball"

Example scene JSON:

{
  "id": "demo-scene",
  "name": "Falling Ball Demo",
  "objects": {
    "ground": {
      "id": "ground",
      "type": "plane",
      "transform": {
        "position": {"x": 0, "y": 0, "z": 0},
        "rotation": {"x": 0, "y": 0, "z": 0},
        "scale": {"x": 1, "y": 1, "z": 1}
      },
      "size": {"x": 20, "y": 20, "z": 1},
      "material": {
        "preset": "metal-dark"
      },
      "physics_binding": null
    },
    "ball": {
      "id": "ball",
      "type": "sphere",
      "transform": {
        "position": {"x": 0, "y": 5, "z": 0},
        "rotation": {"x": 0, "y": 0, "z": 0},
        "scale": {"x": 1, "y": 1, "z": 1}
      },
      "radius": 1.0,
      "material": {
        "preset": "glass-blue",
        "color": {"r": 0.3, "g": 0.6, "b": 1.0}
      },
      "physics_binding": "rapier://sim-falling/body-ball"
    }
  },
  "shots": {
    "main": {
      "id": "main",
      "camera_path": {
        "mode": "orbit",
        "focus": "ball",
        "radius": 8.0,
        "elevation": 30.0
      },
      "start_time": 0.0,
      "end_time": 10.0
    }
  }
}

Why this matters for LLMs:

When you create an object with stage_add_object, you're modifying this scene graph. Later operations like stage_bind_physics or stage_add_shot reference the same object ID you created. This makes it easy to reason about: "I want to modify the ball I just created" → just use object_id="ball".

Authoring vs Baking

chuk-mcp-stage has two distinct phases:

1ļøāƒ£ Authoring Phase (Define the World)

What you're doing: Planning and composing the scene

Operations:

  • Create scene structure

  • Place objects (primitives, positions, materials)

  • Define camera shots and movements

  • Bind object IDs to physics body IDs

  • Set environment and lighting

Output: Scene definition (metadata only, no animation yet)

Tools used:

  • stage_create_scene

  • stage_add_object

  • stage_add_shot

  • stage_bind_physics

  • stage_set_environment

2ļøāƒ£ Baking Phase (Generate Animation Data)

What you're doing: Converting physics simulation to renderable keyframes

Operations:

  • Connect to physics simulation (Rapier)

  • Sample physics state at desired FPS

  • Convert body positions/rotations → keyframes

  • Store animation data in scene VFS

Output: Timestamped keyframe arrays (position, rotation, velocity per frame)

Tools used:

  • stage_bake_simulation (connects to physics, generates keyframes)

  • stage_export_scene (exports scene + baked animations)

Typical Flow

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ AUTHORING PHASE                                              │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ 1. stage_create_scene(name="demo")                           │
│    → Creates empty scene graph                               │
│                                                               │
│ 2. stage_add_object(id="ground", type="plane", ...)          │
│    stage_add_object(id="ball", type="sphere", y=10, ...)     │
│    → Defines visual objects (no motion yet)                  │
│                                                               │
│ 3. stage_set_environment(lighting="three-point")             │
│    → Sets lights, background                                 │
│                                                               │
│ 4. Use physics MCP to create simulation                      │
│    create_simulation(gravity_y=-9.81)                        │
│    add_rigid_body(sim_id, body_id="ball", ...)               │
│    → Physics oracle creates simulation                       │
│                                                               │
│ 5. stage_bind_physics(object_id="ball",                      │
│                       body_id="rapier://sim-id/body-ball")   │
│    → Links visual object to physics body                     │
│                                                               │
│ 6. step_simulation(sim_id, steps=600)  # 10s @ 60 FPS        │
│    → Physics oracle runs simulation                          │
│                                                               │
│ 7. stage_add_shot(mode="orbit", focus="ball", ...)           │
│    → Defines camera cinematography                           │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ BAKING PHASE                                                 │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ 8. stage_bake_simulation(scene_id, sim_id, fps=60, dur=10)  │
│    → Fetches physics data from Rapier                        │
│    → Converts to keyframes                                   │
│    → Stores in /animations/ball.json                         │
│                                                               │
│ 9. stage_export_scene(format="remotion-project")            │
│    → Generates R3F/Remotion code                             │
│    → Includes baked animation data                           │
│    → Returns artifact URIs                                   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

   Authoring = "What should exist and where?"
   Baking    = "What motion actually happened?"

Key Insight: Authoring is declarative (you define intent), baking is computational (physics oracle generates the motion).


šŸŽ¬ Example Workflow

1. Simple Falling Ball Demo

# 1. Create scene
scene = await stage_create_scene(
    name="falling-ball-demo",
    description="Ball falling under gravity"
)

# 2. Add ground plane
await stage_add_object(
    scene_id=scene.scene_id,
    object_id="ground",
    object_type="plane",
    size_x=20.0,
    size_y=20.0,
    material_preset="metal-dark"
)

# 3. Add falling ball
await stage_add_object(
    scene_id=scene.scene_id,
    object_id="ball",
    object_type="sphere",
    radius=1.0,
    position_y=5.0,
    material_preset="glass-blue",
    color_r=0.3,
    color_g=0.5,
    color_b=1.0
)

# 4. Add orbiting camera shot
await stage_add_shot(
    scene_id=scene.scene_id,
    shot_id="orbit-shot",
    camera_mode="orbit",
    focus_object="ball",
    orbit_radius=8.0,
    orbit_elevation=30.0,
    orbit_speed=0.1,
    start_time=0.0,
    end_time=10.0
)

# 5. Export to Remotion
result = await stage_export_scene(
    scene_id=scene.scene_id,
    format="remotion-project"
)

2. Physics-Driven Animation

Note: This example uses the public Rapier service (https://rapier.chukai.io) by default. No configuration needed!

# 1. Create physics simulation (chuk-mcp-physics)
sim = await create_simulation(gravity_y=-9.81)

await add_rigid_body(
    sim_id=sim.sim_id,
    body_id="ball",
    body_type="dynamic",
    shape="sphere",
    radius=1.0,
    position=[0, 5, 0]
)

# 2. Create scene
scene = await stage_create_scene(name="physics-demo")

await stage_add_object(
    scene_id=scene.scene_id,
    object_id="ball",
    object_type="sphere",
    radius=1.0,
    position_y=5.0
)

# 3. Bind physics to visual
await stage_bind_physics(
    scene_id=scene.scene_id,
    object_id="ball",
    physics_body_id=f"rapier://{sim.sim_id}/body-ball"
)

# 4. Run simulation (chuk-mcp-physics)
await step_simulation(sim_id=sim.sim_id, steps=600)

# 5. Bake physics → keyframes
await stage_bake_simulation(
    scene_id=scene.scene_id,
    simulation_id=sim.sim_id,
    fps=60,
    duration=10.0
)

# 6. Export with animation data
await stage_export_scene(
    scene_id=scene.scene_id,
    format="r3f-component"
)

šŸ“š Examples

The examples/ directory contains ready-to-run demonstrations of all features.

🌟 Start Here: Golden Path

The canonical example showing the complete pipeline:

uv run examples/00_golden_path_ball_throw.py

This example demonstrates:

  • āœ… Authoring phase - Scene creation, object placement, camera shots

  • āœ… Baking phase - Physics simulation → keyframes (conceptual)

  • āœ… Export phase - Generate R3F/Remotion code

  • āœ… Artifact URIs - How chuk-mcp-stage integrates with chuk-artifacts

  • āœ… Two-phase model - Declarative → Computational

  • āœ… Complete pipeline - Physics → Stage → Motion → Video

This is the best example to understand the CHUK stack cohesion.

Getting Started

# Run any example
uv run examples/00_golden_path_ball_throw.py  # ⭐ Start here!
uv run examples/01_simple_scene.py
uv run examples/02_physics_integration_demo.py
uv run examples/03_camera_shots_demo.py
uv run examples/04_export_formats.py
uv run examples/05_full_physics_workflow.py

Example Guide

Example

Purpose

What You'll Learn

00_golden_path_ball_throw.py ⭐

Complete pipeline

Full workflow, artifact URIs, two-phase model

01_simple_scene.py

Basic scene creation

Objects, transforms, materials, simple camera

02_physics_integration_demo.py

Physics binding concepts

Binding objects to physics bodies, metadata

03_camera_shots_demo.py

Camera cinematography

ORBIT, STATIC, DOLLY, CHASE modes, easing functions

04_export_formats.py

Export capabilities

JSON, R3F, Remotion, glTF formats and use cases

05_full_physics_workflow.py

Complete pipeline

Full physics-to-video workflow with public Rapier

Example Outputs

00_golden_path_ball_throw.py ⭐ - Complete pipeline demonstration

šŸ“‚ Artifact URIs (Not file contents!):
   Scene data:  artifact://stage/golden-path-ball-throw/exports/scene.json
   R3F:         artifact://stage/golden-path-ball-throw/exports/r3f/Scene.tsx
   Remotion:    artifact://stage/golden-path-ball-throw/exports/remotion/

šŸŽ¬ Complete Pipeline:
   1. Authoring   - Define scene structure   āœ“
   2. Physics     - Create simulation         (conceptual)
   3. Binding     - Link objects → bodies     āœ“
   4. Baking      - Physics → keyframes       (conceptual)
   5. Export      - Scene → R3F/Remotion      āœ“
   6. Render      - Remotion → MP4            (external)

01_simple_scene.py - Creates falling ball scene

āœ“ Created scene: falling-ball
āœ“ Added ground plane
āœ“ Added ball at (0, 5, 0)
āœ“ Added orbit camera shot (10s)

03_camera_shots_demo.py - 38-second multi-shot sequence

šŸ“¹ Shot Sequence:
   •   0.0s -  10.0s  ORBIT   - Smooth orbit around center
   •  10.0s -  15.0s  STATIC  - Static wide angle
   •  15.0s -  22.0s  DOLLY   - Dolly tracking shot
   •  22.0s -  28.0s  CHASE   - Chase with spring easing
   •  28.0s -  33.0s  ORBIT   - Fast linear orbit
   •  33.0s -  38.0s  STATIC  - Low angle hero shot

04_export_formats.py - Exports to all formats

āœ“ JSON:     /exports/scene.json
āœ“ R3F:      /exports/r3f/Scene.tsx
āœ“ Remotion: /exports/remotion/Root.tsx
āœ“ glTF:     /exports/scene.gltf

Note: In production, these would be artifact URIs like:
  artifact://stage/{scene_id}/exports/scene.json

05_full_physics_workflow.py - Shows complete pipeline

šŸŽ¬ Complete Pipeline:
   1. Physics Simulation (chuk-mcp-physics)
   2. Scene Composition (chuk-mcp-stage) āœ“
   3. Bind Physics āœ“
   4. Bake Simulation (Rapier service)
   5. Export (R3F/Remotion) āœ“
   6. Render Video (Remotion)

Learning Path

Recommended order:

  1. Start with 00_golden_path_ball_throw.py ⭐ - See the complete pipeline first

  2. Understand basics with 01_simple_scene.py

  3. Explore camera control with 03_camera_shots_demo.py

  4. Learn export options with 04_export_formats.py

  5. See physics concepts with 02_physics_integration_demo.py

  6. Complete workflow with 05_full_physics_workflow.py

Why start with golden path? It shows you the destination (full pipeline) before diving into individual pieces. You'll understand how all the tools work together in the CHUK stack.


šŸ—ļø Architecture

Scene Storage

  • Backend: chuk-artifacts (VFS-backed workspaces)

  • Format: JSON scene definitions with nested objects

  • Scope: SESSION (ephemeral), USER (persistent), SANDBOX (shared)

Each scene is a workspace containing:

/scene.json          # Scene definition
/animations/         # Baked keyframe data
  ball.json
  car.json
/export/             # Generated R3F/Remotion code
  r3f/
  remotion/

Camera Path Modes

Mode

Use Case

Parameters

orbit

Product shots, inspection

radius, elevation, speed, focus

static

Fixed observation

position, look_at

chase

Follow moving objects

target, offset, damping

dolly

Linear reveals

from_position, to_position, look_at

flythrough

Scene tours

waypoints[]

crane

Cinematic sweeps

pivot, arc, height_range

Material Presets

  • metal-dark, metal-light

  • glass-clear, glass-blue, glass-green

  • plastic-red, plastic-blue, plastic-white

  • rubber-black

  • wood-oak

Export Formats

  • R3F Component - React Three Fiber .tsx files

  • Remotion Project - Full project with package.json

  • glTF - Static 3D scene file

  • JSON - Raw scene data

VFS & Artifacts Integration

chuk-mcp-stage is tightly integrated with chuk-artifacts and chuk-virtual-fs for storage and asset management.

Why This Matters

Unlike typical MCP servers that return large JSON blobs inline, chuk-mcp-stage returns artifact URIs:

# āŒ Traditional approach (bloated)
{
  "scene_data": "...<10MB of JSON>...",
  "r3f_component": "...<5000 lines of TSX>...",
  "animations": "...<50MB of keyframes>..."
}

# āœ… CHUK approach (cohesive)
{
  "scene": "artifact://stage/demo-scene/scene.json",
  "component": "artifact://stage/demo-scene/export/r3f/Scene.tsx",
  "animations": "artifact://stage/demo-scene/animations/ball.json"
}

Benefits:

  1. No inline bloat - Tools return URIs, not massive data

  2. Persistent storage - Scenes survive across sessions (if using USER scope)

  3. VFS operations - Use vfs_ls, vfs_find, vfs_cp to manage scene files

  4. Cross-tool sharing - Other MCP servers can access same artifacts

  5. Checkpoint support - Version control for scene iterations

Storage Model

Each scene = one workspace in chuk-artifacts:

artifact://stage/{scene_id}/
ā”œā”€ā”€ scene.json              # Scene definition
ā”œā”€ā”€ animations/             # Baked physics keyframes
│   ā”œā”€ā”€ ball.json          # Per-object animation data
│   ā”œā”€ā”€ car.json
│   └── character.json
└── export/                 # Generated code
    ā”œā”€ā”€ r3f/               # React Three Fiber
    │   ā”œā”€ā”€ Scene.tsx
    │   ā”œā”€ā”€ Camera.tsx
    │   └── animations.json
    ā”œā”€ā”€ remotion/          # Remotion project
    │   ā”œā”€ā”€ Composition.tsx
    │   ā”œā”€ā”€ Root.tsx
    │   └── package.json
    └── gltf/              # 3D model exports
        └── scene.gltf

Example: Working with Artifacts

# 1. Create scene (returns artifact URI)
result = await stage_create_scene(name="demo")
# → {"scene_id": "demo-xyz", "workspace": "artifact://stage/demo-xyz"}

# 2. Add objects and bake simulation
# ... (authoring phase)

# 3. Export to Remotion (returns artifact URIs)
export_result = await stage_export_scene(
    scene_id="demo-xyz",
    format="remotion-project",
    output_path="/export/remotion"
)
# → {
#     "composition": "artifact://stage/demo-xyz/export/remotion/Composition.tsx",
#     "root": "artifact://stage/demo-xyz/export/remotion/Root.tsx",
#     "package": "artifact://stage/demo-xyz/export/remotion/package.json"
# }

# 4. Use VFS tools to explore (via chuk-virtual-fs MCP)
await vfs_ls("artifact://stage/demo-xyz/export/remotion")
# → ["Composition.tsx", "Root.tsx", "package.json"]

await vfs_read("artifact://stage/demo-xyz/export/remotion/package.json")
# → Returns package.json contents

# 5. Copy to another location
await vfs_cp(
    "artifact://stage/demo-xyz/export/remotion",
    "artifact://projects/my-video"
)

Integration with Other CHUK Tools

chuk-mcp-r3f-preview can directly preview scenes:

# Stage creates scene
scene_uri = "artifact://stage/demo-xyz/export/r3f/Scene.tsx"

# R3F preview server loads it
await r3f_preview_scene(scene_uri)
# → Opens interactive 3D preview in browser

chuk-motion can render baked animations:

# Stage bakes physics
animation_uri = "artifact://stage/demo-xyz/animations/ball.json"

# Motion applies spring physics to keyframes
await motion_apply_spring(animation_uri, stiffness=100)

This is where the CHUK stack cohesion shines: Every tool speaks the same artifact URI language.


šŸ”— Integration with CHUK Stack

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                     chuk-mcp-stage                          │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  │
│  │ Scene Graph  │  │   Camera     │  │  Physics Bridge  │  │
│  │              │  │   Paths      │  │                  │  │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
          │                 │                   │
          ā–¼                 ā–¼                   ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ chuk-artifacts  │  │ chuk-motion │  │  chuk-mcp-physics   │
│                 │  │             │  │      (Rapier)       │
│ • scene.json    │  │ • easing    │  │                     │
│ • assets/       │  │ • springs   │  │ • rigid bodies      │
│ • animations/   │  │ • keyframes │  │ • constraints       │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  │ • sim state         │
                            │         ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                            ā–¼
                   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
                   │ Remotion        │
                   │                 │
                   │ • R3F render    │
                   │ • video export  │
                   │ • MP4 output    │
                   ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

šŸŽÆ Use Cases

Immediate Wins

  1. Physics Explainer Videos - Auto-generate educational content

  2. Simulation-as-a-Service - LLMs can request visualizations

  3. Procedural B-Roll - Synthetic motion graphics

Vertical Plays

  1. Motorsport Visualization - Racing lines, braking zones, overtakes

  2. 3D Data Storytelling - Animated datasets with cinematography

  3. Science Journalism - Render model predictions visually

Weird & Powerful

  1. Explainable AI Animations - Show what models are thinking

  2. Virtual Physics Lab - Programmable experiments

  3. Agent Cinematography - AI chooses camera paths


šŸ“ Data Models

All models are Pydantic-native with no dictionary goop:

from chuk_mcp_stage.models import (
    Scene,              # Complete scene definition
    SceneObject,        # 3D object (mesh, material, transform)
    Shot,               # Camera path + time range
    CameraPath,         # Camera movement definition
    Material,           # PBR material properties
    Environment,        # Lighting & background
    BakedAnimation,     # Physics → keyframes
)

Enums everywhere:

ObjectType.SPHERE
MaterialPreset.GLASS_BLUE
CameraPathMode.ORBIT
LightingPreset.THREE_POINT
ExportFormat.R3F_COMPONENT

🧪 Testing

# Run tests
pytest

# With coverage
pytest --cov=chuk_mcp_stage

šŸ› ļø Development

# Install dev dependencies
pip install -e ".[dev]"

# Format
black src/ tests/

# Lint
ruff check src/

# Type check
mypy src/

šŸ“„ License

MIT License - see LICENSE for details


🌟 Why This Matters

Most people can: āœ… Run simulations āœ… Generate charts āœ… Animate text

Almost nobody can:

Simulate → Direct → Render → Explain → Export

chuk-mcp-stage gives you that pipeline.

You're not rendering things anymore. You're producing explainable simulations as media.


Built with ā¤ļø for the CHUK AI stack

Available Tools

9 tools
stage_add_objectA

Add a 3D object to the scene.

Adds primitives (box, sphere, cylinder, etc.) or placeholders for meshes.
Objects can be bound to physics bodies later for animation.

Args:
    scene_id: Scene identifier
    object_id: Unique object name (e.g., "ground", "ball", "car")
    object_type: Object type - "box", "sphere", "cylinder", "capsule", "plane", "mesh"
    position_x, position_y, position_z: Position in 3D space
    rotation_x, rotation_y, rotation_z, rotation_w: Rotation quaternion
    scale_x, scale_y, scale_z: Scale factors
    size_x, size_y, size_z: Size for box (width, height, depth)
    radius: Radius for sphere/cylinder/capsule
    height: Height for cylinder/capsule
    material_preset: Material preset - "metal-dark", "glass-blue", "plastic-white", etc.
    color_r, color_g, color_b: RGB color (0.0-1.0)

Returns:
    AddObjectResponse with object_id confirmation

Tips for LLMs:
    - For ground: object_type="plane", large size, static
    - For dynamic objects: smaller primitives that match physics bodies
    - Quaternion: [0,0,0,1] is identity (no rotation)
    - Common materials: "metal-dark", "glass-blue", "plastic-white", "rubber-black"

Example:
    # Add ground plane
    await stage_add_object(
        scene_id=scene_id,
        object_id="ground",
        object_type="plane",
        size_x=20.0,
        size_y=20.0,
        material_preset="metal-dark"
    )

    # Add falling sphere
    await stage_add_object(
        scene_id=scene_id,
        object_id="ball",
        object_type="sphere",
        radius=1.0,
        position_y=5.0,
        material_preset="glass-blue",
        color_r=0.3,
        color_g=0.5,
        color_b=1.0
    )
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
object_idYes
object_typeYes
position_xNo
position_yNo
position_zNo
rotation_xNo
rotation_yNo
rotation_zNo
rotation_wNo
scale_xNo
scale_yNo
scale_zNo
size_xNo
size_yNo
size_zNo
radiusNo
heightNo
material_presetNoplastic-white
color_rNo
color_gNo
color_bNo

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses behavior (adds primitives/placeholders, can be bound to physics) and the return type (AddObjectResponse). However, it lacks details on permissions, side effects, or constraints like scene existence.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is lengthy but well-structured with sections: general description, Args, Returns, Tips, and Example. It is comprehensive but could be more concise. However, the structure aids readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 22 parameters, no output schema, and no annotations, the description is highly complete. It explains each parameter, provides common use-case tips, and includes two examples covering key object types (plane and sphere).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It fully documents all 22 parameters with explanations, defaults, and relationships (e.g., radius for sphere/cylinder). This adds significant value beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it adds a 3D object to the scene, specifying primitives or placeholders. It distinguishes from siblings like 'stage_add_shot' and 'stage_create_scene' by focusing on object addition within a scene.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides tips for LLMs, including typical objects like ground planes and dynamic spheres, and common material presets. It does not explicitly state when not to use or list alternatives, but the tips offer clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_add_shotA

Add a camera shot to the scene.

Defines a camera movement path and time range for cinematography.

Args:
    scene_id: Scene identifier
    shot_id: Unique shot name (e.g., "intro-orbit", "close-up")
    camera_mode: "orbit", "static", "chase", "dolly", "flythrough", "crane", "track"
    start_time: Shot start time in seconds
    end_time: Shot end time in seconds
    focus_object: Object ID to focus on (for orbit/chase modes)
    orbit_radius: Distance from focus object (orbit mode)
    orbit_elevation: Camera elevation angle in degrees (orbit mode)
    orbit_speed: Rotation speed in revolutions per second (orbit mode)
    static_position_x, static_position_y, static_position_z: Camera position (static mode)
    look_at_x, look_at_y, look_at_z: Point to look at
    easing: Easing function - "linear", "ease-in-out", "spring", etc.

Returns:
    AddShotResponse with shot details

Tips for LLMs:
    - Orbit mode: Great for product shots, object inspection
    - Static mode: Fixed camera, good for observing motion
    - Chase mode: Follow moving objects
    - Multiple shots can be sequenced for different camera angles

Example:
    # Orbiting shot around falling ball
    await stage_add_shot(
        scene_id=scene_id,
        shot_id="orbit-shot",
        camera_mode="orbit",
        focus_object="ball",
        orbit_radius=8.0,
        orbit_elevation=30.0,
        orbit_speed=0.1,
        start_time=0.0,
        end_time=10.0
    )
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
shot_idYes
camera_modeYes
start_timeYes
end_timeYes
focus_objectNo
orbit_radiusNo
orbit_elevationNo
orbit_speedNo
static_position_xNo
static_position_yNo
static_position_zNo
look_at_xNo
look_at_yNo
look_at_zNo
easingNoease-in-out-cubic

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It explains parameters and camera modes but does not disclose error handling, side effects (e.g., appending shots), or prerequisites. The behavioral impact is partially inferred but not explicitly stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with summary, Args, Tips, and Example. Each section adds value without redundancy. The Tips section is particularly helpful. A slight reduction in length could be achieved, but overall it is appropriately concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 16 parameters, no output schema, and no annotations, the description covers parameter semantics and usage tips well, including an example. It mentions the return type 'AddShotResponse with shot details'. It lacks details on potential errors or behavior under edge cases, but is fairly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description includes a detailed Args list explaining each parameter's purpose, examples, and defaults (e.g., easing default 'ease-in-out-cubic'). This adds significant meaning beyond the schema's type and required fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Add a camera shot to the scene' with specific verb 'Add' and resource 'shot'. It details the functionality (defines camera movement path and time range) and distinguishes from sibling tools like stage_get_shot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'Tips for LLMs' section provides explicit guidance on when to use each camera mode (e.g., orbit for product shots, chase for moving objects). It also mentions sequencing multiple shots. However, it does not explicitly compare to sibling tools or state when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_bake_simulationA

Bake physics simulation to keyframe animations.

Converts physics simulation data into keyframes that can be
exported to R3F/Remotion for video rendering.

Args:
    scene_id: Scene identifier
    simulation_id: Physics simulation ID from chuk-mcp-physics
    fps: Frames per second for sampling (default 60)
    duration: Duration in seconds to bake (if None, bakes entire simulation)
    physics_server_url: Optional Rapier HTTP server URL
        If None, defaults to public Rapier service (https://rapier.chukai.io)
        Can be overridden with RAPIER_SERVICE_URL environment variable

Returns:
    BakeSimulationResponse with frame count and baked object list

Tips for LLMs:
    - Run physics simulation first (chuk-mcp-physics step_simulation or record_trajectory)
    - Bind objects to physics bodies (stage_bind_physics)
    - Bake simulation to convert physics → animation keyframes
    - Then export scene to R3F/Remotion with animation data

Example:
    # After running simulation and binding objects
    result = await stage_bake_simulation(
        scene_id=scene_id,
        simulation_id=sim.sim_id,
        fps=60,
        duration=10.0
    )
    print(f"Baked {result.total_frames} frames for {len(result.baked_objects)} objects")
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
simulation_idYes
fpsNo
durationNo
physics_server_urlNo

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so the description carries the full burden. It explains the conversion process, default service URL, and optional duration. However, it does not mention side effects like whether the original simulation data is retained or destroyed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (description, Args, Returns, Tips, Example). While slightly verbose, it front-loads the main purpose and uses efficient bullet points.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations and no output schema, the description includes return type description and a concrete example. It also provides the full workflow context via tips, making it complete for agent usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description fully explains all parameters in the 'Args' section, including defaults, optionality, and environment variable override for physics_server_url. This adds significant meaning beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it converts physics simulation data into keyframes for animation, specifically mentioning integration with R3F/Remotion. It distinguishes from sibling tools like stage_bind_physics and stage_export_scene by outlining the workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'Tips for LLMs' section provides explicit steps: run physics simulation first, bind objects, then bake, then export. This gives clear when-to-use guidance and distinguishes it from other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_bind_physicsA

Bind a scene object to a physics body.

Links a visual object to a physics simulation body so that
the physics simulation drives the object's animation.

Args:
    scene_id: Scene identifier
    object_id: Scene object ID
    physics_body_id: Physics body ID from chuk-mcp-physics
        Format: "rapier://sim-{sim_id}/body-{body_id}"
        Example: "rapier://sim-abc123/body-ball"

Returns:
    BindPhysicsResponse confirmation

Tips for LLMs:
    - Create physics body first using chuk-mcp-physics
    - Then create matching scene object with same shape/size
    - Bind them together so physics drives visuals
    - Use stage_bake_simulation to convert physics → keyframes

Example:
    # 1. Create physics simulation (chuk-mcp-physics)
    sim = await create_simulation(gravity_y=-9.81)

    # 2. Add physics body
    await add_rigid_body(
        sim_id=sim.sim_id,
        body_id="ball",
        body_type="dynamic",
        shape="sphere",
        radius=1.0,
        position=[0, 5, 0]
    )

    # 3. Create scene object
    await stage_add_object(
        scene_id=scene_id,
        object_id="ball",
        object_type="sphere",
        radius=1.0,
        position_y=5.0
    )

    # 4. Bind them
    await stage_bind_physics(
        scene_id=scene_id,
        object_id="ball",
        physics_body_id=f"rapier://{sim.sim_id}/body-ball"
    )
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
object_idYes
physics_body_idYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description bears full responsibility for behavioral traits. It explains that physics drives the object's animation but does not disclose whether binding is reversible, what happens to existing bindings, or any authentication/rate-limit info. The basic linking behavior is transparent, but deeper effects are omitted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear headings (Args, Returns, Tips, Example) and front-loaded purpose. The example is detailed but adds value; slight verbosity prevents a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description mentions a 'BindPhysicsResponse confirmation' but does not detail the response fields. It also lacks info on reversibility or error conditions. The tips provide good workflow context, but completeness is slightly lacking for a binding operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates with an 'Args' section explaining each parameter: scene_id, object_id, physics_body_id (with format and example). This adds meaning beyond the raw schema, though the return value is only vaguely mentioned.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it binds a scene object to a physics body, with the purpose being that the physics simulation drives the object's animation. This is specific and distinguishes it from sibling tools like stage_add_object (creates objects) and stage_bake_simulation (converts physics to keyframes).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a 'Tips for LLMs' section that outlines the correct workflow: create physics body first, then create matching scene object, then bind. It also suggests using stage_bake_simulation to convert physics to keyframes. This gives clear guidance on the sequence and context, though it does not explicitly state when not to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_create_sceneA

Create a new 3D scene for composition.

Initializes a new scene workspace backed by chuk-artifacts.
The scene can contain 3D objects, lighting, camera shots, and physics bindings.

Args:
    name: Optional scene name (e.g., "pendulum-demo", "f1-silverstone-t1")
    author: Optional author name for metadata
    description: Optional scene description

Returns:
    CreateSceneResponse with scene_id and success message

Tips for LLMs:
    - Scene ID is auto-generated (UUID)
    - Scenes are stored in USER scope (Google Drive) if authenticated, SESSION scope otherwise
    - Use the scene_id for all subsequent operations
    - Typical workflow: create_scene → add_objects → add_shots → export

Example:
    scene = await stage_create_scene(
        name="falling-ball-demo",
        author="Claude",
        description="Simple gravity demonstration"
    )
    # Use scene.scene_id for next steps
ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
authorNo
descriptionNo
_user_idNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description discloses key behavioral traits: auto-generated scene ID (UUID), scope storage based on authentication, and that the tool is the first step in a workflow. It does not mention any destructive or side effects, but as a creation tool, the behavior is appropriately transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a concise headline, followed by detailed args, returns, tips, and an example. It is front-loaded with the key purpose and efficiently covers necessary information without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description explains the return type (CreateSceneResponse with scene_id) and provides a complete workflow context. It covers scope, parameter use, and typical next steps, making it fully informative for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description adds meaningful parameter guidance for name (with naming convention examples), author, and description. The parameter _user_id is not documented in the description, but the overall compensation for low schema coverage is strong.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Create a new 3D scene for composition.' It specifies the resource (scene) and action (create), and distinguishes it from sibling tools like stage_add_object and stage_export_scene by focusing on initialization of a scene workspace.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit workflow guidance ('Typical workflow: create_scene → add_objects → add_shots → export') and explains scope behavior (USER vs SESSION scope). It does not explicitly state when not to use this tool, but the context is clear enough for an agent to decide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_export_sceneA

Export scene to R3F, Remotion, or glTF format.

Converts the scene definition into code/files that can be used
with React Three Fiber or Remotion for rendering.

Args:
    scene_id: Scene identifier
    format: Export format - "r3f-component", "remotion-project", "gltf", "json"
    output_path: Optional VFS path for output (auto-generated if None)

Returns:
    ExportSceneResponse with output paths

Tips for LLMs:
    - "r3f-component": Generate React Three Fiber .tsx files
    - "remotion-project": Full Remotion project with package.json
    - "gltf": Static 3D scene file
    - "json": Raw scene JSON data
    - Exported files are in the scene's VFS workspace
    - Use chuk-artifacts to retrieve exported files

Example:
    result = await stage_export_scene(
        scene_id=scene_id,
        format="remotion-project"
    )
    print(f"Exported to {result.output_path}")
    # Files available at result.artifacts paths
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
formatNor3f-component
output_pathNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description effectively discloses behavior: it converts scenes to files, returns output paths, and explains file locations (VFS workspace). It also notes that exported files can be retrieved via chuk-artifacts. No hidden side effects are mentioned, but the core behavior is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with paragraphs for arguments, returns, tips, and an example. It is front-loaded with the purpose. However, the tips and example are somewhat verbose, making it longer than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (multiple formats, output paths, VFS integration), the description covers key aspects: function, parameters, return type, usage tips, and an example. No output schema exists, but the return type is described adequately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 0% description coverage, but the description adds significant meaning: explains scene_id as identifier, lists format options with examples, and clarifies output_path as optional. This compensates well for the schema's lack of documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool exports scenes to specific formats (R3F, Remotion, glTF, JSON), using a specific verb and resource. It distinguishes itself from sibling tools like stage_add_object or stage_create_scene.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for exporting scenes but does not explicitly state when to use this tool over alternatives or provide conditions to avoid. Tips for LLMs offer some context but no clear when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_get_sceneB

Get complete scene data.

Returns the full scene definition including all objects, shots,
animations, and configuration.

Args:
    scene_id: Scene identifier

Returns:
    GetSceneResponse with complete Scene object
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, but the description adequately describes the tool as a read operation returning full scene data. However, it does not disclose potential side effects, authentication needs, or error handling, leaving gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with clear structure: a one-line summary, a paragraph detailing return content, and a brief Args/Returns section. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the description covers the return content, it lacks details on error cases, prerequisites, or the structure of the response object. Given the tool's simplicity, it's somewhat adequate but could be more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter scene_id is described only as 'Scene identifier,' adding minimal meaning beyond the schema type string. With 0% schema coverage, more detail would be expected (e.g., format, constraints).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves complete scene data, listing specific components (objects, shots, animations, configuration). This distinguishes it from siblings like stage_get_shot (single shot) or stage_create_scene (creation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool vs alternatives. The description merely restates the function without providing context about selection criteria or exclusion of other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_get_shotA

Get shot details from a scene.

Args:
    scene_id: Scene identifier
    shot_id: Shot identifier

Returns:
    GetShotResponse with shot data
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
shot_idYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It states that the tool returns 'GetShotResponse with shot data', indicating a read-only operation, but does not explicitly mention read-only nature, authentication needs, or potential side effects. Given the simplicity of the tool, this is minimally adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, with the purpose stated in the first sentence, followed by a structured Args and Returns section. Every sentence adds value, and there is no redundant or extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple retrieval tool with no output schema and no annotations, the description covers the purpose, parameters, and return type adequately. It could benefit from mentioning potential errors or that scene_id must correspond to an existing scene, but overall it is sufficient given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, requiring the description to compensate. The description provides basic meaning for each parameter ('scene_id: Scene identifier', 'shot_id: Shot identifier'), but lacks details on format or constraints. This adds some value beyond the schema's bare type strings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Get shot details from a scene', specifying the verb 'get', the resource 'shot details', and the context 'from a scene'. This distinguishes it from sibling tools like stage_add_shot (add) and stage_get_scene (get scene).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving shot details but does not explicitly state when to use it versus alternatives (e.g., stage_add_shot for adding shots) or mention any prerequisites or conditions. Usage guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stage_set_environmentA

Set scene environment and lighting.

Configures the background, ambient lighting, and light sources.

Args:
    scene_id: Scene identifier
    environment_type: "gradient", "solid", "hdri", or "none"
    lighting_preset: "studio", "three-point", "noon", "sunset", "warehouse"
    intensity: Overall light intensity (0.0-2.0)

Returns:
    SetEnvironmentResponse confirmation

Example:
    await stage_set_environment(
        scene_id=scene_id,
        environment_type="gradient",
        lighting_preset="three-point"
    )
ParametersJSON Schema
NameRequiredDescriptionDefault
scene_idYes
environment_typeNogradient
lighting_presetNothree-point
intensityNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries the full burden. It discloses parameter options (environment_type, lighting_preset, intensity range) and return type (SetEnvironmentResponse). Missing details like preconditions (e.g., scene existence) or side effects prevent a higher score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is concise with only essential information, front-loaded, and structured with Args, Returns, and an Example. Every sentence contributes value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers parameters, return type, and provides an example. However, it lacks details about whether the scene must already exist or if the tool is idempotent. Given no output schema, it is fairly complete but could add preconditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description adds full meaning. It lists all 4 parameters with their types or enumerations, including default values in the example. This fully compensates for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Set scene environment and lighting' with specific resources (background, ambient lighting, light sources). It effectively distinguishes itself from sibling tools that handle objects, shots, physics, etc., making its unique purpose explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use the tool (to configure environment and lighting), but does not explicitly state when not to use it or suggest alternatives. The context is sufficient, though exclusions would strengthen guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 9 tool updatesv0.2.2
    • First observedstage_add_object
    • First observedstage_add_shot
    • First observedstage_bake_simulation
    • First observedstage_bind_physics
    • First observedstage_create_scene
    • First observedstage_export_scene
    • First observedstage_get_scene
    • First observedstage_get_shot
    • First observedstage_set_environment

TDQS

A4.1/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct aspect of 3D scene composition: objects, shots, physics binding, simulation baking, environment, export, and retrieval. No two tools have overlapping purposes.

Naming Consistency5/5

All tools follow a consistent 'stage_verb_noun' pattern in snake_case, e.g., stage_add_object, stage_get_scene, stage_set_environment. The naming convention is uniform and predictable.

Tool Count5/5

9 tools cover the essential operations for a 3D staging and export server without being overly numerous or sparse. The count is well-scoped for the domain.

Completeness4/5

The tools cover the primary workflow (create, add, bind, bake, export) and include getters. Minor gaps exist: no update/delete for objects or shots, and no scene deletion. However, these are manageable for most use cases.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers