Walkthrough: serve the desktop protocol and verify over HTTP
This walkthrough starts only Glina's loopback Node backend and runs the local structural gate. It does not call /v1/blender-health, start a Blender MCP process, or touch the live Blender bridge. The exact script is examples/serve-verify.sh; it was executed with Node v22 on macOS.
1. Start on an ephemeral port
The script writes a temporary non-secret config, then launches:
node pipeline/cli.js serve --port 0 --config "$WORK/plain.json"
serve bound 127.0.0.1 and printed one ready line. The script extracted the port; the captured run reported:
backend ready on 127.0.0.1:62357
The number is intentionally ephemeral and will differ on another run. A desktop client must read the ready JSON instead of assuming 62357.
2. Probe process health
$ curl -s http://127.0.0.1:62357/v1/health
{
"status": "ok"
}
This proves only that the HTTP process is answering. Blender health is a separate, stateful probe.
3. Stream a verification job
The script posts the reference dragon path:
curl -s -X POST "http://127.0.0.1:$PORT/v1/verify" \
-H 'content-type: application/json' \
-d '{"path":"…/assets/models/smok.glb"}'
The exact captured protocol payload (path shortened here) was one terminal NDJSON event:
{"type":"result","status":0,"json":{"ok":true,"errors":[],"stats":{"meshes":38,"primitives":38,"triangles":748,"materials":5,"animations":2,"animationNames":["flap","idle"],"textures":0,"nodes":48,"animationChannels":54,"movingAnimationChannels":8,"staticAnimationChannels":46},"thresholds":{"triTarget":6000,"triTolerancePct":100,"requireMaterials":true,"requireAnimations":false,"minAnimationClips":0,"minBytes":100,"maxBytes":67108864,"enabled":true},"path":"…/assets/models/smok.glb"}}
No log events preceded it because structural verification is quiet. Sculpt and preview jobs may emit any number of log events before the single result.
4. Implement a consumer safely
- Spawn
glina serve --port 0and parse the first stdout line as{ready:true,port}. - Keep stderr separate; stdout is the startup protocol.
- For an NDJSON endpoint, parse one JSON object per line and append
log.chunkin arrival order. - Do not equate HTTP 200 with success. Wait for
type:"result"and inspectstatusplus the result document. - If the stream closes without a result, treat it as an incomplete exchange.
- Terminate the backend when the owning app exits.
That is the same lifecycle implemented by the macOS desktop companion.