-
Notifications
You must be signed in to change notification settings - Fork 43
Update custom server instructions to support deploying both via apps & bundles CLI #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5118cd0
cd4a826
99932ca
99b9e67
ec67018
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| # Example - custom MCP server on Databricks Apps | ||
|
|
||
| This example shows how to create and launch a custom agent on Databricks Apps. | ||
| Please note that this example doesn't use any Databricks SDK, and is independent of the `mcp` package in the root dir of this repo. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Databricks CLI installed and configured | ||
| - `uv` | ||
|
|
||
| ## Local development | ||
|
|
||
| - run `uv` sync: | ||
|
|
||
| ```bash | ||
| uv sync | ||
| ``` | ||
|
|
||
| - start the server locally. Changes will trigger a reload: | ||
|
|
||
| ```bash | ||
| uvicorn custom-server.app:mcp --reload | ||
| ``` | ||
|
|
||
| ## Deploying a custom MCP server on Databricks Apps | ||
|
|
||
| There are two ways to deploy the server on Databricks Apps: using the `databricks apps` CLI or using the `databricks bundle` CLI. Depending on your preference, you can choose either method. | ||
|
|
||
| Both approaches require first configuring Databricks authentication: | ||
| ```bash | ||
| export DATABRICKS_CONFIG_PROFILE=<your-profile-name> # e.g. custom-mcp-server | ||
| databricks auth login --profile "$DATABRICKS_CONFIG_PROFILE" | ||
| ``` | ||
|
|
||
| ### Using `databricks apps` CLI | ||
|
|
||
| To deploy the server using the `databricks apps` CLI, follow these steps: | ||
|
|
||
| Create a Databricks app to host your MCP server: | ||
| ```bash | ||
| databricks apps create mcp-custom-server | ||
| ``` | ||
|
|
||
| Upload the source code to Databricks and deploy the app: | ||
|
|
||
| ```bash | ||
| DATABRICKS_USERNAME=$(databricks current-user me | jq -r .userName) | ||
| databricks sync . "/Users/$DATABRICKS_USERNAME/my-mcp-server" | ||
| databricks apps deploy mcp-custom-server --source-code-path "/Workspace/Users/$DATABRICKS_USERNAME/my-mcp-server" | ||
| ``` | ||
|
|
||
| ### Using `databricks bundle` CLI | ||
|
|
||
| To deploy the server using the `databricks bundle` CLI, follow these steps | ||
|
|
||
| [//]: # (TODO: would be nice to also be able to use the same uv command to auto-install dependencies and run the app) | ||
| Update the `app.yaml` file in this directory to use the following command: | ||
| ```yaml | ||
| command: ["uvicorn", "custom_server.app:app"] | ||
| ``` | ||
|
|
||
| - In this directory, run the following command to deploy and run the MCP server on Databricks Apps: | ||
|
|
||
| ```bash | ||
| uv build --wheel | ||
| databricks bundle deploy | ||
| databricks bundle run custom-mcp-server | ||
| ``` | ||
|
|
||
| ## Connecting to the MCP server | ||
|
|
||
| [//]: # (TODO: once official Databricks docs for using MCP servers in agents are live, replace this with a link) | ||
| [//]: # (to that section) | ||
|
|
||
| To connect to the MCP server, use the `Streamable HTTP` transport with the following URL: | ||
|
|
||
| ``` | ||
| https://your-app-url.usually.ends.with.databricksapps.com/mcp/ | ||
| ``` | ||
|
|
||
| For authentication, you can use the `Bearer` token from your Databricks profile. | ||
| You can get the token by running the following command: | ||
|
|
||
| ```bash | ||
| databricks auth token -p <name-of-your-profile> | ||
| ``` | ||
|
|
||
| Please note that the URL should end with `/mcp/` (including the trailing slash), as this is required for the server to work correctly. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| command: ["uv", "run", "custom-server"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # We only need `uv` in our requirements if deploying via apps CLI | ||
| uv |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,9 @@ | ||
| from pathlib import Path | ||
| from fastapi.staticfiles import StaticFiles | ||
| from mcp.server.fastmcp import FastMCP | ||
| from fastapi import FastAPI | ||
| from fastapi.responses import FileResponse | ||
|
|
||
| STATIC_DIR = Path(__file__).parent / "static" | ||
|
|
||
| # Create an MCP server | ||
| mcp = FastMCP("Custom MCP Server on Databricks Apps") | ||
|
|
@@ -22,14 +24,16 @@ def get_greeting(name: str) -> str: | |
|
|
||
|
|
||
| mcp_app = mcp.streamable_http_app() | ||
| static = StaticFiles(directory=Path(__file__).parent / "static", html=True) | ||
|
|
||
|
|
||
| app = FastAPI( | ||
| lifespan=lambda _: mcp.session_manager.run(), | ||
| ) | ||
|
|
||
| # note the order of mounting here, | ||
| # and don't change it unless you know what you're doing | ||
| app.mount("/api", mcp_app) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have some upcoming product features that expect that the MCP server is hosted at |
||
| app.mount("/", static) | ||
|
|
||
| @app.get("/", include_in_schema=False) | ||
| async def serve_index(): | ||
| return FileResponse(STATIC_DIR / "index.html") | ||
|
|
||
|
|
||
| app.mount("/", mcp_app) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import uvicorn | ||
|
|
||
|
|
||
| def main(): | ||
| uvicorn.run( | ||
| "custom_server.app:app", # import path to your `app` | ||
| host="0.0.0.0", | ||
| port=8000, | ||
| reload=True, # optional | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,6 +88,7 @@ <h3 class="text-lg leading-6 font-medium text-white">Connection Details</h3> | |
| <pre class="bg-gray-900 p-3 rounded overflow-x-auto"> | ||
| <code class="language-python"> | ||
| from databricks.sdk import WorkspaceClient | ||
| from databricks_mcp import DatabricksOAuthClientProvider | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using this new API to configure auth. We'll also recommend this in docs |
||
| from mcp.client.streamable_http import streamablehttp_client as connect | ||
| from mcp import ClientSession | ||
|
|
||
|
|
@@ -96,9 +97,8 @@ <h3 class="text-lg leading-6 font-medium text-white">Connection Details</h3> | |
| async def main(): | ||
| # Connect to a streamable HTTP server | ||
|
|
||
| headers = client.config.authenticate() | ||
| app_url = "https://your.app.url.databricksapps.com/api/mcp" | ||
| async with connect(app_url, headers=headers) as ( | ||
| app_url = "https://your.app.url.databricksapps.com/mcp/" | ||
| async with connect(app_url, auth=DatabricksOAuthClientProvider(client)) as ( | ||
| read_stream, | ||
| write_stream, | ||
| _, | ||
|
|
@@ -118,7 +118,7 @@ <h3 class="text-lg leading-6 font-medium text-white">Connection Details</h3> | |
| Or use your favourite tool | ||
| </dt> | ||
| <dd class="mt-1 text-sm text-gray-100"> | ||
| You can also connect using tools like <strong>Cloude</strong>, <strong>MCP | ||
| You can also connect using tools like <strong>Claude</strong>, <strong>MCP | ||
| Inspector</strong>, or any other compatible client. | ||
| </dd> | ||
| </div> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid conflict with the one deployed via apps CLI