Skip to main content
Glama

Snowstorm MCP

Local MCP server and Windows editor for authoring Minecraft Blockbuster 1.12.2 particles. It combines a Blockbuster-safe JSON editor, a local Snowstorm preview, GIF/MP4 export, and a reference-video workflow for recreating VFX.

Snowstorm is used for simulation only. The server preserves blockbuster:* extensions when files are edited, and never treats a Snowstorm preview as proof of Minecraft rendering.

Features

  • Create, inspect, patch and validate .particle.json files.

  • Query selected fields across many particles and patch a preflighted batch with coordinated rollback.

  • Preserve Blockbuster fields when the Snowstorm editor saves a file.

  • Validate particle, texture, selector and MagicSpells links as one package graph.

  • Classify gameplay-only MagicSpells helpers without requiring fake particle selectors; report TargetedMultiSpell delays as non-blocking warnings.

  • Merge selector fragments into an instance file with conflict reporting, dry-run artifacts, digest checks and backups.

  • Inspect or retime a MagicSpells .MultiSpell without rewriting unrelated definitions.

  • Render deterministic single-particle or absolute-timeline scene previews as PNG, GIF or MP4.

  • Compose a scene with per-layer camera cuts, a solo layer, in-memory layer overrides and activity-derived sample times.

  • Probe Molang values at explicit ages with per-field, absolute-bound and cross-field assertions.

  • Inspect real particle PNGs side by side on a checkerboard with their declared dimensions.

  • Generate nine measured texture primitives, import PNGs into configured shared banks, browse a texture catalogue and calculate flipbook UVs from real images.

  • Switch among configured projects at runtime with project_list and project_use; existing flat single-project configs remain supported.

  • Open a selected particle in a secure local Electron window.

  • Expose the built-in Blockbuster/Snowstorm authoring guide and effect design briefs to MCP clients.

  • Import source videos into an automatically managed folder, then analyze them with FFmpeg scene detection.

  • Generate JPEG contact sheets, a JSON manifest and individual frames named with millisecond timecodes.

  • Extract decoded frames at requested HH:MM:SS.mmm targets and report their decoded PTS for vision-capable AI review.

Related MCP server: pixelbolt

Requirements

  • Windows 10 or later.

  • Node.js 22.12 or newer.

  • FFmpeg and FFprobe available on PATH.

  • Git, for cloning Snowstorm as a submodule.

Installation

git clone --recurse-submodules https://github.com/frabous/snowstorm-mcp.git
Set-Location snowstorm-mcp
npm install
npx install-electron
npx playwright install chromium
Copy-Item snowstorm-mcp.config.example.json snowstorm-mcp.config.json
npm run build
npm test

GitHub's Download ZIP does not include the vendor/snowstorm submodule, which is required by the preview and editor. Clone with the command above. If you already cloned without submodules, run git submodule update --init --recursive from the repository root.

Edit snowstorm-mcp.config.json so its paths target your package. The provided local configuration is intentionally ignored by Git; it may point to a private Minecraft instance.

The legacy flat configuration describes one project and continues to work. To switch projects without restarting, use the registry format below. Adding or changing project definitions on disk requires a restart; selecting one of the already configured projects does not.

Example layout:

my-package/
  particles/
  resourcepack/
  selectors.json
  spell.yml

MCP Client Configuration

The npm package provides a snowstorm-mcp executable for local stdio. After version 0.3.0 is published, clients can launch it with npx --yes snowstorm-mcp@0.3.0; set SNOWSTORM_MCP_CONFIG to the absolute path of the selected project configuration. If unset, the server looks for snowstorm-mcp.config.json in the MCP process's current working directory. For a source checkout, use node <repository>/dist/mcp.js instead.

The npm/npx installation does not download Playwright's Chromium browser automatically. Install the matching browser once with the Playwright version pinned by this package:

npm exec --yes --package=playwright@1.63.0 -- playwright install chromium

Claude Code

Use user scope to make the server available across Claude Code projects, or choose a narrower scope if preferred:

claude mcp add --scope user --transport stdio --env "SNOWSTORM_MCP_CONFIG=C:\path\to\my-project\snowstorm-mcp.config.json" snowstorm-mcp -- npx --yes snowstorm-mcp@0.3.0
claude mcp list

