Skip to content

feat(skill): add databricks-custom-mcp-server#550

Draft
dgokeeffe wants to merge 1 commit into
databricks-solutions:mainfrom
dgokeeffe:add-custom-mcp-server-skill
Draft

feat(skill): add databricks-custom-mcp-server#550
dgokeeffe wants to merge 1 commit into
databricks-solutions:mainfrom
dgokeeffe:add-custom-mcp-server-skill

Conversation

@dgokeeffe
Copy link
Copy Markdown
Contributor

What

Adds a new skill databricks-custom-mcp-server to databricks-skills/. Captures the end-to-end recipe for building a custom MCP server on Databricks Apps and governing it through Unity Catalog + Supervisor Agents — including the four-layer workaround for the (currently common) case where the workspace OAuth server doesn't yet enable Dynamic Client Registration.

Why

There's no single Databricks doc page covering the full lifecycle: build → deploy → register in UC → attach to a Supervisor Agent. Each layer has at least one non-obvious gotcha:

Gotcha Surfaces as
Apps SSO returns 302→200 HTML for plain GETs Expected HTTP 401 from MCP URL for OAuth discovery, got 200
Workspace OAuth server lacks registration_endpoint Authorization Server does NOT support Dynamic Client Registration
No MCP connection type in UC CONNECTION_TYPE_NOT_SUPPORTED on CREATE CONNECTION TYPE MCP
App's auto-provisioned OAuth client isn't patchable + has wrong redirect URI allowlist invalid_request: redirect_uri 'https://.../login/oauth/http.html' not registered for OAuth application
Both tool_type=app and tool_type=uc_connection register the same MCP server Duplicate tool name 'X' detected for agent 'main'

The skill documents the workaround for each and bundles a reusable scripts/register_mcp_in_uc.py that codifies the four-layer recipe (account-admin custom OAuth integration → UC HTTP connection with is_mcp_connection:true → detach duplicate tool_type=app → user consent click).

Files

  • SKILL.md — entry point with critical rules, surface-decision table, lifecycle diagram, validation checklist
  • 1-build-fastmcp-server.md — FastMCP + FastAPI skeleton, tool-design rules, user-token passthrough
  • 2-deploy-as-databricks-app.mdapp.yaml, SDK + CLI deploy, SP grants, restart-as-recovery
  • 3-register-in-unity-catalog.md — Path 1 (DCR) + Path 2 (manual four-layer); verification via server_label underscore-vs-dash check
  • 4-attach-to-supervisor-agent.mdtool_type=app vs tool_type=uc_connection, mcp_approval_request flow
  • scripts/register_mcp_in_uc.py — idempotent reference implementation of the four-layer recipe

Wiring:

  • Added to DATABRICKS_SKILLS list in install_skills.sh
  • Added get_skill_description + get_skill_extra_files cases
  • Added to README.md under Development & Deployment

How tested

Recipe distilled while wiring an ontology-bound MCP server for a real customer demo on a workspace where DCR is disabled. The verification check at the bottom of section 3 (server_label shape: _ = UC route, - = app route) is what confirms catalog-native routing. All registration steps run via the register_mcp_in_uc.py script idempotently.

Status

Draft — opening for visibility / review queue. Ready to mark ready-for-review when the team has bandwidth.

Captures the end-to-end recipe for building a custom MCP server on
Databricks Apps and governing it through Unity Catalog + Supervisor
Agents — including the four-layer workaround for the (currently common)
case where the workspace OAuth server doesn't enable Dynamic Client
Registration.

Files
-----
- databricks-skills/databricks-custom-mcp-server/SKILL.md
  Entry point. Frontmatter description packs failure-mode phrases a
  developer will paste verbatim ("Authorization Server does NOT support
  Dynamic Client Registration", "Duplicate tool name detected",
  "redirect_uri not registered for OAuth application") so the skill
  fires precisely when someone hits the same gauntlet.

- 1-build-fastmcp-server.md
  FastMCP + FastAPI server skeleton, tool-design rules (type hints,
  one-line docstring summaries, validate at the tool boundary),
  Lakebase OAuth credential rotation, warehouse query helper, user-token
  passthrough via x-forwarded-access-token.

- 2-deploy-as-databricks-app.md
  app.yaml / manifest.yaml shape, SDK + CLI deploy paths, the SP grants
  block that every tool downstream needs, smoke tests, restart-as-
  recovery for the zombie-app state.

- 3-register-in-unity-catalog.md  (the big one)
  Path 1: register_mcp_server_via_dcr() with the Apps-SSO
  requests.get monkey-patch needed for the discovery 401 handshake.
  Path 2: the manual four-layer recipe when DCR isn't enabled
  (account-admin custom OAuth integration → UC HTTP connection with
  is_mcp_connection:true → detach duplicate tool_type=app → per-user
  consent click). Includes the verification check that distinguishes
  UC routing (underscore-style server_label) from app routing
  (dash-style server_label).

- 4-attach-to-supervisor-agent.md
  tool_type=app vs tool_type=uc_connection auth-model tradeoff,
  duplicate-tool-name conflict resolution, mcp_approval_request
  human-in-the-loop pattern, OpenAI-compatible serving-endpoint
  invocation shape ("input" not "messages").

- scripts/register_mcp_in_uc.py
  Idempotent four-layer registration script — drops + recreates the
  UC connection, detaches duplicate app tools, attaches the
  uc_connection tool on a supervisor. Supports --rotate-secret.

Registration
------------
- Added to DATABRICKS_SKILLS list in install_skills.sh
- Added get_skill_description + get_skill_extra_files cases
- Added to README.md under Development & Deployment

Tested
------
End-to-end against a workspace where DCR is disabled (the recipe was
distilled while wiring an ontology-bound MCP server for a real customer
demo). The verification check at the bottom of section 3 — server_label
shape — is what confirms catalog-native routing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant