The gated internal REST/SSE core that fronts the unified Zig ABI, on port
7700 by default. It is the Elixir "scalability multiplier" over the
Idris2-logic / pure-Zig-interface stack (see docs/architecture/README.adoc,
v1.1.0). It is NOT a public ingress — per ADR-0004 the only governed
public surface is the http-capability-gateway (tier-2) in front of this
core. This listener binds the trusted/internal interface and every
invocation passes the TrustPolicy + CredentialDecryptor transaction
gate before dispatch.
Endpoints:
-
GET /health—{"status":"ok","version":…,"cartridges_loaded":N}. -
GET /menu— per-cartridge name / domain / tier / description. -
GET /cartridges— cartridge-name list. -
GET /cartridge/:name— fullcartridge.json, or 404 if unknown. -
POST /cartridge/:name/invoke— wired. Trust-gated, then dispatched viaBojRest.Invoker(shellsboj-invoke→dlopen`s the cartridge `.so→ ADR-0006boj_cartridge_invoke) forfficartridges, or the DenoJsWorkerPoolfallback for no-fficartridges. Returns200with the cartridge’s JSON result. -
POST /cartridge/:name/sse— same gated dispatch, streamed astext/event-stream(open→result|error→done). Makes the surface four-protocol (REST + SSE here; gRPC-compat + GraphQL via the per-cartridge internal Zig adapter).
The Node.js stdio bridge at mcp-bridge/ is what Claude Code and Glama
talk to. This core is the REST server behind it:
| Endpoint | Bridge tool |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
streaming variant of the above |
cd elixir
mix deps.get
mix compile
mix test # full suite (router, invoker, catalog, trust, …)The Zig dispatch CLI must be built once so the FFI path is live:
cd ../ffi/zig && zig build invoke # produces zig-out/bin/boj-invokecd elixir
mix run --no-halt
# listener binds http://127.0.0.1:7700 (internal; front with the gateway)Configure via env vars:
-
BOJ_PORT— listener port (default7700). -
BOJ_CARTRIDGES_ROOT— where to scan forcartridge.json(default:../cartridgesrelative to the Elixir project). -
BOJ_INVOKE_CLI— path to theboj-invokeZig CLI (else auto-probed).
-
Cowboy + Plug, single listener. One supervised listener, routed internally (REST + SSE); NOT N parallel HTTP servers. The
http-capability-gateway(ADR-0004) attaches in front as tier-2. -
Transaction-gated dispatch.
TrustPolicyderives required exposure from the cartridge’sauth.method; loopback callers are locally trusted;CredentialDecryptorruns before any dispatch. No gatekeeperless path to the ABI. -
ETS-backed catalog, read-only. Loaded once at boot; re-scan needs a restart (matches the restart-gated
cartridge.jsonmount lifecycle). -
Best-effort load. A malformed
cartridge.jsonis logged and skipped; the listener still comes up with whatever parsed cleanly.
-
Phase 1 — REST metadata. Listener serves cartridge metadata. DONE 2026-04-18.
-
Phase 2 — invocation wired.
POST /cartridge/:name/invoke(and/sse) dispatch through the unified Zig ABI viaboj-invoke, trust- gated. DONE. -
Phase 3 — gateway. Attach
http-capability-gatewayat tier-2 per ADR-0004 (verb governance, rate-limit tier-2, trust-level primary path). Accepted; production-wiring is a tracked programme — ADR-0004 estimates 8–12 weeks (mTLS-as-primary, E2E, benchmarks). Until then this core stays internal/loopback-bound. -
Phase 4 — mTLS / SDP. Per
Trustfile.a2ml[SDP_RULES].