In a Claude Code session, run /mcp to inspect the connection and tools.

Codex CLI

Codex CLI, the Codex IDE extension and the ChatGPT desktop app share the Codex MCP configuration:

codex mcp add snowstorm-mcp --env "SNOWSTORM_MCP_CONFIG=C:\path\to\my-project\snowstorm-mcp.config.json" -- npx --yes snowstorm-mcp@0.3.0
codex mcp list

OpenCode

Add this entry to OpenCode's mcp configuration. The same shape works in a project opencode.json or the user's global OpenCode configuration:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "snowstorm-mcp": {
      "type": "local",
      "command": ["npx", "--yes", "snowstorm-mcp@0.3.0"],
      "environment": {
        "SNOWSTORM_MCP_CONFIG": "C:\\path\\to\\my-project\\snowstorm-mcp.config.json"
      },
      "enabled": true,
      "timeout": 120000
    }
  }
}

Use opencode mcp list to verify the server. Restart the client after changing its configuration.

Copy-paste setup prompt for an AI agent

Give the following prompt to Claude Code, Codex CLI, OpenCode or another computer-use/coding agent to set up Snowstorm MCP on your machine:

Set up this Snowstorm MCP installation on my machine.

Source checkout (if needed for a local fallback): <absolute path to snowstorm-mcp>
Particle project(s): <absolute path(s) to my package(s), or ask me to identify them>
Clients to configure: detect Claude Code, Codex CLI, OpenCode and other installed MCP clients; configure each one I approve.

Work through these steps and report what you did:
1. Inspect the operating system, shell, repository, existing MCP configuration files, and installed client versions. Use each client's current official documentation for its exact config location, command syntax, scope and verification command. Do not assume that another client's JSON format applies. This project documents Windows support; if the OS is different, explain the MCP-only limitations before proceeding.
2. Check Node.js (version 22.12 or newer), npm, FFmpeg and FFprobe availability, and check Git if cloning the repository or restoring submodules is needed. Check whether project dependencies are installed, Playwright's Chromium is available, and `dist/mcp.js` exists. Install missing prerequisites using the operating system's trusted package manager or official sources, then verify each command is available. If an install needs administrator privileges or a permanent PATH change, explain the exact action and ask me before proceeding; do not silently skip it.
3. Inspect `snowstorm-mcp.config.schema.json` and the package layout. Ask me for any missing or ambiguous particle, resource-pack, selector, instance-selector, spell or artifact paths. Never invent project paths. Keep secrets out of files, logs and chat.
4. Create or update `snowstorm-mcp.config.json` only after showing me the proposed values. Use the legacy flat format for one project or the registry format for several projects. Keep every path valid. Add `../library/textures` to `sharedTextureBanks` only when that directory exists in this layout; otherwise use `[]`. Preserve an explicit `sharedTextureBanks` list if I have one. Set `instanceSelectorsFile` only to the real instance selectors file.
5. Follow the Installation section's commands for any missing local setup: run `npm install` and, for a source checkout, `npx install-electron` as needed. Install Chromium with the matching command above (`npx playwright install chromium` in a source checkout, or the pinned `npm exec --yes --package=playwright@1.63.0 -- playwright install chromium` command for npm/npx use). Then run `npm run build` and `npm test`, and fix setup-related failures before continuing. Do not run any tool that writes particles, selectors, textures or other game assets during setup.
6. Check whether `snowstorm-mcp@0.3.0` is available on npm. If so, configure the local stdio command as `npx --yes snowstorm-mcp@0.3.0`; otherwise use `node <absolute-repository-path>/dist/mcp.js` from the existing checkout and tell me the npm release is not published yet. Set `SNOWSTORM_MCP_CONFIG` to the absolute config path. For each approved client, merge one server entry without removing or rewriting unrelated settings. Choose user/global or project/local scope only after checking the client's behavior and confirming my preference. Back up an existing client config before editing it.
7. Start a fresh client session and use that client's documented MCP status/list command. Verify the server exposes its tools, call `project_list`, then run `particle_list` only if the selected project path is valid. Do not call a mutating tool as a connection test.
8. Summarize configured clients and scopes, files changed, exact verification results, and any remaining issue. Leave private per-machine config files uncommitted.

