shade-mcpSAFE
MCP dev tools for Noisemaker and Portable shader effects
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Open source from Noise Factor · more projects
MCP server for shader effect development.
Distilled from three projects:
- [noisemaker](https://noisemaker.app/) — browser-based shader testing
- [portable](https://github.com/noisefactorllc/portable) — portable effect authoring
- [shade](https://shade.noisedeck.app) — agent-assisted shader editing
Requirements
- Node.js 22 or newer
- A viewer page for the seven viewer-driven browser tools;
runDslProgramneeds a Noisemaker checkout. See Viewer.
Quick Start
npm install # installs dependencies and builds dist/ npm run setup # install Playwright Chromium (browser tools only)
Using shade-mcp with noisemaker or portable? See docs/SETUP.md for step-by-step configuration.
Viewer
The browser tools use Chromium. Seven control a viewer page that hosts the renderer; runDslProgram creates a fresh renderer on a blank page for each call. shade-mcp does not include a viewer. Set SHADE_VIEWER_ROOT to the smallest directory containing the viewer and its imported modules. For the seven viewer tools, the page must expose the renderer through window globals. Set SHADE_GLOBALS_PREFIX to match those globals. runDslProgram uses a fresh renderer independently of the viewer globals and SHADE_VIEWER_PATH. By default it imports Noisemaker source modules from /shaders/src/index.js and assets from /shaders under SHADE_VIEWER_ROOT. For Portable's built-in Noisemaker DSL, set SHADE_DSL_RENDERER_MODULE=https://shaders.noisedeck.app/1/noisemaker-shaders-core.esm.js, SHADE_DSL_ASSETS_BASE=https://shaders.noisedeck.app/1, and SHADE_DSL_USE_BUNDLES=true; keep it
b3f4c6b76e3fOBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add shade-mcp --env ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} --env OPENAI_API_KEY=${OPENAI_API_KEY} -- npx -y [email protected]{
"mcpServers": {
"shade-mcp": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}",
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
}
}
}
}Exposed tools (19)
19 read · 0 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
Points | read | d |
analyzeBranching | read | Analyze unnecessary shader branching with AI. Return optimization suggestions. |
analyzeEffect | read | Return the full definition, shader source, uniforms, and passes for an effect. |
benchmarkEffectFPS | read | Measure achieved FPS, jitter, and frame timing statistics against a target frame rate. |
checkAlgEquiv | read | Compare the semantics of GLSL/WGSL pairs with AI. Flag divergent algorithms. Ignore syntax differences. |
checkEffectStructure | read | Detect these effect issues:\n- unused files\n- broken references\n- naming violations\n- leaked or undefined uniforms\n- missing descriptions\n- structural parity issues\n- GLSL name collisions: uniforms versus functions, reserved words, or built-in shadowing. |
compareShaders | read | Compare shader structure: function names, uniform declarations, and line counts. This tool does not require AI. |
compileEffect | read | Compile a shader effect. Return diagnostics for each pass. Use comma-separated effect IDs for a batch. |
describeEffectFrame | read | Render a frame. Analyze the image with AI vision, using the prompt that the user supplies. |
generateManifest | read | Scan the effects directory to rebuild the effect manifest. |
listEffects | read | List all effects, optionally filtered by namespace. |
renderEffectFrame | read | Render one frame. Compute mean RGB, variance, and monochrome/blank detection. Optionally capture a PNG. |
runDslProgram | read | Compile Noisemaker DSL with optional authored Portable packages in a fresh renderer and return a multi-frame, per-surface PNG grid with metrics. |
searchEffects | read | Search the effect library by concept, tag, algorithm, or visual style. The tool expands the query with synonyms. |
searchShaderKnowledge | read | Search curated shader documentation by meaning: DSL grammar, GLSL techniques, effect patterns, and common errors. |
searchShaderSource | read | Search GLSL source code across all effects with a regular expression. Return matching snippets with context. |
testNoPassthrough | read | Check that a filter effect modifies the input it consumes. Compares the rendered output with the bound input texture (skipping a feedback read of the effect |
testPixelParity | read | Render with both WebGL2 and WebGPU. Compare the output pixel by pixel within the epsilon tolerance. |
testUniformResponsiveness | read | For each uniform control the tool finds two values that differ from the value the loaded program set: a range control |
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- declared (2 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (9)
return `http://127.0.0.1:${activePort}`const { file, dir } = writeDef(`import { Effect } from '../../../src/runtime/effect.js'const { file, dir } = writeDef(`import { Effect } from '../../../src/runtime/effect.js'const { file, dir } = writeDef(`import { stdEnums } from '../../../src/lang/std_enums.js'expect(() => resolveEffectDir('../../../../etc/ssl', tmpEffects)).toThrow(/invalid effect id/i)const res = await fetch(`${url}/effects/../../etc/passwd`)# runner makes so exfil/C2 from a compromised dependency is detectable.
expect(url).not.toBe('http://127.0.0.1:43117')@anthropic-ai/sdk, @modelcontextprotocol/sdk, acorn, openai, playwright, zod, @types/node, tsup
Gates applied: no_behavioural_pass.
b3f4c6b76e3ffull audit observations/trust-audit/mcp-server/noisefactorllc__shade-mcp.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | b3f4c6b76e3f | SAFE | B | 89 | first audit |
Questions
What is the shade-mcp MCP server?
MCP dev tools for Noisemaker and Portable shader effects
What tools does shade-mcp expose?
19 in total: 19 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is shade-mcp safe to connect to an agent?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B.
What credentials does shade-mcp need?
It reads ANTHROPIC_API_KEY and OPENAI_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does shade-mcp run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as shade-mcp at 0.4.11.
How current is this page?
The grade is for one exact copy of the source (b3f4c6b76e3f), read on 2026-10-11. The repository is watched and re-audited when it changes.