# io.github.brac/particlr-mcp (npm · @particlr/mcp)

Agents author particlr .prt particle effects headlessly: validate, simulate, render to PNG, patch.

- Trust score: 61/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-04

## Components

- npm · `@particlr/mcp`: 61/100 (this document), [markdown](https://verifymcp.io/servers/brac-particlr-mcp/particlr-mcp.md), [page](https://verifymcp.io/servers/brac-particlr-mcp/particlr-mcp)

## Channel facts

- Registry: `npm`
- Package: `@particlr/mcp`
- Version: `0.1.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-04.

- **Supply Chain Security**: 83/100
  - No malware found by supply-chain analysis.
  - CVE check failed: a known medium-severity CVE affects hono 4.12.33, reached via @modelcontextprotocol/sdk > hono. A fixed version is available.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (96 of 100), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 19/100
  - Repository check failed: no source repository is declared.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 4 days ago).
  - Security-disclosure policy not yet verified: we couldn't inspect the source repository.
- **Schema Quality & AI Usability**: 84/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 1404 tokens (~117/item across 12 items; 9 tools + 3 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### Claude

```bash
claude mcp add brac-particlr-mcp -- npx -y @particlr/mcp
```

### Codex

```bash
codex mcp add brac-particlr-mcp -- npx -y @particlr/mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "brac-particlr-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@particlr/mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add brac-particlr-mcp --command npx --arg -y --arg @particlr/mcp
```

### Hermes

```yaml
mcp_servers:
  brac-particlr-mcp:
    command: "npx"
    args: ["-y", "@particlr/mcp"]
```

### Other

```json
{
  "mcpServers": {
    "brac-particlr-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@particlr/mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-04 (score 61, −1)

- [security regression] CVE-2026-69207 affects this package: medium
- [security regression] Known CVEs: partial → fail

### 2026-08-03 (score 62, +26)

- [security regression] Provenance: unverified → fail
- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [functional improvement] Schema quality: unverified → excellent
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional] Licence: MIT

### 2026-08-02 (score 36, +10)

- [security improvement] Malware scan: unverified → pass
- [security] Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional regression] Capabilities: pass → unverified

### 2026-08-01 (score 26, −2)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 28)

First indexed and scored.

## MCP tools (9)

### `validate_effect` (~98 tokens)

Validate Effect

Validate a .prt document (JSON string) against the real parse -> migrate -> validate pipeline. Returns ok + the canonical normalized doc + schemaVersion (and the pre-migration version), or structured, path-anchored errors worded for you to fix.

Input parameters:

- `doc` (string): The .prt document as a JSON string.
- `handle` (string): A handle from open_effect — use instead of doc to avoid resending the document.

Output parameters:

- `errors` (array)
- `migratedFrom` (number|null): The doc's ORIGINAL schemaVersion if it was migrated up, else null.
- `normalizedDoc` (string|null): Canonical serializeParticle() output on success (agents iterate on this); null on failure.
- `ok` (boolean)
- `schemaVersion` (number|null): The doc's schemaVersion after migration; null when parsing failed.
- `warnings` (array)

### `simulate_effect` (~206 tokens)

Simulate Effect

Deterministically step a .prt effect in Node (no rendering) and report per-layer live counts over time, peak vs capacity, spatial bounds, completion, and a statehash plus the exact {seed, dt, steps} to reproduce it. Same seed + dt sequence => identical output. Validates first; an invalid doc returns validate-shaped errors.

Input parameters:

- `doc` (string): The .prt document as a JSON string.
- `dt` (number): Fixed timestep. Default 1/60; clamped to (0, 0.05] (the runtime MAX_DT).
- `duration` (number): Seconds to simulate. Default 3; capped at 60.
- `handle` (string): A handle from open_effect — use instead of doc to avoid resending the document.
- `sampleInterval` (number): Seconds between count samples. Default 0.1.
- `seed` (integer): Override the doc's authored seed. Default: the doc's seed.

Output parameters:

- `bounds`: Axis-aligned bounds over every live particle across the run; null if none ever spawned.
- `completed` (boolean): True if the effect reached isDone (one-shots); false for looping/unfinished.
- `completionTime` (number|null): Seconds at which isDone first held; null if never.
- `echo` (object): The exact inputs used after defaulting/clamping — replay these for an identical statehash.
- `layers` (array)
- `statehash` (string): hex8 FNV-1a over the final public sim state — reproducible per {seed, dt, steps}.
- `warnings` (array)

### `list_presets` (~32 tokens)

List Presets

List the shipped .prt presets (name, layer count, schemaVersion) — the few-shot authoring corpus.

Output parameters:

- `presets` (array)

### `get_preset` (~61 tokens)

Get Preset

Fetch one shipped preset by name (stem): its raw .prt text plus a parsed summary. Unknown name returns an error listing the valid names.

Input parameters:

- `name` (string, required): The preset filename stem (see list_presets), e.g. "explosion".

Output parameters:

- `doc` (string): The preset's raw .prt JSON text.
- `name` (string)
- `summary` (object)

### `get_reference` (~104 tokens)

Get Reference

Fetch reference material inline: topic "format-spec" (the .prt format spec, markdown) or "schema" (the JSON Schema for a .prt document).

Input parameters:

- `topic` (string, required): "format-spec" = the .prt format spec (markdown); "schema" = the JSON Schema for a .prt document; "authoring-guide" = how to author a .prt that LOOKS good (units, blend/layer/curve/trail recipes, comm…

Output parameters:

- `format` (string)
- `text` (string)
- `topic` (string)

### `render_effect` (~512 tokens)

Render Effect

CPU-rasterize a .prt effect to PNG image(s): by default one contact-sheet PNG of 16 frames evenly spaced over [0, completion||duration], auto-framed. All builtin + embedded-PNG textures, all five blend modes, flipbook, stretch/velocity-align/flip, per-particle + connect-ribbon TRAILS, and layer draw order are rendered; DISSOLVE is NOT rasterized (a dissolve doc still renders its sprites). Deterministic: frames snap to the same 1/60 trajectory as simulate_effect. Returns image block(s) + a renderHash, the snapped times, the viewport, and the grid. An invalid doc returns validate-shaped errors.

Input parameters:

- `background` (string): Background: "checker" (default), "transparent", or a hex color (#rgb / #rrggbb / #rrggbbaa).
- `doc` (string): The .prt document as a JSON string.
- `fps` (number): Frames at 0, 1/fps, 2/fps … up to the range end. Overrides `frames`.
- `frames` (integer): Number of evenly-spaced frames over [0, completion||duration]. Default 16; max 64.
- `handle` (string): A handle from open_effect — use instead of doc to avoid resending the document.
- `height` (integer): Frame height in px. Default 256; cap 1024 longest edge.
- `layout` (string): "sheet" (default): one contact-sheet PNG. "separate": one PNG per frame (same caps).
- `overrunSeconds` (number): Render past the loop seam: extends the frames/fps time range to duration + overrunSeconds. Looping docs only; ignored (with a warning) otherwise. Explicit `times` already accept any time.
- `seed` (integer): Override the doc's authored seed. Default: the doc's seed.
- `supersample` (number): Anti-alias by rendering at 2x/4x then downsampling. Default off (crisp, byte-golden).
- `times` (array): Explicit render times in seconds (snapped to 1/60 boundaries). Max 64. Overrides frames/fps.
- `viewport` (object): Explicit world-space viewport. Auto-framed from a bounds scan (+12% margin) when omitted.
- `width` (integer): Frame width in px. Default 256; cap 1024 longest edge.

Output parameters:

- `completionTime` (number|null)
- `frameHeight` (integer)
- `frameWidth` (integer)
- `grid`: Contact-sheet grid; null in separate mode.
- `imageCount` (integer)
- `layout` (string)
- `renderHash` (string): hex8 over normalizedDoc + seed + snapped times + size + viewport + bg — distinct from the sim statehash.
- `snappedTimes` (array): The actual step-snapped render times (seconds).
- `viewport` (object)
- `warnings` (array)

### `open_effect` (~111 tokens)

Open Effect

Validate a .prt document and store it under a session handle so you can iterate without resending the text. Returns the handle + validate fields (ok, schemaVersion, warnings, errors); pass the handle to patch_effect / validate_effect / simulate_effect / render_effect. Handles live only for this session (server process); they do not survive a reconnect. Capped at 64 per session.

Input parameters:

- `doc` (string, required): The .prt document as a JSON string. Validated and stored under a fresh handle.

Output parameters:

- `errors` (array)
- `handle` (string|null): A session handle ("fx-1", …) to pass as `handle` to patch/validate/simulate/render; null on failure.
- `migratedFrom` (number|null): The doc's ORIGINAL schemaVersion if it was migrated up, else null.
- `ok` (boolean)
- `schemaVersion` (number|null)
- `warnings` (array)

### `patch_effect` (~156 tokens)

Patch Effect

Apply a small list of RFC 6902 ops (replace/add/remove) to a stored effect, then re-validate. Iterate by sending only the diff, not the whole document. Any failure — bad path/index or a post-patch validation error — rolls back: the stored doc is left unchanged and the failing op index is named. Handles live only for this session (server process); they do not survive a reconnect.

Input parameters:

- `handle` (string, required): A handle from open_effect.
- `ops` (array, required): Restricted RFC 6902 ops (replace/add/remove) applied IN ORDER (max 64). Any failure — bad path, bad index, or a post-patch validation error — rolls back: the stored doc is unchanged.

Output parameters:

- `errors` (array)
- `handle` (string|null): A session handle ("fx-1", …) to pass as `handle` to patch/validate/simulate/render; null on failure.
- `migratedFrom` (number|null): The doc's ORIGINAL schemaVersion if it was migrated up, else null.
- `ok` (boolean)
- `schemaVersion` (number|null)
- `warnings` (array)

### `get_effect` (~58 tokens)

Get Effect

Fetch the canonical stored .prt text for a handle — use this for final delivery/export after iterating. Handles live only for this session (server process); they do not survive a reconnect.

Input parameters:

- `handle` (string, required): A handle from open_effect.

Output parameters:

- `doc` (string): The canonical stored .prt text — for final delivery/export.
- `handle` (string)

## Diagnostics

Captured diagnostic sections: Provenance, Vulnerabilities, Dependencies. The full working is on the page: https://verifymcp.io/servers/brac-particlr-mcp/particlr-mcp#diagnostics

## Score history

- 2026-08-04: 61
- 2026-08-03: 62
- 2026-08-02: 36
- 2026-08-01: 26
- 2026-07-30: 28

## Links

- npm package: https://www.npmjs.com/package/@particlr/mcp
- Socket report: https://socket.dev/npm/package/@particlr/mcp
- Website: https://particlr.com/
- Changelog RSS feed: https://verifymcp.io/servers/brac-particlr-mcp/particlr-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/brac-particlr-mcp/particlr-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/brac-particlr-mcp/particlr-mcp
