@modelcontextprotocol/server-shadertoy 0.4.1 → 1.0.0
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 +74 -19
- package/dist/index.js +3644 -44
- package/dist/mcp-app.html +45 -44
- package/dist/server.js +1748 -1733
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -10,11 +10,51 @@ A demo MCP App that renders [ShaderToy](https://www.shadertoy.com/)-compatible G
|
|
|
10
10
|
</tr>
|
|
11
11
|
</table>
|
|
12
12
|
|
|
13
|
+
## MCP Client Configuration
|
|
14
|
+
|
|
15
|
+
Add to your MCP client configuration (stdio transport):
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"mcpServers": {
|
|
20
|
+
"shadertoy": {
|
|
21
|
+
"command": "npx",
|
|
22
|
+
"args": [
|
|
23
|
+
"-y",
|
|
24
|
+
"--silent",
|
|
25
|
+
"--registry=https://registry.npmjs.org/",
|
|
26
|
+
"@modelcontextprotocol/server-shadertoy",
|
|
27
|
+
"--stdio"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Local Development
|
|
35
|
+
|
|
36
|
+
To test local modifications, use this configuration (replace `~/code/ext-apps` with your clone path):
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"shadertoy": {
|
|
42
|
+
"command": "bash",
|
|
43
|
+
"args": [
|
|
44
|
+
"-c",
|
|
45
|
+
"cd ~/code/ext-apps/examples/shadertoy-server && npm run build >&2 && node dist/index.js --stdio"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
13
52
|
## Features
|
|
14
53
|
|
|
15
54
|
- **Real-time Rendering**: Renders GLSL shaders using WebGL 2.0
|
|
16
55
|
- **ShaderToy Compatibility**: Uses the standard `mainImage(out vec4 fragColor, in vec2 fragCoord)` entry point
|
|
17
56
|
- **Multi-pass Rendering**: Supports buffers A-D for feedback effects, blur chains, and simulations
|
|
57
|
+
- **Mouse & Touch Interaction**: Full iMouse support with click detection (works on mobile)
|
|
18
58
|
- **Standard Uniforms**: iResolution, iTime, iTimeDelta, iFrame, iMouse, iDate, iChannel0-3
|
|
19
59
|
|
|
20
60
|
## Running
|
|
@@ -101,13 +141,20 @@ _Tool input:_
|
|
|
101
141
|
}
|
|
102
142
|
```
|
|
103
143
|
|
|
104
|
-
**Interactive Julia Set** (
|
|
144
|
+
**Interactive Julia Set** (click and drag to control the fractal's c parameter):
|
|
105
145
|
|
|
106
146
|
```glsl
|
|
107
147
|
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
108
148
|
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y * 2.5;
|
|
109
|
-
|
|
110
|
-
vec2 c
|
|
149
|
+
// Use mouse position if clicked, otherwise use animated default
|
|
150
|
+
vec2 c;
|
|
151
|
+
if (iMouse.z > 0.0) {
|
|
152
|
+
// Mouse is pressed - use mouse position
|
|
153
|
+
c = (iMouse.xy / iResolution.xy - 0.5) * 2.0;
|
|
154
|
+
} else {
|
|
155
|
+
// Not pressed - animate around an interesting region
|
|
156
|
+
c = vec2(-0.8 + 0.2 * sin(iTime * 0.5), 0.156 + 0.1 * cos(iTime * 0.7));
|
|
157
|
+
}
|
|
111
158
|
vec2 z = uv;
|
|
112
159
|
float iter = 0.0;
|
|
113
160
|
for (int i = 0; i < 100; i++) {
|
|
@@ -126,25 +173,33 @@ _Tool input:_
|
|
|
126
173
|
|
|
127
174
|
```json
|
|
128
175
|
{
|
|
129
|
-
"fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
176
|
+
"fragmentShader": "void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y * 2.5;\n vec2 c;\n if (iMouse.z > 0.0) {\n c = (iMouse.xy / iResolution.xy - 0.5) * 2.0;\n } else {\n c = vec2(-0.8 + 0.2 * sin(iTime * 0.5), 0.156 + 0.1 * cos(iTime * 0.7));\n }\n vec2 z = uv;\n float iter = 0.0;\n for (int i = 0; i < 100; i++) {\n z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;\n if (dot(z, z) > 4.0) break;\n iter++;\n }\n float t = iter / 100.0;\n vec3 col = 0.5 + 0.5 * cos(3.0 + t * 6.28 * 2.0 + vec3(0.0, 0.6, 1.0));\n if (iter == 100.0) col = vec3(0.0);\n fragColor = vec4(col, 1.0);\n}"
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Mouse & Touch Interaction
|
|
181
|
+
|
|
182
|
+
The `iMouse` uniform provides interactive input, compatible with the official Shadertoy specification:
|
|
183
|
+
|
|
184
|
+
| Component | When Button Down | After Release | Never Clicked |
|
|
185
|
+
| ----------- | ---------------------- | ---------------- | ------------- |
|
|
186
|
+
| `iMouse.xy` | Current position | Last position | `(0, 0)` |
|
|
187
|
+
| `iMouse.zw` | Click start (positive) | Negated (-x, -y) | `(0, 0)` |
|
|
188
|
+
|
|
189
|
+
**Detecting button state:**
|
|
190
|
+
|
|
191
|
+
```glsl
|
|
192
|
+
if (iMouse.z > 0.0) {
|
|
193
|
+
// Button/touch is currently held down
|
|
194
|
+
} else if (iMouse.z < 0.0) {
|
|
195
|
+
// Button was released (can use abs(iMouse.zw) for last click position)
|
|
196
|
+
} else {
|
|
197
|
+
// Never clicked - show default state or animate
|
|
145
198
|
}
|
|
146
199
|
```
|
|
147
200
|
|
|
201
|
+
Touch events are automatically supported for mobile devices.
|
|
202
|
+
|
|
148
203
|
## Architecture
|
|
149
204
|
|
|
150
205
|
### Server (`server.ts`)
|