chuk-mcp-stage
Orchestrates 3D scene creation, camera paths, and physics-driven animations, bridging physics simulations with video rendering by defining scene graphs, binding objects to physics bodies, and exporting to React Three Fiber or Remotion.
README
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)
๐ 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:
-
Direct Rapier HTTP (Default) - Fastest for simulations
- Directly calls Rapier service HTTP API
- Used by
stage_bake_simulationtool - Defaults 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.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:
- 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/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/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-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_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.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:
- Start with
00_golden_path_ball_throw.pyโญ - See the complete pipeline first - Understand basics with
01_simple_scene.py - Explore camera control with
03_camera_shots_demo.py - Learn export options with
04_export_formats.py - See physics concepts with
02_physics_integration_demo.py - 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-lightglass-clear,glass-blue,glass-greenplastic-red,plastic-blue,plastic-whiterubber-blackwood-oak
Export Formats
- R3F Component - React Three Fiber
.tsxfiles - 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:
- 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 files - Cross-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.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
- 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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.