@modelcontextprotocol/server-shadertoy 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -0
- package/dist/index.js +30583 -0
- package/dist/mcp-app.html +161 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.js +35834 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Example: ShaderToy Server
|
|
2
|
+
|
|
3
|
+
A demo MCP App that renders [ShaderToy](https://www.shadertoy.com/)-compatible GLSL fragment shaders in real-time using WebGL 2.0 and [ShaderToyLite.js](https://github.com/nickoala/ShaderToyLite).
|
|
4
|
+
|
|
5
|
+
<table>
|
|
6
|
+
<tr>
|
|
7
|
+
<td><a href="https://modelcontextprotocol.github.io/ext-apps/screenshots/shadertoy-server/01-gradient.png"><img src="https://modelcontextprotocol.github.io/ext-apps/screenshots/shadertoy-server/01-gradient.png" alt="Gradient" width="100%"></a></td>
|
|
8
|
+
<td><a href="https://modelcontextprotocol.github.io/ext-apps/screenshots/shadertoy-server/02-kaleidoscope.png"><img src="https://modelcontextprotocol.github.io/ext-apps/screenshots/shadertoy-server/02-kaleidoscope.png" alt="Kaleidoscope" width="100%"></a></td>
|
|
9
|
+
<td><a href="https://modelcontextprotocol.github.io/ext-apps/screenshots/shadertoy-server/03-fractal.png"><img src="https://modelcontextprotocol.github.io/ext-apps/screenshots/shadertoy-server/03-fractal.png" alt="Kaleidoscope" width="100%"></a></td>
|
|
10
|
+
</tr>
|
|
11
|
+
</table>
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Real-time Rendering**: Renders GLSL shaders using WebGL 2.0
|
|
16
|
+
- **ShaderToy Compatibility**: Uses the standard `mainImage(out vec4 fragColor, in vec2 fragCoord)` entry point
|
|
17
|
+
- **Multi-pass Rendering**: Supports buffers A-D for feedback effects, blur chains, and simulations
|
|
18
|
+
- **Standard Uniforms**: iResolution, iTime, iTimeDelta, iFrame, iMouse, iDate, iChannel0-3
|
|
19
|
+
|
|
20
|
+
## Running
|
|
21
|
+
|
|
22
|
+
1. Install dependencies:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Build and start the server:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run start:http # for Streamable HTTP transport
|
|
32
|
+
# OR
|
|
33
|
+
npm run start:stdio # for stdio transport
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. View using the [`basic-host`](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-host) example or another MCP Apps-compatible host.
|
|
37
|
+
|
|
38
|
+
### Tool Input Examples
|
|
39
|
+
|
|
40
|
+
**Gradient with Time:**
|
|
41
|
+
|
|
42
|
+
```glsl
|
|
43
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
44
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
45
|
+
fragColor = vec4(uv, 0.5 + 0.5*sin(iTime), 1.0);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
_Tool input:_
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
54
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
55
|
+
fragColor = vec4(uv, 0.5 + 0.5*sin(iTime), 1.0);
|
|
56
|
+
}"
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Kaleidoscope**:
|
|
61
|
+
|
|
62
|
+
```glsl
|
|
63
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
64
|
+
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
|
|
65
|
+
float segments = 6.0;
|
|
66
|
+
float zoom = 1.0 + 0.3 * sin(iTime * 0.2);
|
|
67
|
+
float angle = atan(uv.y, uv.x) + iTime * 0.3;
|
|
68
|
+
float r = length(uv) * zoom;
|
|
69
|
+
angle = mod(angle, 6.28 / segments);
|
|
70
|
+
angle = abs(angle - 3.14 / segments);
|
|
71
|
+
vec2 p = vec2(cos(angle), sin(angle)) * r;
|
|
72
|
+
p += iTime * 0.1;
|
|
73
|
+
float v = sin(p.x * 10.0) * sin(p.y * 10.0);
|
|
74
|
+
v += sin(length(p) * 15.0 - iTime * 2.0);
|
|
75
|
+
v += sin(p.x * 5.0 + p.y * 7.0 + iTime);
|
|
76
|
+
vec3 col = 0.5 + 0.5 * cos(v * 2.0 + vec3(0.0, 2.0, 4.0) + iTime);
|
|
77
|
+
fragColor = vec4(col, 1.0);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
_Tool input:_
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
86
|
+
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
|
|
87
|
+
float segments = 6.0;
|
|
88
|
+
float zoom = 1.0 + 0.3 * sin(iTime * 0.2);
|
|
89
|
+
float angle = atan(uv.y, uv.x) + iTime * 0.3;
|
|
90
|
+
float r = length(uv) * zoom;
|
|
91
|
+
angle = mod(angle, 6.28 / segments);
|
|
92
|
+
angle = abs(angle - 3.14 / segments);
|
|
93
|
+
vec2 p = vec2(cos(angle), sin(angle)) * r;
|
|
94
|
+
p += iTime * 0.1;
|
|
95
|
+
float v = sin(p.x * 10.0) * sin(p.y * 10.0);
|
|
96
|
+
v += sin(length(p) * 15.0 - iTime * 2.0);
|
|
97
|
+
v += sin(p.x * 5.0 + p.y * 7.0 + iTime);
|
|
98
|
+
vec3 col = 0.5 + 0.5 * cos(v * 2.0 + vec3(0.0, 2.0, 4.0) + iTime);
|
|
99
|
+
fragColor = vec4(col, 1.0);
|
|
100
|
+
}"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Interactive Julia Set** (mouse controls the fractal's c parameter):
|
|
105
|
+
|
|
106
|
+
```glsl
|
|
107
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
108
|
+
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y * 2.5;
|
|
109
|
+
vec2 mouse = (iMouse.xy / iResolution.xy - 0.5) * 2.0;
|
|
110
|
+
vec2 c = mouse;
|
|
111
|
+
vec2 z = uv;
|
|
112
|
+
float iter = 0.0;
|
|
113
|
+
for (int i = 0; i < 100; i++) {
|
|
114
|
+
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
|
|
115
|
+
if (dot(z, z) > 4.0) break;
|
|
116
|
+
iter++;
|
|
117
|
+
}
|
|
118
|
+
float t = iter / 100.0;
|
|
119
|
+
vec3 col = 0.5 + 0.5 * cos(3.0 + t * 6.28 * 2.0 + vec3(0.0, 0.6, 1.0));
|
|
120
|
+
if (iter == 100.0) col = vec3(0.0);
|
|
121
|
+
fragColor = vec4(col, 1.0);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
_Tool input:_
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
130
|
+
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y * 2.5;
|
|
131
|
+
vec2 mouse = (iMouse.xy / iResolution.xy - 0.5) * 2.0;
|
|
132
|
+
vec2 c = mouse;
|
|
133
|
+
vec2 z = uv;
|
|
134
|
+
float iter = 0.0;
|
|
135
|
+
for (int i = 0; i < 100; i++) {
|
|
136
|
+
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
|
|
137
|
+
if (dot(z, z) > 4.0) break;
|
|
138
|
+
iter++;
|
|
139
|
+
}
|
|
140
|
+
float t = iter / 100.0;
|
|
141
|
+
vec3 col = 0.5 + 0.5 * cos(3.0 + t * 6.28 * 2.0 + vec3(0.0, 0.6, 1.0));
|
|
142
|
+
if (iter == 100.0) col = vec3(0.0);
|
|
143
|
+
fragColor = vec4(col, 1.0);
|
|
144
|
+
}"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Architecture
|
|
149
|
+
|
|
150
|
+
### Server (`server.ts`)
|
|
151
|
+
|
|
152
|
+
Exposes a single `render-shadertoy` tool that accepts:
|
|
153
|
+
|
|
154
|
+
- `fragmentShader`: Main Image shader code (required)
|
|
155
|
+
- `common`: Shared code across all shaders (optional)
|
|
156
|
+
- `bufferA`: Buffer A shader, accessible as iChannel0 (optional)
|
|
157
|
+
- `bufferB`: Buffer B shader, accessible as iChannel1 (optional)
|
|
158
|
+
- `bufferC`: Buffer C shader, accessible as iChannel2 (optional)
|
|
159
|
+
- `bufferD`: Buffer D shader, accessible as iChannel3 (optional)
|
|
160
|
+
|
|
161
|
+
### App (`src/mcp-app.ts`)
|
|
162
|
+
|
|
163
|
+
- Receives shader code via `ontoolinput` handler
|
|
164
|
+
- Uses ShaderToyLite.js for WebGL rendering
|
|
165
|
+
- Displays compilation errors in an overlay
|