Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions apps/agent-app/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Databricks workspace (auto-injected by platform on deploy)
DATABRICKS_HOST=https://your-workspace.cloud.databricks.com

# Agent LLM endpoint (Model Serving endpoint name)
DATABRICKS_AGENT_ENDPOINT=databricks-claude-sonnet-4-5

# Analytics plugin — SQL warehouse ID
DATABRICKS_WAREHOUSE_ID=your-warehouse-id

# Files plugin — Volume path (catalog.schema.volume)
DATABRICKS_VOLUME_FILES=/Volumes/your-catalog/your-schema/your-volume

# Optional: Custom MCP servers the agent can call. When set, the hostname
# is automatically added to agents({ mcp: { trustedHosts } }).
# VECTOR_SEARCH_MCP_URL=https://<workspace>/api/2.0/mcp/vector-search/<catalog>/<schema>/<index>
# CUSTOM_MCP_URL=https://<your-mcp-server>/mcp
3 changes: 3 additions & 0 deletions apps/agent-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
.env
8 changes: 8 additions & 0 deletions apps/agent-app/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
command: ['node', '--import', 'tsx', 'server.ts']
env:
- name: DATABRICKS_WAREHOUSE_ID
valueFrom: sql-warehouse
- name: DATABRICKS_AGENT_ENDPOINT
valueFrom: serving-endpoint
- name: DATABRICKS_VOLUME_FILES
valueFrom: volume
12 changes: 12 additions & 0 deletions apps/agent-app/config/agents/assistant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
endpoint: databricks-claude-sonnet-4-5
default: true
---

You are a helpful data assistant running on Databricks.

Use the available tools to query data, browse files, and help users with their analysis.

When using `analytics.query`, write Databricks SQL. When results are large, summarize the key findings rather than dumping raw data.

You also have access to additional tools from MCP servers — use them when relevant.
50 changes: 50 additions & 0 deletions apps/agent-app/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
bundle:
name: appkit-agent-app

variables:
sql_warehouse_id:
description: SQL Warehouse ID for analytics queries
serving_endpoint_name:
description: Model Serving endpoint name for the agent LLM
volume_full_name:
description: "UC Volume full name (e.g. catalog.schema.volume_name)"

resources:
apps:
agent_app:
name: "appkit-agent-app"
description: "AppKit agent with auto-discovered tools from analytics, files, and genie plugins"
source_code_path: ./

user_api_scopes:
- sql
- files.files
- dashboards.genie

resources:
- name: sql-warehouse
sql_warehouse:
id: ${var.sql_warehouse_id}
permission: CAN_USE

- name: serving-endpoint
serving_endpoint:
name: ${var.serving_endpoint_name}
permission: CAN_QUERY

- name: volume
uc_securable:
securable_type: VOLUME
securable_full_name: ${var.volume_full_name}
permission: WRITE_VOLUME

targets:
dogfood:
default: true
workspace:
host: https://e2-dogfood.staging.cloud.databricks.com

variables:
sql_warehouse_id: dd43ee29fedd958d
serving_endpoint_name: databricks-claude-sonnet-4-5
volume_full_name: main.mario.mario-vol
12 changes: 12 additions & 0 deletions apps/agent-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AppKit Agent</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
40 changes: 40 additions & 0 deletions apps/agent-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "agent-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "NODE_ENV=development tsx watch server.ts",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"@databricks/appkit": "workspace:*",
"@databricks/appkit-ui": "workspace:*",
"@databricks/sdk-experimental": "^0.16.0",
"dotenv": "^16.6.1",
"lucide-react": "^0.511.0",
"react": "19.2.0",
"react-dom": "19.2.0",
"marked": "^15.0.0",
"zod": "^4.0.0"
},
"devDependencies": {
"@tailwindcss/postcss": "4.1.17",
"@types/node": "24.10.1",
"@types/react": "19.2.7",
"@types/react-dom": "19.2.3",
"@vitejs/plugin-react": "5.1.1",
"autoprefixer": "10.4.21",
"postcss": "8.5.6",
"tailwindcss": "4.1.17",
"tailwindcss-animate": "1.0.7",
"tw-animate-css": "1.4.0",
"tsx": "4.20.6",
"typescript": "5.9.3",
"vite": "npm:rolldown-vite@7.1.14"
},
"overrides": {
"vite": "npm:rolldown-vite@7.1.14"
}
}
6 changes: 6 additions & 0 deletions apps/agent-app/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
"@tailwindcss/postcss": {},
autoprefixer: {},
},
};
92 changes: 92 additions & 0 deletions apps/agent-app/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {
agents,
analytics,
createAgent,
createApp,
files,
fromPlugin,
mcpServer,
server,
tool,
} from "@databricks/appkit";
import { z } from "zod";

const port = Number(process.env.DATABRICKS_APP_PORT) || 8003;

// Shared tool available to any agent that declares `tools: [get_weather]` in
// its markdown frontmatter.
const get_weather = tool({
name: "get_weather",
description: "Get the current weather for a city",
schema: z.object({
city: z.string().describe("City name"),
}),
execute: async ({ city }) => `The weather in ${city} is sunny, 22°C`,
});

// Code-defined agent. Overrides config/agents/support.md if a file with that
// name exists. Tools here are explicit; defaults are strict (no auto-inherit
// for code-defined agents), so we pull analytics + files in via fromPlugin.
//
// Optional custom MCP servers can be configured by setting env vars and are
// added to the agent only when present. Any https URL configured here must
// also be allowlisted via `agents({ mcp: { trustedHosts: [...] } })` below.
const customMcpServers: Record<string, ReturnType<typeof mcpServer>> = {};
if (process.env.VECTOR_SEARCH_MCP_URL) {
customMcpServers["mcp.vector-search"] = mcpServer(
"vector-search",
process.env.VECTOR_SEARCH_MCP_URL,
);
}
if (process.env.CUSTOM_MCP_URL) {
customMcpServers["mcp.custom"] = mcpServer(
"custom",
process.env.CUSTOM_MCP_URL,
);
}

const support = createAgent({
instructions:
"You help customers with data analysis, file browsing, and general questions. " +
"Use the available tools as needed and summarize results concisely.",
tools: {
...fromPlugin(analytics),
...fromPlugin(files),
get_weather,
...customMcpServers,
},
});

const trustedMcpHosts = [
process.env.VECTOR_SEARCH_MCP_URL,
process.env.CUSTOM_MCP_URL,
]
.filter((u): u is string => typeof u === "string" && u.length > 0)
.map((u) => new URL(u).hostname);

const appkit = await createApp({
plugins: [
server({ port }),
analytics(),
files(),
agents({
// Ambient tool library referenced by markdown frontmatter `tools: [...]`.
tools: { get_weather },
// Code-defined agents are merged with markdown agents; code wins on key
// collision. Enable auto-inherit for markdown agents so they pick up
// the read-only tools declared on analytics/files; every auto-inherited
// tool must also carry `autoInheritable: true` on its plugin side.
autoInheritTools: { file: true },
agents: { support },
mcp: {
trustedHosts: trustedMcpHosts,
},
}),
],
});

console.log(
`Agent app running on port ${port}. ` +
`Agents: ${appkit.agents.list().join(", ") || "(none)"}. ` +
`Default: ${appkit.agents.getDefault() ?? "(none)"}.`,
);
Loading