Skip to content

Commit eb890d2

Browse files
keugenekclaude
andauthored
Improve apps-mcp visibility with branded output headers (#4032)
## Summary This PR improves the Databricks MCP server user experience by adding distinctive branded headers to all tool outputs, making it immediately clear when users are working with the MCP server versus plain Claude/Cursor. <img width="802" height="186" alt="image" src="https://github.com/user-attachments/assets/f3438deb-b1b6-4450-9160-e8c0495973ee" /> ## Changes ### 1. Branded Output Headers Added clear, user-friendly headers to all MCP tool outputs: - **Scaffold**: `🚀 Databricks MCP: App scaffolded successfully` - **Validate**: `🔍 Databricks MCP: Validating your app` - **Deploy**: `🚢 Databricks MCP: Deploying to production` ### 2. README Improvements - Added "Visual Feedback" section explaining the branded headers - Added prominent troubleshooting section for missing MCP headers - Clarified setup flow and removed redundant credentials step (handled by install command) - Added example output showing what users will see - Expanded troubleshooting with 7 concrete steps ### 3. User-Friendly Messages Changed from technical tool names to friendly descriptions that users can understand ## Example Output ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🚀 Databricks MCP: App scaffolded successfully ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Created appkit application at /path/to/app Files copied: 42 ``` ## Testing - ✅ Build succeeds - ✅ All unit tests pass - ✅ Output formatting verified ## Impact Users will now immediately see when they're using the Databricks MCP server through distinctive branded headers. This helps with: - Identifying when MCP is not connected (missing headers = not using MCP) - Understanding what operations are being performed - Providing better transparency in the workflow --------- Co-authored-by: Claude <[email protected]>
1 parent a93dc5a commit eb890d2

File tree

6 files changed

+286
-18
lines changed

6 files changed

+286
-18
lines changed

experimental/apps-mcp/README.md

Lines changed: 93 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,50 @@ A Model Context Protocol (MCP) server for working with Databricks through natura
1717
- **Conversational interface**: Work with Databricks using natural language instead of memorizing CLI commands
1818
- **Context-aware**: Get relevant command suggestions based on your workspace configuration
1919
- **Unified workflow**: Combine data exploration, bundle management, and app deployment in one tool
20+
- **Transparency**: Every MCP tool call displays clear, branded output so you always know when Databricks MCP is working
2021

2122
Perfect for data engineers and developers who want to streamline their Databricks workflows with AI-powered assistance.
2223

24+
**Visual Feedback:**
25+
When using Databricks MCP, you'll see distinctive branded headers in your chat:
26+
```
27+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
28+
🚀 Databricks MCP: App scaffolded successfully
29+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
30+
```
31+
32+
This makes it immediately clear you're using the Databricks MCP server, not just plain Claude or Cursor. If you don't see these headers, the MCP server isn't connected (see Troubleshooting below).
33+
2334
---
2435

2536
## Getting Started
2637

2738
### Quick Setup (Recommended)
2839

29-
1. **Set up Databricks credentials** (required for Databricks tools):
30-
```bash
31-
export DATABRICKS_HOST="https://your-workspace.databricks.com"
32-
export DATABRICKS_TOKEN="dapi..."
33-
export DATABRICKS_WAREHOUSE_ID="your-warehouse-id"
34-
```
35-
36-
2. **Install the MCP server automatically:**
40+
1. **Install the MCP server automatically:**
3741
```bash
3842
databricks experimental apps-mcp install
3943
```
4044

4145
This interactive command will:
4246
- Automatically detect Claude Code and Cursor installations
43-
- Configure the MCP server with proper settings
47+
- Configure the MCP server with proper settings (including credentials)
4448
- Set up the server at user scope (available in all projects)
4549
- Show manual instructions for other agents if needed
4650

47-
3. **Restart your MCP client** (Claude Code, Cursor, etc.) for changes to take effect.
51+
2. **Restart your MCP client** (Claude Code, Cursor, etc.) for changes to take effect.
52+
53+
3. **Verify the connection:**
54+
```
55+
claude /mcp
56+
```
57+
58+
The databricks MCP server should be listed in "connected" state. If it doesn't show up or appears disconnected, see the Troubleshooting section below.
4859

4960
4. **Create your first Databricks app:**
5061

5162
Try this in your MCP client:
63+
5264
```
5365
Explore my Databricks workspace and show me what catalogs are available
5466
```
@@ -69,6 +81,13 @@ Perfect for data engineers and developers who want to streamline their Databrick
6981

7082
If you prefer to configure manually or the automatic installation doesn't work:
7183

84+
**Set up Databricks credentials** (required for Databricks tools):
85+
```bash
86+
export DATABRICKS_HOST="https://your-workspace.databricks.com"
87+
export DATABRICKS_TOKEN="dapi..."
88+
export DATABRICKS_WAREHOUSE_ID="your-warehouse-id"
89+
```
90+
7291
**Add to your MCP config file** (e.g., `~/.claude.json` for global scope):
7392
```json
7493
{
@@ -90,6 +109,70 @@ Then restart your MCP client for changes to take effect
90109

91110
---
92111

112+
### Troubleshooting
113+
114+
#### 🚨 Not seeing Databricks MCP headers in your chat?
115+
116+
If you ask about Databricks or apps but **don't see the distinctive headers** like:
117+
```
118+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
119+
🚀 Databricks MCP: App scaffolded successfully
120+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
121+
```
122+
123+
**You're using plain Claude/Cursor, not the Databricks MCP server!** This means:
124+
- ❌ No access to Databricks data or tools
125+
- ❌ Generic AI responses instead of actual app generation
126+
- ❌ No scaffolding, validation, or deployment capabilities
127+
128+
**Fix it:** Follow the troubleshooting steps below to connect the MCP server.
129+
130+
---
131+
132+
#### General Troubleshooting
133+
134+
If the MCP server doesn't connect or shows errors:
135+
136+
1. **Check MCP server status:**
137+
```
138+
claude /mcp
139+
```
140+
Look for the databricks server - it should show "connected"
141+
142+
2. **Verify credentials:** Make sure your environment variables are set correctly:
143+
```bash
144+
echo $DATABRICKS_HOST
145+
echo $DATABRICKS_WAREHOUSE_ID
146+
# Don't echo token for security
147+
```
148+
149+
3. **Check configuration file:** Verify the MCP server is properly configured in your `~/.claude.json`:
150+
```bash
151+
cat ~/.claude.json | grep -A 10 databricks
152+
```
153+
154+
4. **Restart your MCP client:** After making configuration changes, always restart your client
155+
156+
5. **Check Databricks CLI:** Verify the CLI is installed and accessible:
157+
```bash
158+
databricks --version
159+
databricks experimental apps-mcp --help
160+
```
161+
162+
6. **Test authentication:** Try listing catalogs to verify credentials work:
163+
```bash
164+
databricks catalogs list
165+
```
166+
167+
7. **Ask Claude for help:** Claude can often diagnose and fix MCP connection issues. Try:
168+
```
169+
My databricks MCP server isn't connecting. Can you help troubleshoot?
170+
```
171+
172+
If issues persist, please report them at https://github.com/databricks/cli/issues
173+
174+
---
175+
93176
## Features
94177

95178
The Databricks MCP server provides CLI-based tools for workspace interaction:

experimental/apps-mcp/cmd/init_template.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path/filepath"
1010

1111
"github.com/databricks/cli/cmd/root"
12+
"github.com/databricks/cli/experimental/apps-mcp/lib/common"
1213
"github.com/databricks/cli/libs/cmdio"
1314
"github.com/databricks/cli/libs/template"
1415
"github.com/spf13/cobra"
@@ -238,6 +239,27 @@ See https://docs.databricks.com/en/dev-tools/bundles/templates.html for more inf
238239
}
239240
tmpl.Writer.LogTelemetry(ctx)
240241

242+
// Show branded success message
243+
templateName := "bundle"
244+
if templatePathOrUrl != "" {
245+
templateName = filepath.Base(templatePathOrUrl)
246+
}
247+
outputPath := outputDir
248+
if outputPath == "" {
249+
outputPath = "."
250+
}
251+
// Count files if we can
252+
fileCount := 0
253+
if absPath, err := filepath.Abs(outputPath); err == nil {
254+
_ = filepath.Walk(absPath, func(path string, info os.FileInfo, err error) error {
255+
if err == nil && !info.IsDir() {
256+
fileCount++
257+
}
258+
return nil
259+
})
260+
}
261+
cmdio.LogString(ctx, common.FormatScaffoldSuccess(templateName, outputPath, fileCount))
262+
241263
// Try to read and display CLAUDE.md if present
242264
readClaudeMd(ctx, configFile)
243265

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package common
2+
3+
import "fmt"
4+
5+
const (
6+
headerLine = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
7+
)
8+
9+
// FormatBrandedHeader creates a branded header with the given emoji and message.
10+
func FormatBrandedHeader(emoji, message string) string {
11+
return fmt.Sprintf("%s\n%s Databricks MCP: %s\n%s\n\n",
12+
headerLine, emoji, message, headerLine)
13+
}
14+
15+
// FormatScaffoldSuccess formats a success message for app scaffolding.
16+
func FormatScaffoldSuccess(templateName, workDir string, filesCopied int) string {
17+
header := FormatBrandedHeader("🚀", "App scaffolded successfully")
18+
return fmt.Sprintf("%s✅ Created %s application at %s\n\nFiles copied: %d\n\nTemplate: %s\n",
19+
header, templateName, workDir, filesCopied, templateName)
20+
}
21+
22+
// FormatValidationSuccess formats a success message for validation.
23+
func FormatValidationSuccess(message string) string {
24+
header := FormatBrandedHeader("🔍", "Validating your app")
25+
return fmt.Sprintf("%s✅ %s\n", header, message)
26+
}
27+
28+
// FormatValidationFailure formats a failure message for validation.
29+
func FormatValidationFailure(message string, exitCode int, stdout, stderr string) string {
30+
header := FormatBrandedHeader("🔍", "Validating your app")
31+
return fmt.Sprintf("%s❌ %s\n\nExit code: %d\n\nStdout:\n%s\n\nStderr:\n%s\n",
32+
header, message, exitCode, stdout, stderr)
33+
}
34+
35+
// FormatDeploymentSuccess formats a success message for deployment.
36+
func FormatDeploymentSuccess(appName, appURL string) string {
37+
header := FormatBrandedHeader("🚢", "Deploying to production")
38+
return fmt.Sprintf("%s✅ App '%s' deployed successfully!\n\n🌐 URL: %s\n",
39+
header, appName, appURL)
40+
}
41+
42+
// FormatDeploymentFailure formats a failure message for deployment.
43+
func FormatDeploymentFailure(appName, message string) string {
44+
header := FormatBrandedHeader("🚢", "Deploying to production")
45+
return fmt.Sprintf("%s❌ Deployment failed for '%s'\n\n%s\n",
46+
header, appName, message)
47+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package common
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestFormatBrandedHeader(t *testing.T) {
9+
result := FormatBrandedHeader("🚀", "Test message")
10+
11+
// Check for key components
12+
if !strings.Contains(result, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") {
13+
t.Error("Missing header line")
14+
}
15+
if !strings.Contains(result, "🚀 Databricks MCP: Test message") {
16+
t.Error("Missing branded message")
17+
}
18+
}
19+
20+
func TestFormatScaffoldSuccess(t *testing.T) {
21+
result := FormatScaffoldSuccess("appkit", "/path/to/app", 42)
22+
23+
// Check for key components
24+
if !strings.Contains(result, "🚀 Databricks MCP") {
25+
t.Error("Missing branded header")
26+
}
27+
if !strings.Contains(result, "✅") {
28+
t.Error("Missing success checkmark")
29+
}
30+
if !strings.Contains(result, "appkit") {
31+
t.Error("Missing template name")
32+
}
33+
if !strings.Contains(result, "/path/to/app") {
34+
t.Error("Missing work directory")
35+
}
36+
if !strings.Contains(result, "42") {
37+
t.Error("Missing file count")
38+
}
39+
}
40+
41+
func TestFormatValidationSuccess(t *testing.T) {
42+
result := FormatValidationSuccess("All checks passed")
43+
44+
if !strings.Contains(result, "🔍 Databricks MCP") {
45+
t.Error("Missing branded header")
46+
}
47+
if !strings.Contains(result, "✅") {
48+
t.Error("Missing success checkmark")
49+
}
50+
if !strings.Contains(result, "All checks passed") {
51+
t.Error("Missing success message")
52+
}
53+
}
54+
55+
func TestFormatValidationFailure(t *testing.T) {
56+
result := FormatValidationFailure("Build failed", 1, "stdout output", "stderr output")
57+
58+
if !strings.Contains(result, "🔍 Databricks MCP") {
59+
t.Error("Missing branded header")
60+
}
61+
if !strings.Contains(result, "❌") {
62+
t.Error("Missing failure mark")
63+
}
64+
if !strings.Contains(result, "Build failed") {
65+
t.Error("Missing failure message")
66+
}
67+
if !strings.Contains(result, "Exit code: 1") {
68+
t.Error("Missing exit code")
69+
}
70+
if !strings.Contains(result, "stdout output") {
71+
t.Error("Missing stdout")
72+
}
73+
if !strings.Contains(result, "stderr output") {
74+
t.Error("Missing stderr")
75+
}
76+
}
77+
78+
func TestFormatDeploymentSuccess(t *testing.T) {
79+
result := FormatDeploymentSuccess("my-app", "https://example.com/app")
80+
81+
if !strings.Contains(result, "🚢 Databricks MCP") {
82+
t.Error("Missing branded header")
83+
}
84+
if !strings.Contains(result, "✅") {
85+
t.Error("Missing success checkmark")
86+
}
87+
if !strings.Contains(result, "my-app") {
88+
t.Error("Missing app name")
89+
}
90+
if !strings.Contains(result, "https://example.com/app") {
91+
t.Error("Missing app URL")
92+
}
93+
}
94+
95+
func TestFormatDeploymentFailure(t *testing.T) {
96+
result := FormatDeploymentFailure("my-app", "Connection timeout")
97+
98+
if !strings.Contains(result, "🚢 Databricks MCP") {
99+
t.Error("Missing branded header")
100+
}
101+
if !strings.Contains(result, "❌") {
102+
t.Error("Missing failure mark")
103+
}
104+
if !strings.Contains(result, "my-app") {
105+
t.Error("Missing app name")
106+
}
107+
if !strings.Contains(result, "Connection timeout") {
108+
t.Error("Missing error message")
109+
}
110+
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
/*
22
Package providers contains MCP tool providers.
33
4-
Each provider implements a set of related tools:
4+
The clitools provider implements CLI-based tools for Databricks integration:
55
6-
- databricks: Databricks API integration
7-
- io: Project scaffolding and validation
8-
- clitools: CLI exploration and invocation
9-
- deployment: Application deployment (optional)
6+
- explore: Discover workspace resources and get workflow recommendations
7+
- invoke_databricks_cli: Execute Databricks CLI commands
8+
- databricks_configure_auth: Configure workspace authentication
109
1110
Provider Interface:
1211
@@ -16,5 +15,8 @@ Provider Interface:
1615
1716
Providers are registered with the MCP server during initialization
1817
and their tools become available to AI agents.
18+
19+
The CLI-based approach leverages existing bundle commands for app
20+
scaffolding, validation, and deployment rather than duplicating API logic.
1921
*/
2022
package providers

0 commit comments

Comments
 (0)