dbx-tools
Companion packages for Databricks developers building Databricks Apps, AppKit backends, Mastra agents, Genie workflows, and Model Serving integrations.
dbx-tools fills gaps around Databricks-provided packages that are often
low-level: missing sensible defaults, requiring repeated setup code, or
making common app patterns more cumbersome than they need to be. The packages in
this repo add opinionated defaults, shared schemas, AppKit plugins, UI helpers,
and local developer tools while staying close to Databricks’ own APIs.
Relationship To Native AppKit
Section titled “Relationship To Native AppKit”Use native AppKit first when it already gives you the exact surface you need.
AppKit has strong built-in plugins for Analytics, Genie, Files, Lakebase, Model
Serving, Jobs, beta AI Search, and beta Agents, plus React UI primitives and
hooks. dbx-tools is not a fork of that platform and should not replace AppKit
for straightforward cases.
Use these packages when the native surface gets repetitive or narrow for a real app:
- you need Databricks defaults before AppKit plugins initialize, such as Lakebase env discovery or layered config resolution;
- you want Mastra’s agent runtime, storage, tools, MCP, and broader ecosystem while still running inside AppKit with OBO auth and Databricks plugin tools;
- you want Genie output as typed async events that an agent or custom UI can consume, enrich, and turn into chart/data embeds;
- you want model selection by intent (
"sonnet","chat-fast") rather than wiring every app to one serving endpoint alias; - you need local OpenAI-compatible development tooling on top of Databricks Model Serving;
- you want agent tools, federated search, index lifecycle helpers, reusable search components, or a Lakebase full-text provider around native AppKit AI Search;
- you need reusable UI surfaces for Mastra chat or human-approved email rather than a one-off component in each app.
What This Adds
Section titled “What This Adds”- AppKit app defaults — auto-configure Lakebase/Postgres env through core config sources, access AppKit execution context safely, and look up sibling plugins with typed helpers.
- Core configuration and locking — resolve scoped settings lazily from
constant data, the environment, project
.envfiles, validated bundles, or App YAML with explicit runtime and source overrides; install binaries atomically; and serialize critical sections across threads, local processes, or replicas with process, file, and Postgres advisory locks. - Mastra inside AppKit — register one or more Mastra agents as an AppKit plugin with OBO auth, Lakebase-backed storage/memory, workspace skills, model selection, history, threads, feedback, and scoped route exposure.
- Genie as agent tools — stream Genie thinking, SQL, rows, and final results as typed events; expose Genie space metadata and starter questions; let agents answer with delayed chart and data embeds.
- Model Serving ergonomics — turn loose model names such as
"sonnet"or"chat-fast"into concrete Databricks serving endpoints using workspace catalogues, fuzzy matching, class ceilings, cache, and fallbacks. - OpenAI-compatible local proxy — point OpenAI-shaped clients at Databricks Model Serving without hand-managing Databricks auth or endpoint ids.
- Approval-gated email workflows — give agents a
send_emailtool that suspends for human approval, supports SMTP or local outbox mode, derives safe senders, and renders Markdown email. - Web search and fetch tools — give agents
web_search(the Databricks native web-search tool, on its own Gemini/GPT web-capable model, returning an answer plus citations) andweb_fetch(page contents) with an optional URL allow-list and per-tool approval gating. - AI Search extensions and Lakebase full text - native AppKit
aiSearchowns Vector Search queries, OBO, caching, reranking, pagination, and the React query hook. The dbx-tools search packages add agent tools, universal search, index creation/sync/seed helpers,SearchBox/SearchResults, andlakebaseAiSearch, a PostgreSQL full-text provider with the same AppKit query contract. - Teams bot endpoint and Adaptive Cards — give an app a real Bot Framework messaging endpoint (inbound JWT validated, replies delivered over the Connector API), compile an agent’s small card spec into a schema-valid Adaptive Card, and render a whole Teams conversation in React.
- A Postgres message bus — broadcast a typed envelope to every app instance
over
LISTEN/NOTIFYwith automatic sender context, plus optional persistence so a subscriber that missed a message can replay history by cursor. - A gated public URL for any command —
dbx tunnel -- <command>fronts a process with a portr tunnel and an email one-time-code gate, for the case that is not an AppKit app at all. - Reusable React surfaces — provide AppKit/Tailwind/Bun foundations, a Mastra chat UI plus React Email approval, preview, compose, and delivery components.
- Shared browser-safe contracts — keep UI, server, tests, and tools aligned with zod schemas for Mastra routes, Genie events, model lookup, email payloads, and selected Databricks SDK shapes.
- Reusable brand context — validate one YAML or JSON source for product names, assets, colors, typography, and LLM writing voice, then consume it from Node, React, browser helpers, or generated JSON Schema.
- Databricks infrastructure helpers — resolve workspace identity, cloud region, public IPs, Zerobus endpoints, and Databricks SDK cancellation without binding every package to AppKit.
Quick Start
Section titled “Quick Start”Install dependencies and type-check the workspace:
bun installbun run --filter '*' compileFor AppKit apps, the most common entrypoint is the Mastra plugin:
import { analytics, createApp, lakebase, server } from "@databricks/appkit";import { agents, genie, plugin } from "@dbx-tools/appkit-mastra";
const analyst = agents.createAgent({ name: "analyst", instructions: `Answer with Databricks context.\n\n${genie.GENIE_INSTRUCTIONS}`, tools(plugins) { return { ...plugins.analytics.toolkit(), ...plugins.genie?.toolkit(), }; },});
await createApp({ plugins: [ server(), analytics(), lakebase(), plugin.mastra({ agents: { analyst }, defaultAgent: "analyst", genie: { spaces: { sales: "01ef..." } }, }), ],});That single plugin registration can provide agent streaming routes, model resolution, Genie-backed data tools, durable Lakebase storage, chat history, thread management, feedback, and MCP exposure.
Use @dbx-tools/ui-mastra on the client side for the matching chat UI:
import { MastraChat } from "@dbx-tools/ui-mastra/react";
export function App() { return <MastraChat agentId="analyst" threadPlacement="auto" showModelPicker />;}Feature Packages
Section titled “Feature Packages”Read the package README for each feature area. They are written as the package-level source of truth: key features, import examples, configuration or runtime behavior, module maps, and links to adjacent packages.
Python Packages
Section titled “Python Packages”Install the published Python packages by distribution name:
uv add dbx-tools-core dbx-tools-postgres dbx-tools-model dbx-tools-litellm dbx-tools-graphitiThe root uv workspace contains these Python counterparts:
| Package | Purpose |
|---|---|
dbx-tools-core |
Loads scoped configuration from constant data, the environment, project .env files, validated Databricks bundles, and App YAML with the same precedence as Node, plus dependency-free stable-key, FNV hash, and identifier helpers. |
dbx-tools-postgres |
Parses the same Lakebase/Postgres address forms as the Node AppKit helper, creates credential-injected SQLAlchemy engines, provides connection-correct sync/async advisory locks with cross-runtime lock ids, and exposes the Node PostgresTopicBus lifecycle and wire envelope. |
dbx-tools-model |
Lists and classifies Databricks Model Serving endpoints, resolves model intent, builds authenticated invocation requests, sanitizes OpenAI chat payloads, and validates embedding responses without AppKit or Mastra runtime dependencies. |
dbx-tools-litellm |
Adds explicit-profile Databricks endpoint discovery and fuzzy, tool-aware model routing to LiteLLM while leaving request conversion, transport, streaming, retries, embeddings, and Responses bridging to LiteLLM’s built-in Databricks provider. |
dbx-tools-graphiti |
Launches upstream Graphiti’s MCP server with a native Neo4j 5 backend, provisioning Java and uv through mise and caching versioned downloads, dependencies, credentials, graph data, and logs without containers. |
Load One Brand File
Section titled “Load One Brand File”The root branding/brand.yaml is the canonical dbx tools
context and points at the reusable SVG assets beside it. The same schema accepts
JSON.
import { brand } from "@dbx-tools/core";
const brandContext = await brand.loadBrandContext();Use brand.BrandContextSchema from @dbx-tools/shared-core in browser-safe
code or structured LLM tools. Use @dbx-tools/ui-branding/react and
@dbx-tools/ui-branding/browser to render or apply the resulting context.
Common Workflows
Section titled “Common Workflows”Add AppKit Defaults
Section titled “Add AppKit Defaults”Use @dbx-tools/appkit when an AppKit backend
needs the setup code you would otherwise repeat in every app: Lakebase env
resolution, config lookup, Databricks SDK cancellation bridging, execution
context fallback, and typed sibling plugin access.
import { lakebase, server } from "@databricks/appkit";import { appkit } from "@dbx-tools/appkit";
await appkit.createApp({ plugins: [server(), lakebase()],});Resolve Models By Intent
Section titled “Resolve Models By Intent”Use @dbx-tools/model when a UI, agent, or CLI
should ask for a model by capability or loose name instead of hard-coding a
serving endpoint id.
import { resolve } from "@dbx-tools/model";
const selected = await resolve.selectModel(client, host, { explicit: "claude sonnet", modelClass: "chat-balanced",});Run OpenAI-Shaped Tools Against Databricks
Section titled “Run OpenAI-Shaped Tools Against Databricks”Use @dbx-tools/cli-model-proxy when a local tool
expects OpenAI-compatible endpoints but you want Databricks auth and Model
Serving resolution.
dbx model-proxy --profile my-workspace --port 4000Then point the client at http://127.0.0.1:4000/v1.
Require Human Approval For Email
Section titled “Require Human Approval For Email”Use @dbx-tools/email with
@dbx-tools/ui-email when an agent should draft email but
not send it until a user approves the suspended tool call.
import { plugin as emailPlugin, tool as emailTool } from "@dbx-tools/email";
const agent = agents.createAgent({ instructions: "Draft emails, then wait for approval before sending.", tools: () => ({ send_email: emailTool.emailTool() }),});
await createApp({ plugins: [server(), lakebase(), emailPlugin.email(), mastraPlugin.mastra({ agents: agent })],});Put A Gated Public URL In Front Of A Command
Section titled “Put A Gated Public URL In Front Of A Command”Use @dbx-tools/tunnel inside an AppKit app, where the
portr tunnel and the @dbx-tools/auth passwordless gate
run in-process through tunnelInterceptor() and the authGate plugin. The gate
supports Better Auth email OTP recovery and passkeys with Lakebase or SQLite
persistence.
Use @dbx-tools/cli-tunnel when the process is not an
AppKit app - a Python service, a static server, a third-party binary - and should
still be reachable only by approved email addresses.
dbx tunnel --allow databricks.com -- bun src/server.tsdbx tunnel status --allow databricks.comThe wrapper claims the public port, moves the wrapped command to a private one,
and gates traffic in between. status prints the resolved configuration without
starting anything.
Development
Section titled “Development”This repository uses a small internal workspace generator so package metadata, barrels, generated schemas, and examples stay consistent. That tooling is not the main product surface of the repo, but it is documented for contributors:
@dbx-tools/projendocuments the projen engine, package discovery, generated files, mixins, OpenAPI generation, and codegen.dbx-toolsdocuments the contributor CLI.
Useful contributor commands:
bun installbunx projenbun run --filter '*' compilebun run --filter '*' testbun run formatuv sync --all-packagesuv run pytestuv run ruff check packages/pyDocumentation
Section titled “Documentation”The READMEs are the current package-level source of truth. The GitHub Pages site
is generated from those README files, so package docs are not maintained twice.
See docs/README.md for the local build command and Pages
workflow.
The continuation plan in
plans/appkit-companion-continuation.md
tracks remaining package-follow-up work.