chuk-mcp-stage
Supports running the local Rapier physics service via Docker for physics simulations.
Provides deployment configuration for hosting the Stage MCP server with OAuth and Google Drive integration on Fly.io infrastructure.
Exports 3D scenes and physics-driven animations to glTF format for use in other 3D applications and renderers.
Integrates with Google Cloud Console for OAuth configuration and credential management to enable Google Drive storage functionality.
Stores 3D scenes in Google Drive with OAuth 2.1 authentication, enabling secure, persistent, user-owned storage with automatic token refresh and cross-device access to scene files.
Supports Redis as a session backend provider for production deployments with OAuth authentication.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@chuk-mcp-stagecreate a scene with a bouncing ball and orbit camera"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
chuk-mcp-stage
3D Scene & Camera MCP Server - The director layer between physics simulation and motion rendering
š 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:
Scene Graph - Define 3D worlds (objects, materials, lighting)
Camera Paths - Cinematography (orbit, chase, dolly, static shots)
Physics Bridge - Bind scene objects to physics bodies (uses public Rapier service by default)
Animation Baking - Convert physics simulations ā keyframes
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/mcpOption 2: Install from PyPI
pip install chuk-mcp-stageOption 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 streamableTransport 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:
Direct Rapier HTTP (Default) - Fastest for simulations
Directly calls Rapier service HTTP API
Used by
stage_bake_simulationtoolDefaults to public service:
https://rapier.chukai.io
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
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.ioNo 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 --releaseSee 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:
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-secret4. Verify OAuth Integration (Optional but Recommended):
# Verify that OAuth setup works
python examples/verify_google_drive_oauth.pyThis 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 http6. Authorize Access:
When Claude Desktop (or any MCP client) connects:
OAuth flow automatically initiates
Browser opens for Google authorization
User grants access to Google Drive
Tokens securely stored and auto-refreshed
OAuth Endpoints (automatically registered):
Authorization:
http://localhost:8000/oauth/authorizeToken:
http://localhost:8000/oauth/tokenDiscovery:
http://localhost:8000/.well-known/oauth-authorization-serverCallback:
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 deployImportant: Update Google Cloud Console with production redirect URI:
Add
https://your-app.fly.dev/oauth/callbackto 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-1See 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 |
|
type | Primitive shape |
|
transform | Position, rotation, scale |
|
material | Visual appearance |
|
physics_binding | Optional physics link |
|
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_scenestage_add_objectstage_add_shotstage_bind_physicsstage_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.pyThis 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.pyExample 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 shot04_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.json05_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:
Start with
00_golden_path_ball_throw.pyā - See the complete pipeline firstUnderstand basics with
01_simple_scene.pyExplore camera control with
03_camera_shots_demo.pyLearn export options with
04_export_formats.pySee physics concepts with
02_physics_integration_demo.pyComplete 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 |
| Product shots, inspection | radius, elevation, speed, focus |
| Fixed observation | position, look_at |
| Follow moving objects | target, offset, damping |
| Linear reveals | from_position, to_position, look_at |
| Scene tours | waypoints[] |
| Cinematic sweeps | pivot, arc, height_range |
Material Presets
metal-dark,metal-lightglass-clear,glass-blue,glass-greenplastic-red,plastic-blue,plastic-whiterubber-blackwood-oak
Export Formats
R3F Component - React Three Fiber
.tsxfilesRemotion Project - Full project with
package.jsonglTF - 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:
No inline bloat - Tools return URIs, not massive data
Persistent storage - Scenes survive across sessions (if using USER scope)
VFS operations - Use
vfs_ls,vfs_find,vfs_cpto manage scene filesCross-tool sharing - Other MCP servers can access same artifacts
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.gltfExample: 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 browserchuk-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
Physics Explainer Videos - Auto-generate educational content
Simulation-as-a-Service - LLMs can request visualizations
Procedural B-Roll - Synthetic motion graphics
Vertical Plays
Motorsport Visualization - Racing lines, braking zones, overtakes
3D Data Storytelling - Animated datasets with cinematography
Science Journalism - Render model predictions visually
Weird & Powerful
Explainable AI Animations - Show what models are thinking
Virtual Physics Lab - Programmable experiments
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 toolsstage_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
)
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| object_id | Yes | ||
| object_type | Yes | ||
| position_x | No | ||
| position_y | No | ||
| position_z | No | ||
| rotation_x | No | ||
| rotation_y | No | ||
| rotation_z | No | ||
| rotation_w | No | ||
| scale_x | No | ||
| scale_y | No | ||
| scale_z | No | ||
| size_x | No | ||
| size_y | No | ||
| size_z | No | ||
| radius | No | ||
| height | No | ||
| material_preset | No | plastic-white | |
| color_r | No | ||
| color_g | No | ||
| color_b | No |
TDQS
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.
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.
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.
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.
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.
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
)
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| shot_id | Yes | ||
| camera_mode | Yes | ||
| start_time | Yes | ||
| end_time | Yes | ||
| focus_object | No | ||
| orbit_radius | No | ||
| orbit_elevation | No | ||
| orbit_speed | No | ||
| static_position_x | No | ||
| static_position_y | No | ||
| static_position_z | No | ||
| look_at_x | No | ||
| look_at_y | No | ||
| look_at_z | No | ||
| easing | No | ease-in-out-cubic |
TDQS
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.
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.
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.
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.
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.
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")
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| simulation_id | Yes | ||
| fps | No | ||
| duration | No | ||
| physics_server_url | No |
TDQS
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.
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.
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.
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.
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.
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"
)
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| object_id | Yes | ||
| physics_body_id | Yes |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| author | No | ||
| description | No | ||
| _user_id | No |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| format | No | r3f-component | |
| output_path | No |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| shot_id | Yes |
TDQS
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.
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.
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.
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.
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.
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"
)
| Name | Required | Description | Default |
|---|---|---|---|
| scene_id | Yes | ||
| environment_type | No | gradient | |
| lighting_preset | No | three-point | |
| intensity | No |
TDQS
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.
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.
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.
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.
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.
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.
9 tool updates
v0.2.2- First observed
stage_add_object - First observed
stage_add_shot - First observed
stage_bake_simulation - First observed
stage_bind_physics - First observed
stage_create_scene - First observed
stage_export_scene - First observed
stage_get_scene - First observed
stage_get_shot - First observed
stage_set_environment
TDQS
Scored across 9 tools
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.
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.
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.
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
Related MCP Connectors
Build interactive 3D web apps ā scenes, physics, audio and music ā from composable components.
Build 3D scenes, place cameras and render shots. Previs, storyboards, set design, product and CAD.
Make animated videos by asking Claude, Cursor or any MCP client. Your AI writes it, we render it.
Cloud Blender for AI agents: scenes, assets, renders, MP4, STL, GLB ā over hosted remote MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to control and manipulate live 3D scenes across frameworks like Three.js, A-Frame, and Babylon.js using a comprehensive set of object and environment tools. It features an integrated in-world chat system that allows for real-time scene modifications directly from within the 3D canvas.3318 npm3MIT
- FlicenseNot gradedqualityFmaintenanceOrchestrates Rive animations by enabling discovery, integration, and composition across frameworks like React and Vue, with code generation and multi-backend storage.5-
- AlicenseNot gradedqualityDmaintenanceConverts natural language prompts into 3D scenes and generates React Three Fiber code for web and ad applications.9,680 npm1MIT
- FlicenseNot gradedqualityAmaintenanceAI-native video composition and VFX engine that exposes its capabilities as MCP tools, enabling AI agents to act as directors and create videos programmatically.-