The npx-installed server includes Snowstorm for rendering but does not bundle Electron. particle_open_desktop requires the source checkout with Electron installed in the MCP repository. The project configuration may remain in a separate Minecraft project directory.

Project Registry and Shared Texture Banks

The flat configuration remains supported for one project. For several projects, use a registry with the project identifier as each key. sharedTextureBanks belongs at registry level and applies to every configured project:

{
  "$schema": "./snowstorm-mcp.config.schema.json",
  "activeProject": "spell-a",
  "sharedTextureBanks": [],
  "projects": {
    "spell-a": {
      "projectName": "spell-a",
      "particlesRoot": "../spell-a/particles",
      "resourcePackRoot": "../spell-a/resourcepack",
      "selectorsFile": "../spell-a/selectors.json",
      "instanceSelectorsFile": "../spell-a/config/metamorph/selectors.json",
      "spellFile": "../spell-a/spell.yml",
      "artifactsRoot": "./.snowstorm-mcp/artifacts/spell-a"
    },
    "spell-b": {
      "projectName": "spell-b",
      "particlesRoot": "../spell-b/particles",
      "resourcePackRoot": "../spell-b/resourcepack",
      "selectorsFile": "../spell-b/selectors.json",
      "spellFile": "../spell-b/spell.yml",
      "artifactsRoot": "./.snowstorm-mcp/artifacts/spell-b"
    }
  }
}

Use project_list to see configured keys and the active project, then project_use to switch immediately. Add instanceSelectorsFile when selectors_merge should default to the real instance selectors file; a live merge requires write: true, dryRun: false and the inspected SHA-256 digest. Omitted sharedTextureBanks defaults to no shared banks. When needed, configure each bank explicitly; paths are relative to the configuration file, and ../library/textures is only appropriate when that directory exists in your layout.

texture_generate writes to the project resource pack unless a configured bank is selected. texture_import copies a PNG into a configured bank. texture_list shows the winning source and particles using each texture; project textures take precedence over shared-bank duplicates.

Particle Workflow

  1. Call particle_design_brief, or request one focused topic from particle_authoring_guide.

  2. Use particle_query to compare only the required fields across references. It collapses common values.

  3. Call particle_create, particle_patch, or dry-run particle_patch_batch before executing the batch.

  4. Run particle_verify_package. Use detail: "full" only when the timeline rows are needed.

  5. Use particle_probe for motion or scale claims, then particle_render_scene for the relevant absolute-time window.

  6. Test the final effect in Minecraft. Snowstorm evidence does not prove Blockbuster behavior.

For timing-only changes, inspect with spell_timeline_inspect, then call spell_retime with its digest. Starts can be supplied in ticks or seconds and must align to the configured tick grid.

Example projected query:

{
  "nameContains": "shockwave",
  "select": {
    "count": "/particle_effect/components/minecraft:emitter_rate_instant/num_particles",
    "lifetime": "/particle_effect/components/minecraft:particle_lifetime_expression/max_lifetime"
  },
  "collapseCommon": true
}

particle_render_scene accepts explicit {file, startSeconds, position} layers or derives layers, absolute starts and static helper offsets from the configured MagicSpells graph. Camera coordinates accept finite numbers or numeric strings. Render windows are capped at 30 seconds, 750 frames and a 480-million rendered-pixel budget. The result includes compact lifecycle checks, a contact sheet, a report and an optional GIF/MP4.

Snowstorm builds its particle material with depth writing enabled, and every quad of an emitter shares one unsorted buffer, so overlapping quads stencil each other with hard straight edges that do not occur in Minecraft. depthWrite: false is therefore the default, and grid: false hides the ground grid and origin axes, which exist only in the preview. Both settings are reported back in caveats. A straight contour that survives with depthWrite: false is the particle texture's own alpha, not a compositing artefact.

particle_patch refuses to replace a numeric field with a bare numeric string such as "9". Such a value is a valid Molang literal, so it cannot be caught by semantic validation, and MCP clients sometimes send numbers as strings. Fields that already hold a quoted number are still rendered correctly.

