Hot Deploys for Themes & Extensions

How the new deploy MCP endpoints work.

Squilla v0.1.0 ships core.theme.deploy and core.extension.deploy — two MCP tools that take a base64-encoded zip archive and unpack it into themes/<slug>/ or extensions/<slug>/ via an atomic directory swap, all without a server restart. This post explains how they work and when to reach for them.

The shape of a deploy call

core.theme.deploy({
  body_base64: "…<base64 of zip>…",
  activate:    true
})

The archive must contain a theme.json (at root or one level deep) declaring a unique slug. The kernel writes the bytes to a temp directory, validates the manifest, then atomically renames the temp into themes/<slug>/. If activate=true, it immediately activates: layouts and blocks load, the seed runs, and any pending settings update.

What happens for extensions

Same pattern. The kernel:

  1. Unpacks the zip into a temp dir
  2. Validates extension.json and finds plugin binaries declared under manifest.plugins[].binary
  3. Chmods those binaries to 0755 (so the kernel can spawn them)
  4. Atomically renames the temp into extensions/<slug>/
  5. Upserts the database row
  6. If activate=true, runs HotActivate: pending migrations, plugin spawn, script load, block load — no server restart

Caveats worth knowing

  • 50 MB cap on the archive. Trim asset bundles aggressively before encoding.
  • No cross-compile. Plugin binaries must already match the host's OS/arch. Build them in the same target as the running container.
  • Slug rules. [A-Za-z0-9_-]+. Re-deploying the same slug overwrites in place — there's no per-version directory.

When to use it

Three cases:

  1. Out-of-repo themes. A designer ships a theme directory; you encode and deploy without committing to the kernel repo.
  2. CI deploys without container rebuilds. Build the theme or extension in a CI job, deploy via MCP. The container image stays unchanged.
  3. Live debugging. Push a patched extension into a running staging environment in seconds.

For day-to-day local development, you probably don't need it — the fs watcher already picks up new directories dropped into themes/ or extensions/, and make theme handles the local hot-deploy loop. But for any deploy that crosses a process or container boundary, the MCP tools are the path.

← all posts