Skip to content

Gateway routes

The Host's HTTP gateway (@open-matrix/system-gateway-http) fronts every web app and HTTP-bearing service runtime. Two route shapes flow through it:

  1. App routes/apps/<appName>/... for any runtime started with --serve whose package declares a webapp block.
  2. Custom HTTP routes — explicit prefixes declared in a package's matrix.json:http.routes.

How a --serve runtime registers an app route

When hivecast up @open-matrix/<pkg> --serve runs, the runner registers route metadata via the runner control plane (packages/mx-cli/src/utils/runner-control-plane.ts):

ts
// from packages/mx-cli/src/commands/run.ts
return {
  appName: webapp.appName,
  routePrefix: `/apps/${webapp.appName}/`,
  assetMount,
  ...(webappServer ? { origin: webappServer.baseUrl, port: webappServer.port } : {}),
};

The gateway picks up the registration and starts proxying /apps/<appName>/* to the asset endpoint or to the standalone webapp server (depending on whether --serve allocated a port).

How a package declares custom HTTP routes

matrix.json:http.routes lists prefixes a package wants to own beyond /apps/<appName>/. From matrix-web/matrix.json:

json
"http": {
  "routes": [{
    "export": "MatrixWebHttpSurface",
    "prefixes": [
      "/api/identity/", "/.well-known/", "/auth/", "/login",
      "/login/", "/api/auth/", "/api/domains/",
      "/api/connect-token/", "/api/components",
      "/api/provision", "/api/provision/",
      "/api/runtime/register", "/api/nats-jwt"
    ]
  }]
}

The gateway reads these on runtime startup and routes matching HTTP requests to the named export.

Default HiveCast routes

A default hivecast install brings up runtimes for these apps (packages/hivecast/bin/hivecast.mjs:28-39); each contributes its route at the gateway:

URL pathPackageSource
/apps/web/@open-matrix/matrix-webwebapp.appName: "web"
/apps/edge/@open-matrix/matrix-edgewebapp.appName: "edge"
/apps/director/@open-matrix/directorwebapp.appName: "director"
/apps/chat/@open-matrix/chatwebapp.appName: "chat"
/apps/inference-settings/@open-matrix/inference-settingswebapp.appName: "inference-settings"
/apps/flowpad/@open-matrix/flowpadwebapp.appName: "flowpad"
/apps/smithers/@open-matrix/smitherswebapp.appName: "smithers"
/api/identity/, /auth/, /.well-known/, etc.@open-matrix/matrix-webhttp.routes
/healthzgateway itselfimplicit
/nats-wsgateway proxies to NATS WebSocketimplicit

Same-origin requirement

CLAUDE.md Rule 7: the browser connects via the same-origin WebSocket. The gateway proxies /nats-ws to the bundled NATS sibling. A package's browser bootstrap should always connect to /nats-ws on the same origin that served index.html. Absolute WebSocket URLs from package code break this contract.

Pinning ports for stable URLs

A --serve runtime gets a free port by default (good for parallel dev). Pin it for stable browser bookmarks (packages/host-service/src/cli.ts:173-175):

bash
hivecast up @open-matrix/director --serve --port 5173 \
  --id RUNTIME-DIRECTOR-DEV --home /tmp/matrix-home

The pinned port appears in metadata.webapp.port of the runtime record, and the gateway reuses it for routing.

Route conflicts

Two runtimes claiming the same appName is an error. The runner control plane refuses the second registration; the second runtime will start but its route will not register.

Two runtimes claiming overlapping HTTP prefixes is also an error; the gateway resolves them in order of registration today (first wins). Avoid the conflict at design time — don't create two packages that own the same HTTP prefix.

Per-Host vs cross-Host routing

A Host's gateway routes only to runtimes on the same Host. For cross-Host routing (e.g. HiveCast routing a request to a user's own Host), the public-facing Edge Host runs system-gateway-http plus the Matrix-protocol relay; that's the platform-side concern out of scope for this site.

See also

Source: projects/matrix-3/packages/system-gateway-http/src implements the gateway; packages/mx-cli/src/utils/runner-control-plane.ts is the registration facade; route metadata is constructed in packages/mx-cli/src/commands/run.ts:545-559.