- A Databricks workspace with Model Serving endpoints enabled
The simplest way — no CLI, no cloning, everything stays in the Databricks UI.
- Go to Databricks → Apps → Create App
- Choose Custom App and connect this Git repo:
https://github.com/databrickslabs/coding-agents-databricks-apps.git - Click Deploy
- Open the app — on first terminal session, paste a short-lived PAT when prompted
The app pulls the code directly from Git. To update later, just re-deploy — it picks up the latest from the repo.
Note: On first startup, the app automatically removes the template's
.githistory and reinitializes a clean, remote-free git repo. This prevents accidental pushes back to the template repo from the in-browser terminal.
Optional (Highly Recommended): If you use Databricks AI Gateway, also add
DATABRICKS_GATEWAY_HOSTas a secret or environment variable. Otherwise the app falls back to direct model serving endpoints.
If you prefer working from the terminal or need more control:
databricks repos create \
--url https://github.com/datasciencemonkey/coding-agents-databricks-apps.git \
--path /Workspace/Users/<your-email>/apps/coding-agents-databricks-appsIn the cloned workspace folder, copy the template and edit it:
cp app.yaml.template app.yamlSet your DATABRICKS_GATEWAY_HOST, or remove the gateway lines to fall back to direct model serving endpoints.
databricks apps create <your-app-name>No secrets or resources to configure. On first terminal session, paste a short-lived PAT when prompted — all CLIs are configured automatically.
databricks apps deploy <your-app-name> \
--source-code-path /Workspace/Users/<your-email>/apps/coding-agents-databricks-appsTip: To update later, just
git pullin the workspace repo and re-deploy.
Databricks Apps can deploy directly from a Git ref — no sync-to-workspace
step. This is how the coda-01..08 fleet runs. The Makefile wraps it:
# 1. Attach the repo to the app (idempotent; creates the app if needed)
make configure-git APP_NAME=coda-04 PROFILE=<profile>
# 2. Private repo? Add a Git credential to the app SP (needs CAN MANAGE on the SP).
# Token is read from stdin so it never hits a command line / shell history.
gh auth token | make configure-git-credential APP_NAME=coda-04 PROFILE=<profile>
# 3. Deploy from a ref (branch | tag | commit)
make deploy-git APP_NAME=coda-04 PROFILE=<profile> GIT_REF=main
make redeploy-git APP_NAME=coda-04 PROFILE=<profile> GIT_REF=main # + (re)grant Omnigent IAMOverridable vars: GIT_URL, GIT_PROVIDER (gitHub, gitLab, …), GIT_REF,
GIT_REF_TYPE (branch | tag | commit).
Raw CLI equivalents:
databricks apps create-update <app> --json '{"update_mask":"git_repository","git_repository":{"url":"<URL>","provider":"gitHub"}}'
databricks apps deploy <app> --json '{"git_source":{"branch":"main"}}' # or {"tag":...} / {"commit":...}Note: apps created before Git-deploy went GA may not grant the creator
CAN MANAGEon the app SP. If adding a Git credential fails, ask a workspace admin to grantCAN MANAGEon the service principal first.
When an app registers as an Omnigent host (OMNIGENTS_SERVER_URL set), its
service principal — which starts with zero privileges — needs a specific IAM
set, or the host silently never appears in the Omnigent picker.
make grant-omnigent-host (run automatically by deploy / redeploy /
redeploy-git) grants, via grant_omnigent_host.sh:
CAN_USEon the Omnigent server app — else the host tunnel's WebSocket upgrade is rejected at the Apps edge and the host never registers.- The full Unity Catalog traversal chain to the wheel volume
(
OMNIGENTS_WHEEL_SPEC=/Volumes/<cat>/<schema>/<vol>):USE_CATALOGon the catalogUSE_SCHEMAon the schemaREAD_VOLUME+WRITE_VOLUMEon the volume
READ_VOLUMEalone is a silent trap. WithoutUSE_CATALOG/USE_SCHEMAthe SP cannot traverse to the volume; the wheel download fails withUser does not have USE CATALOG on Catalog '<cat>', theomnigentCLI never installs, and the host never registers — while every "grant" still reports green. This bit us in production (2026-07-11).
Group option. Instead of per-SP grants you can grant a group the chain
and add the app SPs to it. Gotcha: account-federated groups cannot have
members edited via the workspace SCIM preview endpoint
("can only be managed in account") — use the account SCIM proxy the UI uses,
PATCH /api/2.0/account/scim/v2/Groups/{id} (works with a workspace-admin PAT).
Membership uses the SP's SCIM id (== the app's service_principal_id), not
its client_id.
Restart after a late grant. Grants persist, but an app that booted before its grants landed won't retroactively install the CLI — the boot-time install does not retry in-process. Restart the app to re-run install/launch:
databricks apps stop <app> --profile <p> && databricks apps start <app> --profile <p>Verify the host is live:
# SP can now traverse to the wheel volume
databricks fs ls "dbfs:/Volumes/<cat>/<schema>/<vol>" --profile <sp-profile>
# In-container after a good boot
which omnigent && ls ~/.omnigent/logs/host-runner/
# On the server (as the SP): GET /v1/hosts lists the deterministic host_id
# host_id = "host_" + sha256("coda-omnigents-host:<sp_client_id>")[:32]If the host is registered but not in your picker, it's SP-owned — share it to
your user (owner-gated POST /api/omnigent-host/share).
| Variable | Required | Description |
|---|---|---|
DATABRICKS_TOKEN |
No | Optional. If not set, the app prompts for a token on first session. Auto-rotated every 10 minutes |
HOME |
Yes | Set to /app/python/source_code in app.yaml |
ANTHROPIC_MODEL |
No | Claude model name (default: databricks-claude-opus-4-8) |
PI_MODEL |
No | Pi model name — same /anthropic gateway route as Claude (default: databricks-claude-opus-4-8) |
ENABLE_PI |
No | Set false to skip installing the Pi coding agent (default: true) |
CODEX_MODEL |
No | Codex model name (default: databricks-gpt-5-5) |
GEMINI_MODEL |
No | Gemini model name (default: databricks-gemini-2-5-pro) |
HERMES_MODEL |
No | Hermes model name (default: databricks-claude-opus-4-8) |
DATABRICKS_GATEWAY_HOST |
No | AI Gateway URL override. Auto-discovered from DATABRICKS_WORKSPACE_ID if unset. Falls back to direct model serving if neither is available |
This is a single-user, zero-config auth app. No secrets or tokens are required at deploy time.
- Owner resolution: The app owner is determined from
app.creatorvia the service principal + Apps API — no PAT needed - Authorization: Each request's
X-Forwarded-Emailheader is compared againstapp.creator. Non-matching users see 403 - Interactive PAT setup: On first terminal session, the user pastes a short-lived PAT interactively. All CLIs (Claude, Codex, OpenCode, Gemini, Hermes, Databricks) are configured automatically
- Auto-rotation: PAT rotates every 10 minutes with a 15-minute lifetime. Old tokens are proactively revoked. Maximum leaked-token exposure: 15 minutes
- Session-aware: Rotation is skipped when no active terminal sessions exist
- On restart: The user re-pastes a token (no persistence by design)
Production uses Gunicorn (gunicorn.conf.py) with:
workers=1— PTY file descriptors and in-memory session state can't survive forkingthreads=8— Handles concurrent polling from the terminal clientworker_class=gthread— Single process + thread poolpost_worker_inithook callsinitialize_app()to start setup
Git commits automatically sync projects to Databricks Workspace:
/Workspace/Shared/coda/{app-name}/{project-name}/
The post-commit hook uses nohup ... & disown to ensure the sync process survives across all coding agents, since some agents kill the entire process group when a shell command finishes.