ext-apps/examples/shadertoy-server
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Olivier Chafik cce8d5c7a3
docs: add MCP client configuration to example READMEs
Add stdio transport configuration snippets near the top of each example
README to help users quickly set up the servers in their MCP clients.

- Node.js examples use npx with the published npm packages
- Python qr-server uses uv with local path
- Removed Claude Desktop-specific references from qr-server
2026-01-16 14:00:57 +00:00
..
src feat(shadertoy): show fullscreen button only on widget hover, add min-height (#281) 2026-01-15 14:15:17 +00:00
.gitignore Improve consistency and organization of examples for AI learning 2026-01-13 20:48:02 -06:00
grid-cell.png feat(basic-host): URL params, fullscreen mode, unified layout (#266) 2026-01-14 22:09:41 +00:00
main.ts feat: compile example servers to JavaScript for npm consumption (#259) 2026-01-14 23:46:17 +00:00
mcp-app.html feat(shadertoy): add fullscreen support + ditch insets for max visual effect (#278) 2026-01-15 13:01:55 +00:00
package.json chore: bump version to 0.4.1 (#282) 2026-01-15 16:11:53 +00:00
README.md docs: add MCP client configuration to example READMEs 2026-01-16 14:00:57 +00:00
screenshot.png feat(shadertoy): add fullscreen support + ditch insets for max visual effect (#278) 2026-01-15 13:01:55 +00:00
server.ts fix(examples): resolve DIST_DIR path for npm package execution (#277) 2026-01-15 12:23:13 +00:00
tsconfig.json Add shadertoy-server example for WebGL shader rendering (#226) 2026-01-12 18:26:02 +00:00
tsconfig.server.json feat: compile example servers to JavaScript for npm consumption (#259) 2026-01-14 23:46:17 +00:00
vite.config.ts Add shadertoy-server example for WebGL shader rendering (#226) 2026-01-12 18:26:02 +00:00

Example: ShaderToy Server

A demo MCP App that renders ShaderToy-compatible GLSL fragment shaders in real-time using WebGL 2.0 and ShaderToyLite.js.

Gradient Kaleidoscope Kaleidoscope

MCP Client Configuration

Add to your MCP client configuration (stdio transport):

{
  "mcpServers": {
    "shadertoy": {
      "command": "npx",
      "args": [
        "-y",
        "--silent",
        "--registry=https://registry.npmjs.org/",
        "@modelcontextprotocol/server-shadertoy",
        "--stdio"
      ]
    }
  }
}

Features

  • Real-time Rendering: Renders GLSL shaders using WebGL 2.0
  • ShaderToy Compatibility: Uses the standard mainImage(out vec4 fragColor, in vec2 fragCoord) entry point
  • Multi-pass Rendering: Supports buffers A-D for feedback effects, blur chains, and simulations
  • Standard Uniforms: iResolution, iTime, iTimeDelta, iFrame, iMouse, iDate, iChannel0-3

Running

  1. Install dependencies:

    npm install
    
  2. Build and start the server:

    npm run start:http  # for Streamable HTTP transport
    # OR
    npm run start:stdio  # for stdio transport
    
  3. View using the basic-host example or another MCP Apps-compatible host.

Tool Input Examples

Gradient with Time:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;
    fragColor = vec4(uv, 0.5 + 0.5*sin(iTime), 1.0);
}

Tool input:

{
  "fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;
    fragColor = vec4(uv, 0.5 + 0.5*sin(iTime), 1.0);
}"
}

Kaleidoscope:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    float segments = 6.0;
    float zoom = 1.0 + 0.3 * sin(iTime * 0.2);
    float angle = atan(uv.y, uv.x) + iTime * 0.3;
    float r = length(uv) * zoom;
    angle = mod(angle, 6.28 / segments);
    angle = abs(angle - 3.14 / segments);
    vec2 p = vec2(cos(angle), sin(angle)) * r;
    p += iTime * 0.1;
    float v = sin(p.x * 10.0) * sin(p.y * 10.0);
    v += sin(length(p) * 15.0 - iTime * 2.0);
    v += sin(p.x * 5.0 + p.y * 7.0 + iTime);
    vec3 col = 0.5 + 0.5 * cos(v * 2.0 + vec3(0.0, 2.0, 4.0) + iTime);
    fragColor = vec4(col, 1.0);
}

Tool input:

{
  "fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    float segments = 6.0;
    float zoom = 1.0 + 0.3 * sin(iTime * 0.2);
    float angle = atan(uv.y, uv.x) + iTime * 0.3;
    float r = length(uv) * zoom;
    angle = mod(angle, 6.28 / segments);
    angle = abs(angle - 3.14 / segments);
    vec2 p = vec2(cos(angle), sin(angle)) * r;
    p += iTime * 0.1;
    float v = sin(p.x * 10.0) * sin(p.y * 10.0);
    v += sin(length(p) * 15.0 - iTime * 2.0);
    v += sin(p.x * 5.0 + p.y * 7.0 + iTime);
    vec3 col = 0.5 + 0.5 * cos(v * 2.0 + vec3(0.0, 2.0, 4.0) + iTime);
    fragColor = vec4(col, 1.0);
}"
}

Interactive Julia Set (mouse controls the fractal's c parameter):

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y * 2.5;
    vec2 mouse = (iMouse.xy / iResolution.xy - 0.5) * 2.0;
    vec2 c = mouse;
    vec2 z = uv;
    float iter = 0.0;
    for (int i = 0; i < 100; i++) {
        z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
        if (dot(z, z) > 4.0) break;
        iter++;
    }
    float t = iter / 100.0;
    vec3 col = 0.5 + 0.5 * cos(3.0 + t * 6.28 * 2.0 + vec3(0.0, 0.6, 1.0));
    if (iter == 100.0) col = vec3(0.0);
    fragColor = vec4(col, 1.0);
}

Tool input:

{
  "fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y * 2.5;
    vec2 mouse = (iMouse.xy / iResolution.xy - 0.5) * 2.0;
    vec2 c = mouse;
    vec2 z = uv;
    float iter = 0.0;
    for (int i = 0; i < 100; i++) {
        z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
        if (dot(z, z) > 4.0) break;
        iter++;
    }
    float t = iter / 100.0;
    vec3 col = 0.5 + 0.5 * cos(3.0 + t * 6.28 * 2.0 + vec3(0.0, 0.6, 1.0));
    if (iter == 100.0) col = vec3(0.0);
    fragColor = vec4(col, 1.0);
}"
}

Architecture

Server (server.ts)

Exposes a single render-shadertoy tool that accepts:

  • fragmentShader: Main Image shader code (required)
  • common: Shared code across all shaders (optional)
  • bufferA: Buffer A shader, accessible as iChannel0 (optional)
  • bufferB: Buffer B shader, accessible as iChannel1 (optional)
  • bufferC: Buffer C shader, accessible as iChannel2 (optional)
  • bufferD: Buffer D shader, accessible as iChannel3 (optional)

App (src/mcp-app.ts)

  • Receives shader code via ontoolinput handler
  • Uses ShaderToyLite.js for WebGL rendering
  • Displays compilation errors in an overlay