Gaea is a media server for the Mac. It serves the Media Engine Spec (MES) Image, Audio, Video and Mesh (3D) profiles, and its models come as plugins:
- each plugin is a signed
.gaeapluginbundle that Gaea installs from a GitHub repo and runs in a process of its own; - Gaea does the MES front end, the queue, memory across processes, the plugins' lifecycle and the UI;
- the plugins do the generating.
Important
Gaea is alpha software in active development. Releases can still change how it behaves, so try it before you build on it, and read each release's notes before you update.
Download Gaea-<version>.zip from Releases, unzip it, and move
Gaea.app to Applications. It needs macOS 26 on Apple silicon, and it updates itself from these releases
(gaea update, or Settings → Updates). The command-line tool is Gaea.app/Contents/Helpers/gaea.
This is the operator's guide: one Mac running Gaea for the MES clients on it or on its network.
- As an app: open
Gaea.app. It lives in the menu bar, and its console has the Plugins, Models and System pages. Settings has the models root (General), adapters and updates. - Headless, for a studio Mac with no one at it:
Gaea.app/Contents/MacOS/Gaea --headless. Start it at login with a launch agent; an update relaunches it headless, on the same port and folder. - Where clients find it: MES on port 17630 (
--port), advertised over Bonjour (--no-advertisestops that).- Open, the default, it listens on this Mac only.
--pairedserves the network over TLS (--hostpicks the address). Each client pairs once: the app asks you, and a headless server with--approve-pairingsapproves every pairing, which is only for a network you trust.
- How it's configured: MES clients can't configure Gaea. You configure it in its console, Settings, and with
gaea, which talks to the running server over a socket on this Mac only (G-17). - Its folder is
~/Library/Application Support/Gaea:gaea.sqlite(plugins, models, trust, crashes and settings),Plugins/,Held/,Updates/,Crashes/and logs.GAEA_HOMEmoves it; keep that path short, because the socket's path is at most 103 bytes. - What it's doing:
gaea statusgives the server, plugins, workers, memory and crashes;gaea logsis Gaea's own log.
Every model is a plugin's. A plugin is a signed bundle from a GitHub repo, and each one runs in a process of its own.
- Adding one:
gaea plugins add https://github.com/xocialize-code/gaea-plugin-z-imageinstalls the newest full release (or… <version>) and turns it on. The plugins listed in this repo's CLAUDE.md are ours.GAEA_GITHUB_TOKEN=$(gh auth token)in Gaea's environment reads a private repo, and lifts GitHub's limit of 60 API calls an hour without a token, which a server with many plugins reaches when it checks them all. Gaea never stores the token. - Before anyone waits on one: a model's first job downloads any weights that aren't under the models root, then
loads them. A large model can take minutes; Z-Image's 19 GB took about nine on a fast connection.
gaea plugins addnames the weights it didn't find there.gaea plugins warm <id> [model] [lane]downloads and loads them now, so the next job starts at once.- A client that does wait is told, as MES progress stage
preparing: "downloading the weights (first use): 4.2 of 19.0 GB", then the load. The job'sx-gaea.worker.prepare_secondssays how long it took.
- Seeing them:
gaea pluginslists them, with each one's version, state and recent crashes.gaea plugins logs <id>shows its events and its worker's stderr. - Updates: Gaea reads every plugin's repo when it starts, and
gaea plugins checkreads them again.gaea plugins update <id> [version]installs the new version beside the current one, and switches when the plugin has no job.gaea plugins rollback <id>goes back to the version kept.- A release that needs a newer Gaea isn't offered.
- Switching off:
gaea plugins disable <id>keeps the plugin installed and takes its models out of what clients see;enablebrings them back.gaea plugins remove <id>uninstalls it. - Settings: a plugin's settings are on its row in the console's Plugins page, drawn from its manifest.
- On and off:
gaea modelslists every plugin's models. Research models and models whose licence needs accepting start off, andgaea models enable <id>turns one on. For a model whose licence asks each user to accept it too (LTX), clients see its terms and send their acceptance with the job; a job without it is refused withterms_not_accepted. - The models root is the one folder every plugin reads and downloads weights into: MLXEngine's store
(
~/Library/Application Support/MLXEngine/Models) unless you move it.gaea models root <folder>moves it, andgaea models root defaultgoes back. Settings → General does the same.--models-root <folder>moves it for one launch.- Workers restart when it changes, each one once its job ends.
- A model downloads its weights the first time a job needs them. Put the root on a fast volume: a plugin can refuse a lane whose weights sit on a volume too slow for it, and the warning says what it measured.
- Point it at the folder that holds the
models--org--namesnapshots themselves, not a folder above it. Otherwise every model downloads a copy of weights you already have.gaea modelsmarks a model whose default lane's weights it doesn't find under the root.
- Lanes: many models come in several quantizations ("lanes", such as bf16, int8, int4).
- Gaea loads a model's default lane when it fits in memory. Otherwise it loads the largest smaller lane that fits,
and the result carries a
lane_fallbackwarning naming both. gaea models lane <id> <lane>sets the default, and… defaultgoes back to the manifest's.- A request that names a lane (
x-gaea.lane) gets that lane or is refused; it never falls back.
- Gaea loads a model's default lane when it fits in memory. Otherwise it loads the largest smaller lane that fits,
and the result carries a
- Keeping a server to quick work (a preview server that has to keep up with many requests). Clients see each change
in the operations' descriptors, and a request past it is refused.
- Tiers: a plugin with tiers of very different cost ships each as its own model (LTX's compact24 … max128,
TRELLIS.2's 512, 1024 and 1536):
gaea models disable trellis2-1024turns one off, and the server offers only the qualities its remaining models serve. - Caps:
gaea models limit <id> <field> <value>narrows what a model takes, by MES limit name:max_megapixels,max_side,max_duration_s,max_frames,max_count,max_faces,max_texture_size,max_text_chars,max_source_sormax_layer_count. For example,gaea models limit klein-4b max_megapixels 4.2keeps Klein to 2048². A cap never widens what the plugin offers.… <field> noneremoves one, and… noneevery one. A mesh offer whose default is above a cap is made at the cap, withfaces_reducedortexture_reduced. - Lanes:
gaea models lanes <id> off <lane>switches a lane off. It's never chosen, not even as a fallback, and a request that names it is refused. The default moves to the next lane, and a model with every lane off isn't offered.… on <lane>switches it back. - The budget:
gaea budget <GB>(below).
- Tiers: a plugin with tiers of very different cost ships each as its own model (LTX's compact24 … max128,
TRELLIS.2's 512, 1024 and 1536):
- Adapters (LoRAs):
gaea adapterslists those the plugins ship and those you added.gaea adapters add <hf-url> --model <id>adds one from Hugging Face, pinned to its commit and sha256. One that needs accepting starts off, andgaea adapters enable <id>accepts its terms.
Gaea runs one GPU job at a time across all its plugins, and it keeps workers warm so the next job doesn't reload.
- The budget is three quarters of the Mac's memory unless the operator sets another.
gaea budget <GB>sets it now and for later launches, andgaea budget defaultgoes back.gaea budgetreads it and lists the models no lane of which fits.--budget-bytes Nsets one for a launch, and the operator's applies again from the next.- A model whose smallest lane doesn't fit isn't offered. Workers already running keep the ceiling they started with until they restart.
- Admission: Gaea admits each job against the budget, counting what every worker holds. When a job doesn't fit,
Gaea stops idle workers, least recently used first, to make room. A job that can't fit even then is refused with
no_capacity, and a model larger than the whole budget isn't offered. - Peaks: it learns each model's real peak from its runs, so a model that declares too little is charged what it used.
- Idle workers stop after 15 minutes, which frees their memory. A model then reloads on its next job (seconds,
from disk).
gaea workers idle <seconds>changes it (30 or more), andgaea workers idle defaultgoes back.--idle-secondssets it for one launch.gaea statusshows it.
- Clients see the policy:
GET /healthstates the idle unload (memory.idle_unload_s) and when each loaded model will be unloaded if it stays idle (resident_until), and every job's timings reportprepare_ms, the time it spent downloading or loading its model. - The ledger:
gaea ledgershows the budget, what each worker is charged and what it measures; the System page shows the same. - Wired memory: a worker keeps its weights wired while its job runs, as an in-process engine does, and lets them
go when the job ends. With one job at a time, that is never more than the job Gaea admitted.
GAEA_UNWIRED=1in Gaea's environment turns it off.
Gaea runs only plugins signed by a team you trust. It checks the signature, not the repo's URL, at install and again at every launch.
- Our team (Dustin Nielson, CFZS6RXUCP) is trusted from the start.
- A new team: its release is held, not installed. The console's Plugins page and
gaea trustshow the certificate's name, the team id, notarization and the repo.gaea trust approve <held-id>trusts the team and finishes the install. Later releases from that team then install without asking.gaea trust decline <held-id>drops the release.
- Removing a team:
gaea trust remove <team>stops its plugins and keeps them installed until you trust it again.
- Checks: Gaea checks its GitHub releases every six hours, and
gaea update --checkchecks now. Settings → Updates shows the same. - Gaea updates itself only while it runs. A copy that has been closed for a while is updated by starting it, then
gaea update. - Installing:
gaea update [<version>]downloads the release, checks its signature, notarization and sha256, and installs it once no job is running or waiting. It waits a minute after the last job (--update-grace), so that job's client can fetch its outputs, then swaps the app and relaunches. - Going back: the version it replaced is kept in
Updates/, andgaea update --rollbackgoes back to it.gaea update --canceldrops an update that is still waiting. - Pre-releases are off;
gaea update --prereleases onincludes them. - Plugin versions: an update that would drop a protocol version an installed plugin uses is refused, naming the plugin.
A worker that exits when Gaea didn't ask it to has crashed. Gaea records each crash.
- The job: a job whose worker crashed is run once more on a new worker. If that one crashes too, the job fails and its error names both crashes. A streamed job isn't run again.
- The record:
gaea crashes [<plugin>]lists them, newest first, andgaea crashes show <id>gives one in full:- the plugin, version, model, lane and job;
- the signal or exit code;
- the last lines the worker wrote;
- macOS's crash report, copied to
Crashes/and summarised (a SIGKILL writes none).
- Quarantine: a plugin's third crash within ten minutes switches it off. Its models leave what clients see, its
jobs are refused with the reason, and
gaea plugins,gaea statusand the console say why. Find the cause in its crashes, thengaea plugins enable <id>(or its On toggle) clears the quarantine, and the count starts again. - macOS's own dialog: when Gaea runs as an app, macOS may also show "quit unexpectedly" for a crashed worker
(
gaea-…-worker). It is only macOS's notice. Gaea has already recorded the crash and dealt with the job, so you can close it.
The guide for plugin authors is AUTHORING.md in gaea-plugin-demo. It covers:
- the template;
- GaeaPluginKit;
- signing with your own Developer ID;
- releasing;
- what an operator sees when your team is new to their server.
The protocol between Gaea and a plugin is GPP-1, with its schemas in schemas/v1.
| Path | What |
|---|---|
| Docs/Gaea - PRD.md | The product requirements |
| Docs/Gaea - Plan.md | Decisions, architecture, the plugin protocol and the phases |
| spec/GPP-1.md | The Gaea Plugin Protocol v1 and manifest.json |
| Sources/ | The host: GaeaCore, the console, the app, the gaea CLI |
| Docs/Evidence/ | The acceptance runs behind each piece of work |
Apache-2.0.