Connect Claude Code, Cursor, or any MCP client to Refract. Create shader backgrounds and custom 3D scenes with natural language. Get a live embed URL back.
From zero to a live 3D scene in under five minutes.
Open Refract, click your avatar, then API Keys → Create Key. Copy the rfk_ key—it’s shown once.
Drop this into your client’s MCP configuration file.
{
"mcpServers": {
"refract": {
"type": "url",
"url": "https://www.refract.build/mcp",
"headers": {
"Authorization": "Bearer rfk_your_key_here"
}
}
}
}
{
"mcpServers": {
"refract": {
"type": "url",
"url": "https://www.refract.build/mcp",
"headers": {
"Authorization": "Bearer rfk_your_key_here"
}
}
}
}
Tell your AI client what to build. The MCP tool runs, and you get a live embed URL back.
Create a 3D scene of a glass sphere floating over a dark plane with soft lighting.
Create effects from presets or raw GLSL, build custom 3D scenes, compose multi-layer scenes, add text overlays, and get embed code for any platform.
list_presets to find available preset IDs.u_time, u_resolution, u_mouse) are injected automatically.rebuild_scene when done.rebuild_scene when done.rebuild_scene when done.rebuild_scene when done.rebuild_scene when done.rebuild_scene when done.Everything you need to know about writing custom 3D scenes. This is the runtime your code runs in.
Your code exports a default setup function that receives a context object and returns an animate function called every frame.
export default function setup(ctx) { const { scene, camera, renderer, clock, mouse, THREE } = ctx; const geometry = new THREE.IcosahedronGeometry(1, 3); const material = new THREE.MeshPhysicalMaterial({ transmission: 0.95, roughness: 0.05, color: '#88ccff' }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); return function animate(time, delta) { mesh.rotation.y = time * 0.3; mesh.position.y = Math.sin(time) * 0.2; }; }
ctxThe context object passed to your setup function.
| Property | Type | Notes |
|---|---|---|
| scene | THREE.Scene | Pre-configured with RoomEnvironment IBL for PBR reflections |
| camera | THREE.PerspectiveCamera | Default position [0, 0, 5], configurable FOV |
| renderer | THREE.WebGLRenderer | ACES filmic tone mapping |
| clock | THREE.Clock | Standard Three.js clock |
| mouse | { x, y } | Normalized 0–1, bottom-left origin |
| THREE | namespace | Full Three.js r170 (0.170.0) |
fetch, XMLHttpRequest, or WebSocket. No eval or Function constructor. No localStorage or sessionStorage. No DOM manipulation except document.createElement for procedural canvas textures. Code max size: 100KB.
Camera position and FOV can be set via create_3d_scene params (cameraPosition, cameraFov) or inside your code with camera.position.set() and camera.lookAt(). Code-level settings override the params.
Copy these into Claude Code or Cursor. Each produces a deployable 3D scene.
A translucent glass sphere with PBR reflections, gently spinning and bobbing.
Create a 3D scene with a glass morphism sphere floating in the center. Use MeshPhysicalMaterial with high transmission and low roughness. Add a subtle rotation and floating animation.
Animated retro grid with bloom post-processing and a glowing horizon.
Create a synthwave landscape: an infinite neon grid plane receding into the distance with a glowing sun on the horizon. Use LineSegments for the grid, animate it scrolling toward the camera. Purple and cyan color scheme.
A dense spiral galaxy of colored particles with smooth rotation.
Create a particle galaxy with 50,000 points arranged in a spiral arm pattern. Color gradient from blue at center to pink at edges. Slow rotation animation. Use PointsMaterial with size attenuation.
A chrome torus knot with environment reflections and slow rotation.
Create a metallic torus knot with MeshPhysicalMaterial. Set metalness to 1.0 and roughness to 0.1 for a chrome look. Add slow Y-axis rotation and a subtle float animation on the Y position.
Use the get_embed_code tool to get a ready-to-paste snippet for your platform.
<style> [data-refract-wrap] { position: relative; width: 100%; aspect-ratio: 16 / 9; overflow: hidden; } </style> <div data-refract-wrap> <iframe data-refract src="https://refract.build/embed/your-id" style="position:absolute;inset:0;width:100%;height:100%;border:none;" loading="lazy" allow="autoplay" ></iframe> </div>