shots cuts the camera across the window, so a sequence that needs one framing near the caster and another at 26 blocks no longer has to compromise on a single camera. solo renders one layer alone, which is how a composited artefact is attributed. A layer's overrides are applied in memory and are never written, so a throwaway diagnostic variant cannot end up in the delivery folder; the result names every overridden layer and says so in caveats. Omit sampleTimes and they are derived from each layer's own start, midpoint and tail, and sampleTimesSource reports which happened.

Texture Inspection

texture_contact_sheet renders up to 16 real PNGs on a checkerboard with their dimensions, bytes and alpha flag. It is the only view that separates an artwork defect from a compositing artefact: a hard straight contour on a tile is the texture's own alpha, and it survives a scene render with depthWrite disabled.

texture_generate writes a named PNG into the project resource pack or a selected shared bank. It supports soft_lens, anime_cloud, faceted_crystal, bokeh_disc, puff, ember, streak, lightning and beam_core. The soft_lens primitive measures decoded pixels and refuses a bright-frame coverage below 35%. texture_list catalogs project and bank assets by name, dimensions, alpha, coverage and usage. texture_import validates and copies an external PNG into a configured bank without overwriting existing files. flipbook_atlas calculates its UV values from the actual dimensions of a resolved PNG.

Texture metrics and Snowstorm previews help inspect assets; they do not prove Minecraft playback. Pre-colored textures generally need a neutral tint, and generated PNGs still need to be checked in the target game.

{
  "textures": [
    "b.a:particles/serious_punch/cloud_sheet",
    "b.a:particles/serious_punch/tunnel_ring"
  ]
}

Probing Claims

particle_probe maps an alias to a JSON Pointer, and assertions reference the alias. A JSON pointer in field is rejected by name.

{
  "file": "serious_punch_tunnel_rings.particle.json",
  "select": {
    "size": "/particle_effect/components/minecraft:particle_appearance_billboard/size",
    "alpha": "/particle_effect/components/minecraft:particle_appearance_tinting/color/3"
  },
  "samples": [{ "age": 0.2 }, { "age": 0.9 }, { "age": 1.6 }],
  "assertions": [
    { "field": "size", "sampleIndexes": [0, 1, 2], "metric": "length", "direction": "increasing" },
    { "field": "size", "sampleIndexes": [0, 2], "metric": "length", "maxValue": 20 },
    { "combine": { "op": "multiply", "fields": ["size", "alpha"] }, "sampleIndexes": [0, 1, 2], "metric": "value", "maxValue": 4 }
  ]
}

minValue and maxValue are absolute bounds, which is what a "must not swallow the camera" or "must not white out" invariant actually needs; minRatio and maxRatio remain relative to the first sample. combine reduces several fields into one series, so a cross-field invariant such as particle count times alpha needs no local checker.

particle_authoring_guide embeds the Snowstorm/Blockbuster skill directly in the MCP. Request one of workflow, components, blockbuster, motion, textures, magicspells, validation or reference-video to minimize context; omit topic only when the AI needs the complete guide.

Video Reference Workflow

referenceVideosRoot is optional. When omitted, the MCP creates and manages:

.snowstorm-mcp/artifacts/reference-videos/

Give the AI the path to a source video. It calls video_import, which copies it into the managed directory without changing the original file. Then use the returned file value with video_analyze:

{
  "sourcePath": "D:\\references\\my-vfx-reference.mp4"
}

The result includes file, for example my-vfx-reference.mp4. Call:

{
  "file": "my-vfx-reference.mp4",
  "samples": 12
}

video_analyze returns:

  • An inline JPEG contact sheet for an MCP client with vision support.

  • contact-sheet.jpg on disk.

  • manifest.json containing duration, resolution, detected scene times and every extracted frame path.

  • Frame names such as frame-03-00-00-12.500.jpg.

For a closer VFX transition, call video_extract_frames. It reports both the requested target and the actual decoded frame PTS, since frames only exist at real stream timestamps:

{
  "file": "megumin-reference.mp4",
  "timecodes": ["00:00:12.500", "00:00:12.750", "00:00:13.000"]
}

For audio-led timing, use video_audio_transients. It ranks high-pass attacks in a bounded mixed-audio window; these are candidate timings, not isolated SFX recognition. Use video_compare after a scene render to make a reference-left/Snowstorm-right MP4 with the reference audio retained. It only reads preview MP4s inside the MCP artifact root and writes its output under .snowstorm-mcp/artifacts/comparisons/.

