Skip to main content

Mecatl Studio web UI

Early access: expect breaking changes between releases

Studio is under active development. Its interface, its /api/v1 endpoints, its configuration variables, and the data it keeps in your browser can change in any release, with no deprecation period and no migration path. A screen, a URL, or a setting you rely on today may be renamed or removed in the next version.

Deploy it by an exact version tag rather than latest, read the release notes before upgrading, and do not build an integration against its HTTP surface yet. The published image carries org.stacklok.mecatl.studio.stability=early-access so a deployment can assert on it.

Mecatl Studio is the browser client for a Mecatl deployment. It runs as one container that serves the web app and a backend for frontend (BFF) from the same origin. Your browser talks only to the BFF; the BFF holds your credential and talks to mecated or mecak8s over the same gRPC listener the terminal client uses. Studio never receives a provider API key.

Every release includes a multi-architecture image for linux/amd64 and linux/arm64:

ghcr.io/stacklok/mecatl/studio:<VERSION>

Pin an exact release version: latest moves with every release, and an early-access release can change the interface without warning. The image is signed with keyless cosign, includes an SPDX SBOM attestation, and carries SLSA build provenance. See the release workflow docs for how to verify a signed image.

What Studio offers​

Studio exposes the shared capabilities described in the feature guides, and it hides or disables what the connected deployment does not enable:

  • Chats: sessions with streamed runs, image attachments, permission approvals, steering, and model and reasoning-effort selection.
  • Scheduled: scheduled tasks with a cron builder and fire history, when the deployment enables scheduling.
  • Skills: configured and learned skills, learning proposals, and session reflection, when the deployment enables them.
  • Settings: profile and appearance preferences stored in the browser, memory consolidation, the model inventory, and storage health. Provider credentials and model routing stay with the deployment and are shown read-only.

A global search palette and a keyboard-shortcuts reference page complete the set.

Try it locally with Compose​

The repository's apps/docker-compose.yml starts a mecated container and Studio on an internal network and publishes Studio on 127.0.0.1:3100.

  1. Clone the repository and change into apps/.

  2. Copy .env.example to .env and set one provider key, for example ANTHROPIC_API_KEY.

  3. Run:

    docker compose up --build
  4. Open http://127.0.0.1:3100.

The local mecated runs without OIDC, so Studio starts in its unauthenticated mode and every browser that reaches it acts as the same principal. The Compose file opts into that with STUDIO_ALLOW_UNAUTHENTICATED=1 because it publishes Studio on the loopback address only.

Deploy against mecak8s​

In production Studio runs behind your ingress and connects to a mecak8s deployment that publishes an OIDC profile (see Cloud-native k8s with mecak8s). Users sign in through the deployment's identity provider with Authorization Code and PKCE; Studio keeps the session in encrypted, HttpOnly cookies and forwards the user's token on every request.

Set these variables on the Studio container:

VariableValue
MECATL_BASE_URLThe https:// address of the mecak8s gRPC listener, for example https://mecak8s.example.com.
STUDIO_PUBLIC_URLThe origin your users open, for example https://studio.example.com. Studio derives the OIDC callback https://studio.example.com/api/v1/auth/callback and the Secure cookie flag from it.
STUDIO_SESSION_SECRETAt least 32 bytes, shared by every Studio replica. Generate one with openssl rand -base64 48.
STUDIO_TRUSTED_PROXY_HOPS1 when one ingress or load balancer sits in front of Studio, so rate limiting and audit records see the client address from X-Forwarded-For instead of the proxy.

Register the callback URL with your identity provider's public client. Studio discovers the issuer, client ID, audience, and scopes from the deployment's protected-resource document and refuses to start when that document cannot be fetched, so a misconfigured target fails at deploy time.

If the protected-resource document lives at a different address than the gRPC listener, set MECATL_RESOURCE_URL to that address. The local Compose file uses it because mecated serves gRPC and HTTP on separate ports.

Studio listens on port 3100, answers GET /api/health as soon as it starts, and runs as a non-root user. Scale it horizontally without shared storage: every replica needs only the same STUDIO_SESSION_SECRET.

Static token or no authentication​

Studio can also run as a single service identity by setting MECATL_AUTH_TOKEN together with MECATL_BASE_URL, or against a deployment that publishes no OIDC profile. In both cases every browser that reaches Studio acts as one principal, so the image refuses to start unless you also set STUDIO_ALLOW_UNAUTHENTICATED=1. Use this only behind your own access control.

Configuration reference​

VariableDefaultPurpose
MECATL_BASE_URLunsetConnects to an existing mecatl gRPC listener. The image requires it.
MECATL_RESOURCE_URLderived from MECATL_BASE_URLAddress of the RFC 9728 protected-resource document.
MECATL_AUTH_TOKENunsetStatic bearer token; disables browser login.
STUDIO_PUBLIC_URLunsetBrowser-facing origin; required for browser login and inside the image.
STUDIO_SESSION_SECRETunsetSecret sealing the session cookies; required for browser login.
STUDIO_PORT3100Listening port.
STUDIO_TRUSTED_PROXY_HOPS0Reverse-proxy hops to trust when reading X-Forwarded-For.
STUDIO_RATE_LIMIT_MAX20Login requests allowed per client within the window.
STUDIO_RATE_LIMIT_WINDOW_MS60000Rate-limit window in milliseconds.
STUDIO_ACTIVITY_REPLAY_MAX2000Durable events one reattach replays before it tells the browser to read the transcript for older history. Live events are never bounded.
STUDIO_ACTIVITY_MAX_STREAMS4Concurrent activity streams one chat admits per replica.
STUDIO_ALLOW_UNAUTHENTICATEDunsetSet to 1 to run a static-token or no-authentication target inside the image.
STUDIO_LOG_LEVELinfoOne of debug, info, warn, or error. Logs are JSON lines on standard error.

For local development outside a container, the Studio README covers the spawn and mock runtime modes and the task studio:* commands.

Next steps​

Troubleshooting​

Studio exits with "authentication setup failed (auth_discovery_failed)"

Studio could not fetch the deployment's protected-resource document. Check that MECATL_BASE_URL (or MECATL_RESOURCE_URL) points at the HTTPS address that serves /.well-known/oauth-protected-resource. A deployment without OIDC answers 404 there, which Studio treats as "no browser login" instead of an error.

Sign-in loops back to the login screen

Studio sets Secure cookies when STUDIO_PUBLIC_URL is https://. Confirm users open exactly that origin, that the identity provider redirects to STUDIO_PUBLIC_URL/api/v1/auth/callback, and that every replica shares the same STUDIO_SESSION_SECRET.