AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Synapse

mcp-josephoibrahim-synapse · by JosephOIbrahim

Talk to Houdini in plain English. SYNAPSE lives inside Houdini's own Python and turns your words into real, undoable nodes - one Ctrl+Z reverses a whole operation, and a human approves anything risky. It says 'unknown' instead of guessing. 120+ tools, 6,000+ tests, Houdini 22.0.400. Limitations documented, not omitted.

No reviews yet
0 installs
25 views
0.0% view→install

Install

$ agentstack add mcp-josephoibrahim-synapse

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-josephoibrahim-synapse)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Synapse? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

An AI agent that runs inside Houdini — not beside it.

Read Known limitations first — this repo's habit is saying what doesn't work.

SYNAPSE lives in Houdini's own Python interpreter and calls hou.* directly.No external bridge, no RPC hop, no second copy of the scene.

v5.45.1 · Houdini 22.0.400 (doc pin — the symbol gate re-stamps per running build) · Python 3.13 · USD 0.26.5 · PySide6


For artists — the one-minute version

You type what you want. Real nodes appear in your scene — built, wired, and named. "Give me a Vellum cloth setup on this mesh" becomes actual nodes, not a chat answer.

One Ctrl+Z undoes the whole thing. Every operation is grouped, so a ten-node build reverses in a single undo. You can always get your scene back.

It asks before anything risky. Writing files, big changes — a human clicks approve. It never bakes gigabytes to disk on its own.

It says "I don't know" instead of guessing. Unmeasured things are reported as unknown, never invented. When something isn't supported yet, it tells you so.