{
  "file": "megumin-reference.mp4",
  "previewPath": "C:\\project\\.snowstorm-mcp\\artifacts\\scenes\\run\\scene.mp4",
  "referenceStartSeconds": 32,
  "durationSeconds": 4.5
}

The server places generated video artifacts under .snowstorm-mcp/artifacts/video/, leaving source videos and existing reference images untouched. Scene detection selects visual discontinuities; it does not identify VFX semantics, layers or camera effects by itself.

Desktop Editor

npm run desktop

Open a particular particle with:

npx electron . "C:\full\path\to\effect.particle.json"

The Save safely control merges Snowstorm's output with the prior Blockbuster document and creates a backup under .snowstorm-mcp/artifacts/backups.

MCP Tools

Tool

Purpose

particle_list / particle_inspect / particle_query

Compact inventory, source inspection and projected multi-file reads.

particle_create / particle_patch / particle_patch_batch

Safe single-file writes or preflighted batches with best-effort rollback.

particle_validate / particle_verify_package

Semantic particle and complete package-graph checks.

spell_timeline_inspect / spell_retime

Strict MagicSpells timeline reading and timing-only edits.

particle_probe

Numeric Molang samples with per-field, absolute-bound and cross-field assertions.

particle_render / particle_render_scene

Single-particle or deterministic multi-layer previews, with camera cuts, solo layers and in-memory overrides.

selectors_merge

Dry-run or digest-checked additive merge of a package selectors fragment into the configured instance file.

texture_generate / texture_import

Generate measured texture primitives or copy an external PNG into a shared bank.

texture_list / flipbook_atlas / texture_contact_sheet

Browse assets and their usage, compute UV values, or inspect PNGs on a checkerboard.

project_list / project_use

Inspect configured projects and switch the active one without restarting.

particle_open_desktop

Electron editor.

particle_authoring_guide / particle_design_brief

Embedded Snowstorm authoring knowledge.

video_import

Copy a user-provided video into the automatic managed directory.

video_list

Discover imported reference videos.

video_analyze

Scene-aware frames, contact sheet and manifest.

video_audio_transients

Mixed-track high-pass attack candidates for timing.

video_extract_frames

Targeted timecode extraction with decoded PTS reporting.

video_compare

Side-by-side reference/preview MP4 with reference audio.

Security and Limits

The server confines configured particle, texture and reference-video paths, rejects traversal including symlink escapes, serializes MCP writes, and creates backups. Batch writes lock every target, verify every digest before mutation and attempt every rollback if a rename fails. New texture assets publish atomically without replacing an existing file. If a process crashes while holding a file lock, the next write reports the lock path; remove it only after confirming no Snowstorm MCP writer is still running. A process crash can still interrupt a multi-file commit, so retained backups remain the recovery source. Do not run it against folders writable by untrusted local processes.

Generated previews validate the local Snowstorm simulator only. Verify texture blending, anchors, collisions, selector links, MagicSpells timing and performance inside Minecraft before shipping.

License

This project is GPL-3.0-or-later because it vendors Snowstorm, which is GPL-3.0-or-later. Snowstorm source is retained in vendor/snowstorm; see NOTICE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Author, validate, preview, and render motion-graphics videos from a single JSON document (Clipkit Protocol). 16 tools with in-chat PNG previews, captions, templated promos, and hand-off to a free browser editor by link.
    16
    19
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Enables agents to author, validate, inspect, patch, and render editable JSON pixel-art and animation recipes through local tools, producing PNG contact sheets, APNGs, sprite atlases, and related export bundles.
    8
    437 npm
    14
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to model, sculpt, rig, animate and bake particle effects by editing a semantic scene document, with built-in software rendering, measurable critics that flag floating or broken geometry, and game-ready glTF export. It exposes templates, atomic edit batches, motion and effect previews, undo history, and no GPU, browser, or Blender required.
    0
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables creating and editing pixel art, sprites, sprite sheets, tiles, icons, particle and fluid effects, and short animations from editable JSON recipes, exporting as PNG, GIF, APNG, or video frames while working only with local project files.
    437 npm
    MIT