The native, no-custom-code path for pinning a Databricks user's SQL queries to a specific warehouse. Honored by the managed /api/2.0/mcp/sql MCP endpoint, the SQL editor, AI/BI dashboards, Genie, alerts, and Catalog Explorer. Three configuration paths: UI, CLI, and REST API.
A per-user default warehouse override tells every Databricks surface that consumes a "default warehouse" to route that user's queries to a specific compute resource — without per-call client configuration.
/api/2.0/mcp/sql
Without an override, each surface falls back to the workspace's configured default warehouse (Settings → Compute → Default warehouse), and the managed MCP applies its priority-tier heuristic (any RUNNING warehouse → any STOPPED, serverless first, "shared"-named first, etc.).
With an override, the user gets predictable, deterministic warehouse routing across all these surfaces. The override sits at the workspace level keyed on user identity — admins can set overrides for any user, users can set their own.
This override is the right answer for most warehouse-pinning needs on Databricks. It has one structural limit: it's keyed on user identity, not on workload or agent. If you need different agents owned by the same user to route to different warehouses, you need a custom MCP server instead.
execute_sqlFor the custom-MCP path, see the main warehouse-pinning guide.
Two surfaces: the workspace-level default warehouse for everyone, and the per-user override that supersedes it for specific users.
The workspace default is the fallback. Any user with a per-user override (see Path B below) bypasses this setting entirely. To force everyone onto the same warehouse, leave per-user overrides unset or use a script to set them uniformly.
As of May 2026, the UI for per-user overrides is documented as available but the exact menu path isn't fully detailed in the public admin docs. Users can typically set their own default via the SQL editor warehouse picker (a "set as my default" affordance appears alongside the warehouse selector). Admins managing other users' overrides should use the CLI or REST API paths below for reliable, scriptable control.
For admin-managed overrides — e.g., setting a team's warehouse for every team member as part of onboarding — use the CLI or REST API. They're scriptable, version-controllable via Terraform, and produce auditable change logs.
The Databricks CLI v0.250+ ships five subcommands under databricks warehouses for managing per-user overrides. The CLI is the fastest path for one-off configuration and scriptable rollouts.
# Install
brew install databricks/tap/databricks
# Authenticate (creates profile in ~/.databrickscfg)
databricks auth login --host https://<your-workspace>.cloud.databricks.com
# Find a warehouse ID
databricks warehouses list --profile <your-profile>
# Create a new CUSTOM override pointing at a specific warehouse
databricks warehouses create-default-warehouse-override \
me CUSTOM \
--warehouse-id <warehouse-id> \
--profile <your-profile>
The me shorthand resolves to your authenticated user. Type CUSTOM means "pin to this specific warehouse"; the alternative LAST_SELECTED uses the most recently selected warehouse instead (sticky behavior, no explicit pin).
databricks warehouses get-default-warehouse-override \
default-warehouse-overrides/me \
--profile <your-profile>
# Output:
# {
# "default_warehouse_override_id": "<numeric-user-id>",
# "name": "default-warehouse-overrides/<numeric-user-id>",
# "type": "CUSTOM",
# "warehouse_id": "<your-warehouse-id>"
# }
# Change the warehouse target (uses field mask: "*" = update all fields)
databricks warehouses update-default-warehouse-override \
default-warehouse-overrides/me "*" CUSTOM \
--warehouse-id <new-warehouse-id> \
--profile <your-profile>
# Or switch type from CUSTOM to LAST_SELECTED (no warehouse-id needed)
databricks warehouses update-default-warehouse-override \
default-warehouse-overrides/me "*" LAST_SELECTED \
--profile <your-profile>
databricks warehouses list-default-warehouse-overrides \
--profile <your-profile>
# Replace 'me' with the target user's numeric ID
# Get user IDs from: databricks workspace-users list (or SCIM API)
databricks warehouses create-default-warehouse-override \
<user-id> CUSTOM \
--warehouse-id <warehouse-id> \
--profile <admin-profile>
databricks warehouses delete-default-warehouse-override \
default-warehouse-overrides/me \
--profile <your-profile>
# After deletion, the user falls back to the workspace-level default warehouse
For scripted rollouts (e.g., setting overrides for every member of a team), use update-default-warehouse-override with the --allow-missing flag. When the override doesn't exist, the flag tells the API to create one instead of failing. This lets you write a single "set the override to X" script that works whether the user has an existing override or not.
All five operations live under /api/warehouses/v1/default-warehouse-overrides. Same workspace OAuth bearer-token auth as any other Databricks API. The CLI is a thin wrapper around these endpoints.
| Method | Path | Purpose |
|---|---|---|
POST |
/api/warehouses/v1/default-warehouse-overrides?default_warehouse_override_id=<id> |
Create override for a user (id can be me or numeric user ID) |
GET |
/api/warehouses/v1/default-warehouse-overrides/<id> |
Read a single override |
PATCH |
/api/warehouses/v1/default-warehouse-overrides/<id>?update_mask=<mask> |
Update (use * for all fields) |
DELETE |
/api/warehouses/v1/default-warehouse-overrides/<id> |
Remove override (fall back to workspace default) |
GET |
/api/warehouses/v1/default-warehouse-overrides |
List all overrides (admin only) |
POST /api/warehouses/v1/default-warehouse-overrides?default_warehouse_override_id=me
Authorization: Bearer <your-token>
Content-Type: application/json
{
"type": "CUSTOM",
"warehouse_id": "<warehouse-id>"
}
Get a bearer token via databricks auth token --host <workspace-url>.
PATCH /api/warehouses/v1/default-warehouse-overrides/me?update_mask=*
Authorization: Bearer <your-token>
Content-Type: application/json
{
"type": "CUSTOM",
"warehouse_id": "<new-warehouse-id>"
}
The update_mask query parameter follows Google Cloud Resource Manager conventions: * updates all fields, comma-separated field names update only those (e.g., ?update_mask=warehouse_id to change just the target without touching the type).
HOST=<your-workspace-host> # e.g. https://abc.cloud.databricks.com
TOKEN=$(databricks auth token --host "$HOST" | jq -r .access_token)
WAREHOUSE_ID=<your-warehouse-id>
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"type\":\"CUSTOM\",\"warehouse_id\":\"$WAREHOUSE_ID\"}" \
"$HOST/api/warehouses/v1/default-warehouse-overrides?default_warehouse_override_id=me"
| Operation | User permission required |
|---|---|
| Manage your own override | Any workspace user |
| Read another user's override | Workspace admin |
| Set / update / delete another user's override | Workspace admin |
| List all overrides | Workspace admin |
The target warehouse must also be accessible to the override's user — i.e., the user needs CAN_USE permission on the warehouse. Setting an override pointing at a warehouse the user can't reach won't fail at create-time, but queries will fail when they try to start.
After the override is set, you don't need any client-side configuration for warehouse routing — the managed MCP looks up the override server-side on every request. You just need to point your MCP client at the managed endpoint with workspace OAuth. Two paths: a stdio proxy that uses your Databricks CLI authentication (works for both clients), or Cursor's native HTTP + OAuth (Cursor-only).
https://<your-workspace-host>/api/2.0/mcp/sql
Note the path ends in /mcp/sql with no warehouse ID. The override is what tells the server where to route — the URL stays the same for every user.
uv run mcp_proxy.py~/.databrickscfg profile for auth.MCP clients speak stdio (subprocess + stdin/stdout JSON-RPC). The managed MCP endpoint speaks HTTPS with Databricks OAuth. mcp_proxy.py bridges the two — it reads JSON-RPC from stdin, attaches an OAuth bearer token from your CLI profile, and POSTs to the workspace endpoint.
git clone https://github.com/robkisk/databricks-managed-mcp.git
# The proxy lives at databricks-managed-mcp/mcp_proxy.py
# It uses PEP 723 inline deps — no install step needed
.mcp.json{
"mcpServers": {
"databricks-sql": {
"command": "uv",
"args": [
"run",
"/absolute/path/to/databricks-managed-mcp/mcp_proxy.py",
"--path",
"/api/2.0/mcp/sql",
"--profile",
"<your-profile>"
]
}
}
}
For Claude Code: place this at .mcp.json in your project root, or ~/.claude/.mcp.json globally. For Cursor: .cursor/mcp.json in your project root. Restart the client to load the new server.
Cursor supports MCP servers over HTTP with first-class OAuth handling. No proxy script needed — Cursor opens a browser tab for the workspace login on first use and caches the token.
.cursor/mcp.json{
"mcpServers": {
"databricks-sql": {
"type": "http",
"url": "https://<your-workspace-host>/api/2.0/mcp/sql",
"oauth": {
"clientId": "<databricks-oauth-app-client-id>",
"callbackPort": 8080
}
}
}
}
The clientId is a Databricks OAuth app client ID — a workspace admin creates this once via databricks account custom-app-integration create (account-level call, requires Account Admin) and shares it with users in the workspace. Hardcode the actual UUID value; placeholder strings like $DATABRICKS_OAUTH_CLIENT_ID are not substituted at runtime.
After restarting your MCP client, ask the agent a quick SQL question:
"Use the databricks-sql MCP to run: SELECT current_user(), now()"
If the override is wired correctly, the query lands on your override warehouse. Verify by checking warehouse state on the Databricks control plane — see Verify it works below for the full state-delta methodology.
Both clients use the same managed MCP endpoint, and the override applies to the calling user. Wiring Claude Code and Cursor for the same user means both route to the override warehouse — there is no way to send Claude Code queries to one warehouse and Cursor queries to another while sharing a user. If you need that split, use a custom MCP server (see the main pinning guide).
Three layers of verification — each tighter than the last. Use whichever fits your confidence requirement.
databricks warehouses get-default-warehouse-override \
default-warehouse-overrides/me \
--profile <your-profile>
Returns the override's type and warehouse_id. If warehouse_id matches your intended target, the override is stored correctly.
databricks experimental aitools tools get-default-warehouse --profile <your-profile>
This CLI command resolves the same default-warehouse lookup that the managed MCP uses. The returned warehouse ID should match your override target. If it doesn't, the override is recorded but not winning the priority lookup — file a support ticket with both values.
Stop your target warehouse and every other warehouse the lookup might reach. Send a query through the managed MCP (or any consuming surface). The target warehouse should transition STOPPED → RUNNING, and no other warehouse should be touched.
# Stop all warehouses to baseline
for WID in $(databricks warehouses list --profile <p> -o json | jq -r '.[].id'); do
databricks warehouses stop "$WID" --profile <p> &
done; wait
# Send a query through any default-warehouse-using surface (MCP, SQL editor, etc.)
# Then re-list warehouses and check which one woke up:
databricks warehouses list --profile <p> -o json | jq '.[] | {id, state, name}'
Layer 1 confirms persistence, Layer 2 confirms the resolver, Layer 3 confirms the consuming surface honors what the resolver returns. State-delta verification (Layer 3) is robust because warehouse state transitions are observable on the Databricks control plane and can't be faked by a misbehaving downstream component.
| Type | Behavior | Use when |
|---|---|---|
CUSTOM |
Pin to the specific warehouse_id field |
You want explicit, predictable routing — admin-managed or user-set with intent |
LAST_SELECTED |
Use whichever warehouse the user most recently chose | You want sticky behavior — user's last UI selection persists across sessions |
Databricks ships a Terraform data source databricks_warehouses_default_warehouse_override for reading existing overrides. As of May 2026 the corresponding resource for declarative creation isn't shipped in the provider — use the CLI or REST API for now. Track the Terraform provider changelog for resource availability.