Skip to main content
Glama

scratch-mcp

An MCP server for Assimilate SCRATCH / Live FX, generated at startup from Assimilate's published OpenAPI file. No hand-written tools. Read-only by default.

This is the server we used in Can an agent drive SCRATCH from the REST API alone? — the evaluation found that an agent given only the REST docs did as well as one given these generated tools, so the honest pitch for this repo is not "you need this." It is:

  • Scoping. Today's SCRATCH REST server exposes reads, writes, deletes and shutdown on one flat surface, and in our tests the model reached for the destructive call first, every time. readonly and safe modes filter the surface before the agent ever sees it.

  • Convenience. If your agent host speaks MCP and not raw HTTP, this is a 100-line way in.

Quick start

Requires Python 3.11+ and a running SCRATCH / Live FX (9.9 b1205+) with the HTTP server enabled in System Settings.

git clone https://github.com/jmeadlock/scratch-mcp
cd scratch-mcp
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt

export ASSIM_BASE=http://localhost:8080/APIV2   # your SCRATCH host
python server.py --list                         # see what readonly exposes
python server.py                                # stdio MCP, readonly

Modes

Mode

Tools

What's in it

readonly (default)

48

every GET

safe

114

everything except DELETE, /application/shutdown, /application/restart, /application/render/deletemedia/*, and writes to /system

full

145

the whole API, including deletes and shutdown

python server.py --mode safe
python server.py --mode full --transport http --port 8765

Counts are from SCRATCH REST 1.1.0 / spec info.version 1.0.5. They'll change when the spec does.

Claude Desktop / Hermes / other MCP hosts

stdio config, e.g. for Claude Desktop's claude_desktop_config.json:

{
  "mcpServers": {
    "scratch": {
      "command": "/path/to/scratch-mcp/.venv/bin/python",
      "args": ["/path/to/scratch-mcp/server.py", "--mode", "readonly"],
      "env": { "ASSIM_BASE": "http://192.168.1.50:8080/APIV2" }
    }
  }
}

Environment

Var

Default

Notes

ASSIM_BASE

http://localhost:8080/APIV2

REST base including /APIV2

ASSIM_KEY

(empty)

optional access key, sent as raw Authorization: <key> (Assimilate's convention, not Bearer)

ASSIM_SPEC

spec/assimilate_rest_api.yaml

point at a newer YAML without editing the repo

A .env file next to server.py is read if present (never committed — see .gitignore).

Related MCP server: io.github.Airta-Admin/davinc-resolve-local-bridge-mcp

Things to know before you point an agent at it

Parameter names come straight from the spec. Tools want slot_idx, shot_uuid, queue_uuid — not index or id. In our eval the model guessed index eight times in a row and burned its call budget. If your agent host lets you add tool descriptions, that's the one hint worth adding.

Two requests crashed SCRATCH b1211 (macOS) during testing: POST /application/player/entershot/{…} with an unsubstituted path template, and POST /application/tools/lut with a model-composed body. Both are in full/safe mode. Nothing here guards against them; use readonly if you can't afford a relaunch.

GET /application/render can return 200 with an empty body. The generated tool handles it, but the agent will see an empty result and may re-query.

The spec is a snapshot. spec/assimilate_rest_api.yaml is copied from Assimilate's repo (MIT, see spec/LICENSE-Assimilate.txt) at commit 3236f85 (2026-08-03). To track upstream, replace the file or set ASSIM_SPEC.

How it works

server.py reads the YAML, overrides servers[0].url with ASSIM_BASE, builds an httpx.AsyncClient, and hands both to FastMCP.from_openapi() with a list of RouteMap rules for the chosen mode. That's it. Tool names are derived from operationIds (get-construct-current-slots → get_construct_current_slots).

License

MIT — see LICENSE. The bundled OpenAPI file is © Assimilate Inc, MIT, license preserved alongside it.

Related MCP Connectors

Related MCP Servers