fix(mcp): auto-authorize UC connections when proxy returns JSON-RPC auth error#12
Merged
Conversation
…uth error
The Databricks MCP proxy returns "needs authorization" as an HTTP-200
JSON-RPC error with code -32600 and a message like:
Credential for user identity('...') is not found for the connection
'<name>'. Please login first to the connection by visiting
https://<host>/explore/connections/<name>?o=<workspaceId>
Mason's existing auto-authorize flow only fired on HTTP 401/403, so the
proxy's auth-required path silently logged "Found 0 tools" and the user
was stuck. They had to copy the URL out of the console and visit it
manually before retrying.
This change:
- main.ts mcpRequest: detect JSON-RPC error responses matching the auth
patterns and throw a 401-flavored error. Extract the embedded
authorize URL from the message when present.
- src/mcp.ts: add detectAuthError() that covers HTTP-401 wording AND
the proxy's "Please login first" / "Credential for user identity"
text. Both the manual UC Connect button and the autoConnectMcp loop
use it. Prefer the message-embedded authorize URL over a
reconstructed /explore/connections/<name> path so the workspace id
("?o=...") is preserved when the proxy provides it.
Co-authored-by: Isaac
Co-authored-by: Isaac
The renderer's mcpUrlFor() treated any UC connection with a directHost as if it were an MCP-speaking endpoint and built "<host>/mcp". That shortcut was added for Databricks Apps that host their own MCP server (mcp-salesforce-XXX.aws.databricksapps.com), where bypassing the UC proxy is intentional. But for SaaS endpoints — mcp.atlassian.com, www.googleapis.com, api.githubcopilot.com, graph.microsoft.com — the UC proxy is the only correct path: it handles credential translation, per-user OAuth, and the MCP shim. Hitting those hosts directly with /mcp produces a 404 HTML error page from the upstream SaaS. Gate the directHost shortcut on the hostname matching *.databricksapps.com. Everything else routes through the UC proxy at <workspace>/api/2.0/mcp/external/<name>, which combined with the earlier JSON-RPC auth detection makes UC external connections (Atlassian, GitHub, Gmail, SharePoint, …) connect cleanly on the first authorize. Co-authored-by: Isaac
For tools that take no parameters (e.g. atlassianUserInfo,
getAccessibleAtlassianResources), Anthropic via the Databricks AI
Gateway streams the tool_call with an empty function.arguments
delta. Mason's stream accumulator initialized arguments to "" and
never normalized when no delta came in, so the assistant message
landed in history with arguments: "". The next chat-loop turn sent
that message back to the Gateway, which rightly rejected it:
API 400: Param 'arguments' in the tool_calls function specification
is not a valid JSON string. No content to map due to end-of-input
OpenAI/Anthropic client SDKs normalize empty arguments to "{}" for
exactly this reason. Do the same here after the SSE loop finishes
accumulating tool_calls — affects every model+tool combination that
the gateway round-trips through chat completions, not just Atlassian.
Co-authored-by: Isaac
Many system-managed UC HTTP connections (Google Drive, SharePoint, Gmail, GitHub Copilot API, Tavily REST, etc.) are credential-only OAuth shims for SaaS REST APIs — they share connection_type "HTTP" with real MCP-speaking connections but the Databricks MCP proxy at /api/2.0/mcp/external/<name> returns 404 for them (the proxy forwards to googleapis.com/sharepoint/etc., which 404 on /initialize). The UC API exposes this via the is_mcp_connection field. Filter list-uc-connections to require it be truthy (or absent for legacy workspaces that pre-date the field — backward compatible). Result: Mason's UC MCP picker now only shows connections that actually speak MCP, eliminating the dead-end 404 attempts on Google Drive / SharePoint / etc. Co-authored-by: Isaac
autoConnectMcp loops over every URL ever saved to ~/.mason/config/ workspaces.json. When the UC discovery filter (is_mcp_connection gating) started dropping non-MCP connections from the picker, the URLs from earlier sessions stayed in saved config and kept retrying on every launch — producing repeated 404 spam for connections that will never work (Google Drive, SharePoint, Gmail, etc.). This change prunes them in place. When auto-connect fails on a UC proxy URL with a non-auth 4xx (either immediately or after the authorize-then-retry path), Mason flags the URL as "not actually an MCP server" and drops it from workspace config at the end of the auto-connect loop. The write happens once per session and only when something was actually dropped. Only UC proxy URLs are eligible for auto-pruning — arbitrary user-pasted HTTP MCP URLs aren't touched (transient outage there shouldn't auto-destroy their config). Co-authored-by: Isaac
A user hit:
API 400: Param 'arguments' in the tool_calls function specification
is not a valid JSON string. Unexpected end-of-input...
[Source: {"compute_type": "serverless", "language": "python"; ...]
The model started streaming a tool call, then the stream cut off mid-
JSON (max_tokens hit, abort, or network glitch). Mason's accumulator
kept the partial string {"...":"python" with no closing brace, sent it
back to the Gateway on the next turn, and the Gateway rejected the
whole request — wedging the conversation until reload.
The previous fix only normalized *empty* arguments to "{}". This adds
JSON-validity sanity: if arguments fail JSON.parse, replace with "{}"
and log a warning. Tool runs with no args; model recovers on the next
turn instead of the entire conversation breaking.
Factor into a shared sanitizeToolCalls() helper used on all three
return paths: streamed chat completions, non-streamed chat completions,
and the Responses API translation.
Co-authored-by: Isaac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Mason's UC external MCP connect path silently fails for first-time connections that need per-user authorization. The Databricks MCP proxy returns "needs authorization" as an HTTP-200 JSON-RPC error (code -32600) with a message like:
Mason's existing auto-authorize flow only fired on HTTP 401/403, so users saw `[MCP] Found 0 tools` and were stuck.
Changes
Bumps to 1.4.1.
Test plan
This pull request and its description were written by Isaac.