It is not magic and not a render button. Read [Known limitations](#known-limitations) — this project's habit is saying what doesn't work before you find out mid-shot.


Watch it work

[](https://vimeo.com/1216840044)

SYNAPSE in practice: plain English in, undoable nodes out.


Runs your model

Five engines behind one seam. The roster and the producer path are the same thing: python/synapse/panel/providers/.

Ollama needs no API key, and nothing leaves the machine. SYNAPSE talks to your local server at its default address, http://localhost:11434.

Your pick persists. Engine choice is saved to .synapse/panel_settings.json and survives restarts.


The one design choice

Everything else follows from where the agent lives.

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#4d4d4d','primaryTextColor':'#FFFFFF','primaryBorderColor':'#000000','lineColor':'#000000','textColor':'#FFFFFF','secondaryColor':'#404040','tertiaryColor':'#333333','clusterBkg':'#333333','clusterBorder':'#000000','edgeLabelBackground':'#333333','nodeTextColor':'#FFFFFF'}}}%%
flowchart LR
    subgraph OUT["outside-in"]
        H1[Houdini] -->|whole scene, every turn| C1[cloud model]
        C1 -->|answer| H1
    end
    subgraph IN["inside-out — SYNAPSE"]
        H2[Houdini] --> A[agent in-process]
        A -->|only what you asked about| C2[cloud model]
        C2 --> A
        A -->|acts in place| H2
    end

Measured, not claimed. Grounding payload across a 13 → 25,850 node ladder rises 443 → 113,411 tokens. That is 256× — not flat. The same probe without depth bounds rises 2,788×.

The honest statement: cost scales with what you ask about, not with the size of your scene.

The mechanism is bounded depth. Single-call coverage falls to 10% on the largest scenes, with 100% completeness inside the window it reads. There is currently no delta path — every inspect is a full re-read.

Producer: harness/notes/token_bench/, 2026-07-27. Proxy tokenizer, no live-model arm.


Known limitations

Read this here rather than discover it mid-shot.

synapse_inspect_scene does not return over the external MCP surface. It hangs to the idle timeout. The function itself is instantaneous when called directly — 0.08s for the whole of a 5,764-node scene — so the fault is in the main-thread marshal under MCP, not in introspection. The panel's WebSocket path is unaffected and is demonstrated working on that same scene.

The retrieval corpus is Houdini 21 documentation. Symbols and node types are H22 and verified; the prose is not yet converted. Most consequential for Copernicus.

No delta path. Every inspect is a full re-read. Re-asking about the same thing costs the same again.

A render can be stopped, but not from RopNode. No cancel method exists there. hou.ActiveRender is documented, #status: ni, and absent at runtime. SYNAPSE now stops renders through rkill (render_stop), with two limits worth knowing:

  • Only background renders can be stopped — those are the only ones rps can see. A foreground, in-process render is not reachable.
  • Only Karma/husk renders can be stopped by ROP path. A mantra render shows up in rps as the bare word mantra with no node identity, so SYNAPSE refuses to guess which one is yours and asks for an explicit PID instead.

Stopping a mantra render leaves a valid-looking but empty frame. mantra writes the EXR header to the real output path immediately and keeps pixels in a .mantra_checkpoint sidecar, so a stopped render leaves a ~1KB EXR that opens fine and contains no image. A "does the file exist?" check will pass it. Detect it by the leftover .mantra_checkpoint, or by a header missing renderTime. Stopping a Karma render is safe — husk only writes the declared output on completion, so it simply never appears.

The chat-time UI grip is closed (v5.40.1). Mid-chat node-selection freezes — the bridge-down Qt-fallback class — no longer fire; tool calls and context-gather run off the main thread. See The chat freeze, and what fixed it below. Distinct from the render freezes covered there.

execute_python results are stringified over the live WS. A dict comes back as its Python repr ("result": str(result)). Parse with ast.literal_eval; a handler-side fix is queued but needs a Houdini restart to go live, so the client-side parse is the current contract. Found by the bench's first live contact, 2026-08-02.

The PDG rollback has never executed. bridge.py:1718 passes remove_files=; the real keyword is remove_outputs. It raises TypeError every time.

41 node types in use are deprecated — 39 of them deprecated in the docs while the runtime says nothing, so a probe alone cannot see them.

Emergency halt is surfaced, and the shipped mechanism alone was not enough. It now lives in the panel's overflow as a control distinct from Stop. Worth knowing why it is not just a button on the old function: EmergencyProtocol.trigger_emergency_halt walks /obj only. Probed against a real cook at /tasks/h3b_topnet on 22.0.368 it returned ALL_OPERATIONS_HALTED in 0.0s and the cook was still running three seconds later — and /tasks is where TOP networks live by default. The halt handler therefore does its own scene-wide sweep and reports the three results separately: what the bridge halt did, which TOP networks it then cancelled, and which background renders are still running (it does not kill those — rkill * would reach renders this session never started).

Node grounding is uneven, and the shape of it changed. 603 Copernicus, LOP and Cop2 types now carry build-pinned reference from nodes.zip — but that is what a node is, not how to use it together. Workflow prose is still H21. And 88 live types ship with no help page at all, so documentation cannot ground them by any method. 37.9% of LOP parameters are documented — the ceiling from documentation alone.

Token figures are proxy-measured, and no genuine outside-in comparison has been built.


What it knows, and where that comes from

This matters more than the feature list, and it is the thing to check first.

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#4d4d4d','primaryTextColor':'#FFFFFF','primaryBorderColor':'#000000','lineColor':'#000000','textColor':'#FFFFFF','secondaryColor':'#404040','tertiaryColor':'#333333','clusterBkg':'#333333','clusterBorder':'#000000','edgeLabelBackground':'#333333','nodeTextColor':'#FFFFFF'}}}%%
flowchart TD
    K[what SYNAPSE knows] --> S[symbols and node types]
    K --> N[H22 node reference]
    K --> P[prose and how-to]
    S --> S1["h22_symbol_table.json35,908 symbols, re-stamped per build"]
    S --> S2["connectivity_22.jsonlop_solaris_knowledge_22.json"]
    N --> N1["rag/corpus/h22_nodes.json603 live types, 22.0.368"]
    P --> P1["rag/skills/houdini21-referenceH21 documentation"]
    S1 --> OK["verified against the running buildgate goes STALE if they diverge"]
    S2 --> OK
    N1 --> OK
    P1 --> GAP["NOT yet converted to H22"]

Symbols are H22. The table is stamped against the running build, and phantom_gate_status goes stale if they diverge.

Node reference is H22. Extracted from nodes.zip — the reference that ships with the build — and every entry validated by probing its documented type against the running catalogue. Only matched entries are written, so a phantom is never stored rather than filtered at read time.

Prose is H21. The retrieval corpus is Houdini 21 documentation, accurately labelled as such. If you ask a how-to question, SYNAPSE may answer from H21 material and tell you so.

And the Copernicus gap is now closed on the node axis. It was the sharpest hole in this diagram — Copernicus barely existed in H21, so prose could never cover it. Ask about chromakey or grunge_rust by name and you get a build-pinned answer. Ask how to composite and you still get H21 prose.


What it does

Builds networks. Ask for a Solaris scene, a material graph, a COP chain — it wires the nodes and tells you what it chose.

Explains itself. Every mutation records what it did and why.

Stays on the main thread. All hou.* calls marshal to Houdini's main thread.

Says no when it can't. This took four fixes in one day (2026-08-02), all the same disease — a green light that couldn't report failure. get_health now carries write_plane (it used to say healthy over a dead write path); composition_valid carries a real verdict (it had zero assignment sites — an integrity anchor that could never fail); operations that fail before validation say so instead of inheriting "ran and passed"; and value-only edits the reduced hash cannot see are counted as unobservable_deltas rather than vanishing. Producers: commits 68ab53e, 57c4ec6, 73284e1; pinned by tests/test_write_plane_health.py (26), tests/test_stage_exceeds_cache_and_composition_valid.py (13), tests/test_r306_reduced_mode_surfacing.py (19).

Writes memory on a fresh scene. The first memory_write on an unsaved scene used to die with WinError 5$JOB points into Houdini's install bin/, which the seat can't write. Scene memory now resolves a writable address (discovery still reads the raw $JOB root, so studio show-configs keep working). Verified end-to-end on the live seat, twice, against a captured cold-boot baseline. Producer: scripts/live_probes/probe_g1_acceptance_ws.pyVERDICT: PASS.

Refuses to boot on a render nodenarrowly. hou.isUIAvailable() gates the daemon, the Fork Bomb guard. But it protects a component with no production callers today while other surfaces boot headless. A guard that exists, not a guarantee that holds.

The full claim, unpacked

This is the package description in long form — everything the one-liner compresses.

115 tools, two paths. The full safety set (undo-wrapped, reversible, provenance-recorded) rides the audited /mcp bridge path. The direct /synapse path is RBAC-gated, main-thread-marshalled execution with observe-only provenance. Scene mutations are undo-wrapped and reversible. Filesystem and network effects of executed code are not.

A registry-wide truth contract. A result may not claim an outcome the handler did not observe.

A self-improving utility flywheel. Proposed node-graphs are validated against probe-verified Houdini truth — node wiring plus Solaris/LOP context — before they build.

A five-engine chat panel. Switch between Claude, Google Gemini, NVIDIA Nemotron, local Ollama, and any custom OpenAI-compatible endpoint. Raw-stdlib providers, no vendor SDK.

Pipeline citizenship. Tokens stay raw, per-frame render paths, OCIO color-managed previews, per-show config.

Studio operability. Rotating logs, synapse_doctor diagnostics + bundle, env-var conformance, bounded autonomy with a stop control that takes effect between operations, an upgrade runbook, egress + key-provisioning docs.

A two-tier audit trail. Tier-0 Floor hook + the agent.usd Ledger.

Crash-atomic escrowed memory. And a process-wide stall-detection chain (detect → breaker → emergency-halt report) that reports and degrades rather than unblocking a parked session.

Verified end-to-end on Houdini 22.0.368. 22.0.400: symbol-stamped 2026-08-09 (35,908 symbols, gate armed); e2e re-verification pending — see docs/SUPPORT_MATRIX.md.


Install

Four steps. The third is the one people miss.

1 — Clone

git clone https://github.com/JosephOIbrahim/Synapse.git

2 — Package file

python scripts/install_synapse_package.py

Writes the package file — Documents/houdini22.0/packages/synapse.json — for you, correctly encoded.

SYNAPSE ships two installers, and the split matters: scripts/install_synapse_package.py installs the package file (this step); install.py installs the shelf, panel, and icons. Order: package file first, then install.py.

3 — Verify

python scripts/install_synapse_package.py --verify

Read-only. Prints pass/fail per requirement.

4 — Doctor

With the server up, run the synapse_doctor tool — ask the panel, or call it from any connected MCP client. Diagnostics plus a support bundle (see Studio operability, above). Registered in mcp_server.py; implemented in python/synapse/server/doctor.py.

Manual install — write the package file by hand

At Documents/houdini22.0/packages/synapse.json:

{
    "name": "synapse",
    "enable": true,
    "env": [
        { "var": "SYNAPSE_ROOT", "value": "C:/path/to/Synapse" },
        {
            "var": "PYTHONPATH",
            "value": ["$SYNAPSE_ROOT/python", "$SYNAPSE_ROOT"],
            "method": "prepend"
        }
    ],
    "hpath": "$SYNAPSE_ROOT/houdini"
}

Three things that bite

Save the JSON without a BOM. PowerShell's Set-Content -Encoding utf8 writes one. Houdini's parser rejects it silently.

# writes a BOM - Houdini will not load this
Set-Content synapse.json $text -Encoding utf8

# no BOM
[System.IO.File]::WriteAllText($path, $text, (New-Object System.Text.UTF8Encoding $false))

hpath, not path. On H22 the keyword is hpath — SideFX use it exclusively in their own packages. The deprecated path still works, which is why nobody notices.

PYTHONPATH needs both entries. shared/ lives at the repo root, not under python/.

Get any of these wrong and import synapse still succeeds, the version still prints, and the panel never appears. No error. Just absence.


First prompt

Nothing to set up beyond Install. Fresh empty scene. No OCIO. No demo scaffold. No harness runner.

  1. Open Houdini — new, empty scene.
  2. Open the SYNAPSE panel.
  3. Type:

> Make me simple terrain — a grid displaced with mountain noise.

This prompt maps to a recipe the panel ships with — mountain_displace in python/synapse/panel/recipe_book.py: a 100×100 grid SOP wired into a mountain SOP (height 1.5). Two nodes, one connection.

What you'll see: a terrain-like displaced surface in the viewport. That visible bump-scape is the proof the install worked — no test suite required.

Looking for the full staged walkthrough instead? That's demo/README.md — the staged demo, which does carry pipeline prerequisites (OCIO, the demo hip).


Troubleshooting

The panel didn't appear.

Run the doctor first: the synapse_doctor tool, callable from any connected MCP client — no panel required (registered in mcp_server.py, implemented in python/synapse/server/doctor.py).

Why there's no error message to read: get the package file wrong — a BOM, path instead of hpath, a missing PYTHONPATH entry — and import synapse still succeeds, the version still prints, and **the p

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.