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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。