Factory Labs

Connect Databricks Mosaic AI Agents

Wire a Databricks-managed AI agent to your Factory Labs MCP endpoint via OAuth Bearer.

Databricks Mosaic AI Agent Framework can call any MCP server that speaks the Streamable HTTP transport with OAuth 2.0 Bearer auth — which is exactly what https://api.factorylabs.ai/mcp exposes. This guide walks through the setup so a Databricks agent can read and write CRM records as itself.

Two complementary modes. This page covers the outbound direction — a Databricks agent calling into Factory Labs. If you want Factory Labs to call into a Databricks SQL warehouse, see Connect Databricks (Warehouse) instead; that one uses the federated SQL adapter and is configured via Settings → Integrations.

Prerequisites

  • A Databricks workspace with Mosaic AI Agent Framework enabled.
  • A Factory Labs admin account (to create the OAuth client).
  • The Factory Labs MCP endpoint: https://api.factorylabs.ai/mcp
  • (Optional) A custom subdomain — https://{org-slug}.factorylabs.ai/mcp.

Step 1: Create an OAuth Client in Factory Labs

In Factory Labs, open Settings → Integrations → MCP for Databricks and click Generate setup snippet. Behind the scenes this creates an OAuth client identical to what you get from Settings → API → Create Client, with defaults pre-tuned for Databricks Agents:

FieldDefault
NameDatabricks Mosaic Agent — <workspace>
Redirect URIshttps://<workspace>.cloud.databricks.com/api/2.0/agent/mcp/callback
Scopescrm:read crm:write erp:read warehouse:query

You'll receive a client_id (prefixed crm_) and a client_secret. The secret is shown once — copy it into a Databricks secret scope (see Step 3).

Step 2: OAuth flow used by the agent

Databricks runs the standard authorization_code + PKCE (S256) flow:

Loading diagram…

For full flow details (parameters, error codes, refresh-on-401 behavior) see MCP Authentication.

Step 3: Register the MCP server inside Databricks

Run this in any notebook attached to a runtime that has the databricks-agents package installed (or use the Agent Studio UI):

from databricks.sdk.service.serving import (
    AgentToolDefinition,
    AgentMcpServerConfig,
    AgentOAuthCredentialConfig,
)
from databricks.sdk import WorkspaceClient

w = WorkspaceClient()

w.serving_endpoints.create_agent_tool(
    tool=AgentToolDefinition(
        name="crm_factory",
        mcp=AgentMcpServerConfig(
            url="https://api.factorylabs.ai/mcp",
            transport="streamable_http",
            oauth=AgentOAuthCredentialConfig(
                client_id_secret="secrets/factory_labs/oauth_client_id",
                client_secret_secret="secrets/factory_labs/oauth_client_secret",
                authorization_endpoint="https://api.factorylabs.ai/oauth/authorize",
                token_endpoint="https://api.factorylabs.ai/oauth/token",
                scopes=["crm:read", "crm:write", "erp:read", "warehouse:query"],
            ),
        ),
    )
)

Store the client_id and client_secret in a Databricks secret scope first:

databricks secrets put-secret factory_labs oauth_client_id   --string-value "crm_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
databricks secrets put-secret factory_labs oauth_client_secret --string-value "<the-secret>"

The Mosaic AI runtime handles the token cache, refresh, and retry on 401.

Step 4: Verify the agent can list tools

In the Agent Studio playground, ask the agent:

Use the crm_factory tool to list the first 5 opportunities and show me their stage and amount.

Expected behaviour:

  1. Agent calls the MCP tools/list method (≤ 200 ms cold-start, ≤ 50 ms warm).
  2. Receives the full tool catalog (≈ 30 tools spanning CRM + ERP + RAG + warehouse).
  3. Picks list_records (or search_crm), invokes it, and returns the rows.

Capabilities exposed to Databricks agents

The same tool catalog used by the in-product Assistant is reachable from Databricks. See MCP Tools Reference for the full list. Highlights:

GroupExamplesNotes
CRMsearch_crm, get_opportunity, update_opportunity_stage, create_activityRead + write, scoped by user role
ERPerp_get_inventory, erp_get_order_statusRead-only, when an ERP connection is configured
Warehouse (federated SQL)warehouse_table__<uuid> (one per exposed source)Each call is enforced by query-guard (single SELECT, allow-listed columns, row filter, byte cap)
RAGsearch_knowledge_base, cite_chunkReturns text + cite-anchors
Resourcescrm://schema, crm://pipelines, crm://dashboardsRead-only context

Rate limits

WindowLimitNotes
Per OAuth client600 req/minBurst headroom is 50 % above this; sustained excess returns 429.
Per tenant total3 000 req/min across all clientsAggregated across MCP + REST + Assistant.
Per warehouse tool call1 GiB scanned / call (clamped by query-guard.maxBytes)Tunable per data source.
Token TTL3 600 secondsRefresh by repeating the authorization flow; refresh tokens are not yet issued.

429 responses include Retry-After in seconds. Tools called inside a single agent turn are deduplicated server-side, so a polling loop won't multiply charges.

Troubleshooting

401 Unauthorized with WWW-Authenticate: Bearer resource_metadata=… The Bearer token is missing, expired, or doesn't carry the required scope. Check the agent log for the OAuth refresh attempt — Mosaic AI logs the discovery URL it called.

403 Forbidden on a specific tool The OAuth client lacks the scope that gates that tool. Edit the client in Settings → API, add the missing scope (e.g. crm:write or warehouse:query), and re-issue the secret.

429 Too Many Requests You're past the per-minute burst cap. The Retry-After header tells you when to retry. For a sustained workload, request an upgraded plan or move the read-only portion to the Delta Sharing publish stream so it doesn't hit the request budget at all.

Tools appear but warehouse tool calls fail with INVALID_QUERY The model emitted SQL that violated the guard (multi-statement, DDL, an un-allow-listed column, etc.). The details field of the JSON-RPC response names the rejected token. Tighten the prompt or tell the agent to call describe_<table> first to discover the columns.

Agent can't discover the MCP endpoint Curl the discovery doc to verify it's reachable from the workspace: curl https://api.factorylabs.ai/.well-known/oauth-protected-resource — should return JSON with resource, scopes_supported, and an authorization_servers array.