Greetings @smferro54epam , the errors point to two distinct issues: your custom MCP app expects OAuth-based Databricks credentials (not a raw bearer token), and the URL you pass to the HTTP transport must be a fully qualified https URL to the appโs /mcp endpoint.
Whatโs failing and why
- A 401 Unauthorized from the MCP endpoint means the request lacked valid authentication for the target resource, which happens if you send a PAT or an arbitrary โBearerโ header instead of the Databricks OAuth flow used by the MCP connection helpers.
- httpx.UnsupportedProtocol: โRequest URL is missing an 'http://' or 'https://' protocolโ indicates the string passed to the client lacks a scheme or isnโt a proper HTTP(S) URL, which often happens if the variable holds just โ<mcp-app-url>/mcpโ without the https:// prefix or if an object is passed instead of a string.
- The official guidance for custom MCP servers on Databricks Apps shows connecting with streamable HTTP transport and DatabricksOAuthClientProvider to mint and refresh tokens; direct bearer tokens are not supported for this flow, and OAuth is the supported method for custom servers.
Fix checklist
- Use the exact app URL including scheme and path, for example โhttps://mcp-server.databricksapps.com/mcpโ or the URL shown in the Apps UI for your deployed MCP server; do not drop the โhttps://โ or the โ/mcpโ path if your app exposes it there.
- From a Databricks notebook, construct a WorkspaceClient and pass it to DatabricksOAuthClientProvider, then connect with mcp.client.streamable_http (aliased as connect in the docs); ensure you await session.initialize() before calling list_tools.
- Choose the right auth context: use ModelServingUserCredentials for onโbehalfโof user flows inside agents, or a service principal client_id/client_secret in system contexts; custom servers support OAuth and the examples show both patterns.
- Confirm your MCP server implements HTTP-compatible โstreamable HTTPโ transport and that your app listens on the correct port (Databricks Apps default to 8000 unless overridden), as required by the custom MCP hosting guide.
- If running in a notebook event loop, await the top-level async function once; avoid double-running event loops, and keep your call signatures identical to the documented examples to prevent protocol/loop issues.
Minimal working example (notebook)
```python
from databricks.sdk import WorkspaceClient
from databricks_mcp import DatabricksOAuthClientProvider
from mcp.client.streamable_http import streamablehttp_client as connect
from mcp import ClientSession
async def main():
app_url = "https://mcp-server.databricksapps.com/mcp" # replace with your appโs URL
client = WorkspaceClient() # or WorkspaceClient(credentials_strategy=ModelServingUserCredentials())
async with connect(app_url, auth=DatabricksOAuthClientProvider(client)) as (r, w, _):
async with ClientSession(r, w) as session:
await session.initialize()
tools = await session.list_tools()
print([t.name for t in tools.tools])
await main()
```
This mirrors the official โNotebookโ and โAgent codeโ examples for custom MCP servers and ensures both a valid https URL and OAuth-backed authentication are used.
Wiring into ResponsesAgent and a supervisor
- When using the MCP server from agent code, use the same OAuth approach and log your agent with the proper resource scope so the runtime can pass tokens to the app; the docs call out logging the agent model with apps.apps or DatabricksApps depending on auth mode.
- For onโbehalfโof user, set credentials_strategy=ModelServingUserCredentials in WorkspaceClient so the agent calls to the MCP server are executed under the end userโs authorization context.
Common pitfalls to avoid
- Sending a PAT or a hand-crafted โAuthorization: Bearer โฆโ header to the MCP app; use DatabricksOAuthClientProvider instead so tokens are minted/refreshed correctly for the app endpoint.
- Using a workspace-relative path or templated variable that expands to โ<mcp-app-url>/mcpโ without โhttps://โ; httpx will throw UnsupportedProtocol if the scheme is missing.
- Skipping session.initialize() before tool calls; the documented sequence initializes the MCP session before listing or invoking tools.
If it still 401s
- Verify the app URL is correct and reachable and that the app is deployed and running in Databricks Apps, then re-run the exact sample from the docs to isolate config issues from app code issues.
- Check the HTTP semantics for 401: the server should challenge with WWWโAuthenticate when credentials are missing or reject invalid credentials; confirm your request is indeed using the OAuth flow from the helper and not mixing headers from a prior attempt.
For context, this thread describes the same two symptoms (401 with โBearerโ and httpx UnsupportedProtocol when trying other connection methods), which align with the fixes above: use OAuth via the Databricks helper and pass a fully qualified https app URL.
Hope this helps, Louis.