Compartilhar via


Usar servidores MCP gerenciados do Databricks

Important

Esse recurso está em Beta. Os administradores do workspace podem controlar o acesso a esse recurso na página Visualizações . Consulte Gerenciar visualizações do Azure Databricks.

Os servidores MCP gerenciados pelo Databricks são servidores prontos para uso que conectam seus agentes de IA a dados armazenados no Catálogo do Unity, índices de Pesquisa de Vetores do Databricks, espaços do Genie e funções personalizadas.

Servidores gerenciados disponíveis

Para exibir seus servidores MCP e suas URLs de ponto de extremidade, acesse seu workspace>Agentes>Servidores MCP:

Guia Servidor MCP de agentes

O Databricks fornece os seguintes servidores MCP que funcionam prontos para uso.

Servidor MCP Description Padrão de URL
Busca em vetores Consultar índices de Pesquisa de Vetor para localizar documentos relevantes. Há suporte apenas para índices com inserções gerenciadas do Databricks. https://<workspace-hostname>/api/2.0/mcp/vector-search/{catalog}/{schema}
Espaço do gênio Consultar espaços do Genie para analisar dados estruturados usando linguagem natural. Use o servidor Genie MCP ao conectar assistentes externos de IA, como Claude ou ChatGPT, aos seus dados para operações de leitura somente.
Nota: O servidor MCP gerenciado para Genie invoca o Genie como uma ferramenta MCP, o que significa que o histórico não é passado ao invocar as APIs do Genie. Como alternativa, você pode usar o Genie em um sistema de vários agentes.
https://<workspace-hostname>/api/2.0/mcp/genie/{genie_space_id}
Funções do Unity Catalog Use funções do Catálogo do Unity para executar consultas SQL predefinidas. https://<workspace-hostname>/api/2.0/mcp/functions/{catalog}/{schema}
DBSQL Execute o SQL gerado por IA. Use o servidor MCP do DBSQL para criar pipelines de dados com ferramentas de codificação de IA (Claude Code, Cursor, Codex etc). Para recuperação de dados em modo somente leitura e integrações de chatbot, use o Genie em vez disso. https://<workspace-hostname>/api/2.0/mcp/sql

Cenário de exemplo

Considere um agente personalizado que ajuda no suporte ao cliente. Você pode conectá-lo a vários servidores MCP gerenciados:

  • Pesquisa de vetor: https://<workspace-hostname>/api/2.0/mcp/vector-search/prod/customer_support
    • Pesquisar documentação e tíquetes de suporte
  • Genie Space: https://<workspace-hostname>/api/2.0/mcp/genie/{billing_space_id}
    • Consultar dados de cobrança e informações do cliente
  • Funções UC: https://<workspace-hostname>/api/2.0/mcp/functions/prod/billing
    • Executar funções personalizadas para pesquisas e atualizações de conta

Isso fornece ao agente acesso a dados não estruturados (tíquetes de suporte), dados estruturados (tabelas de cobrança) e lógica de negócios personalizada.

Notebooks de exemplo: construir um agente com servidores MCP do Databricks

Os seguintes notebooks mostram como criar agentes do LangGraph e OpenAI que chamam ferramentas MCP usando servidores MCP geridos pelo Databricks.

Agente de chamada de ferramentas do LANGGraph MCP

Obter laptop

Agente de chamada de ferramentas do OPENAI MCP

Obter laptop

Criar um agente a partir de um ambiente local

Conectar-se a um servidor MCP no Databricks é semelhante à conexão com qualquer outro servidor MCP remoto. Você pode se conectar ao servidor usando SDKs padrão, como o SDK do Python do MCP. A principal diferença é que os servidores MCP do Databricks são seguros por padrão e exigem que os clientes especifiquem a autenticação.

A biblioteca python databricks-mcp ajuda a simplificar a autenticação no código do agente personalizado.

A maneira mais simples de desenvolver o código do agente é executá-lo localmente e autenticar-se em seu workspace. Siga estas etapas para criar um agente de IA que se conecte a um servidor MCP do Databricks.

Configure seu ambiente

  1. Use o OAuth para autenticar em seu workspace. Execute o seguinte comando em um terminal local:

    databricks auth login --host https://<your-workspace-hostname>
    
  2. Quando solicitado, reate um nome de perfil e anote-o para uso posterior. O nome do perfil padrão é DEFAULT.

  3. Verifique se você tem um ambiente local com Python 3.12 ou superior e instale dependências:

    pip install -U "mcp>=1.9" "databricks-sdk[openai]" "mlflow>=3.1.0" "databricks-agents>=1.0.0" "databricks-mcp"
    

Testar sua conexão de ambiente local

A computação sem servidor deve ser habilitada em seu workspace para executar este snippet.

Valide sua conexão com o servidor MCP listando suas ferramentas do Catálogo do Unity e executando a ferramenta interna de interpretador de código python.

  1. Execute o seguinte código para validar sua conexão com o servidor MCP:
from databricks_mcp import DatabricksMCPClient
from databricks.sdk import WorkspaceClient

# TODO: Update to the Databricks CLI profile name you specified when
# configuring authentication to the workspace.
databricks_cli_profile = "YOUR_DATABRICKS_CLI_PROFILE"
assert (
    databricks_cli_profile != "YOUR_DATABRICKS_CLI_PROFILE"
), "Set databricks_cli_profile to the Databricks CLI profile name you specified when configuring authentication to the workspace"
workspace_client = WorkspaceClient(profile=databricks_cli_profile)
workspace_hostname = workspace_client.config.host
mcp_server_url = f"{workspace_hostname}/api/2.0/mcp/functions/system/ai"

# This code uses the Unity Catalog functions MCP server to expose built-in
# AI tools under `system.ai`, like the `system.ai.python_exec` code interpreter tool
def test_connect_to_server():
    mcp_client = DatabricksMCPClient(server_url=mcp_server_url, workspace_client=workspace_client)
    tools = mcp_client.list_tools()

    print(
        f"Discovered tools {[t.name for t in tools]} "
        f"from MCP server {mcp_server_url}"
    )

    result = mcp_client.call_tool(
        "system__ai__python_exec", {"code": "print('Hello, world!')"}
    )
    print(
        f"Called system__ai__python_exec tool and got result "
        f"{result.content}"
    )


if __name__ == "__main__":
    test_connect_to_server()

Criar o agente

  1. Baseie-se no código acima para definir um agente de turno único básico que usa ferramentas. Salve o código do agente localmente como um arquivo chamado mcp_agent.py:

     import json
     import uuid
     import asyncio
     from typing import Any, Callable, List
     from pydantic import BaseModel
    
     import mlflow
     from mlflow.pyfunc import ResponsesAgent
     from mlflow.types.responses import ResponsesAgentRequest, ResponsesAgentResponse
    
     from databricks_mcp import DatabricksMCPClient
     from databricks.sdk import WorkspaceClient
    
     # 1) CONFIGURE YOUR ENDPOINTS/PROFILE
     LLM_ENDPOINT_NAME = "databricks-claude-sonnet-4-5"
     SYSTEM_PROMPT = "You are a helpful assistant."
     DATABRICKS_CLI_PROFILE = "YOUR_DATABRICKS_CLI_PROFILE"
     assert (
         DATABRICKS_CLI_PROFILE != "YOUR_DATABRICKS_CLI_PROFILE"
     ), "Set DATABRICKS_CLI_PROFILE to the Databricks CLI profile name you specified when configuring authentication to the workspace"
     workspace_client = WorkspaceClient(profile=DATABRICKS_CLI_PROFILE)
     host = workspace_client.config.host
     # Add more MCP server URLs here if desired, for example:
     # f"{host}/api/2.0/mcp/vector-search/prod/billing"
     # to include vector search indexes under the prod.billing schema, or
     # f"{host}/api/2.0/mcp/genie/<genie_space_id>"
     # to include a Genie space
     MANAGED_MCP_SERVER_URLS = [
         f"{host}/api/2.0/mcp/functions/system/ai",
     ]
     # Add Custom MCP Servers hosted on Databricks Apps
     CUSTOM_MCP_SERVER_URLS = []
    
    
    
     # 2) HELPER: convert between ResponsesAgent “message dict” and ChatCompletions format
     def _to_chat_messages(msg: dict[str, Any]) -> List[dict]:
         """
         Take a single ResponsesAgent‐style dict and turn it into one or more
         ChatCompletions‐compatible dict entries.
         """
         msg_type = msg.get("type")
         if msg_type == "function_call":
             return [
                 {
                     "role": "assistant",
                     "content": None,
                     "tool_calls": [
                         {
                             "id": msg["call_id"],
                             "type": "function",
                             "function": {
                                 "name": msg["name"],
                                 "arguments": msg["arguments"],
                             },
                         }
                     ],
                 }
             ]
         elif msg_type == "message" and isinstance(msg["content"], list):
             return [
                 {
                     "role": "assistant" if msg["role"] == "assistant" else msg["role"],
                     "content": content["text"],
                 }
                 for content in msg["content"]
             ]
         elif msg_type == "function_call_output":
             return [
                 {
                     "role": "tool",
                     "content": msg["output"],
                     "tool_call_id": msg["tool_call_id"],
                 }
             ]
         else:
             # fallback for plain {"role": ..., "content": "..."} or similar
             return [
                 {
                     k: v
                     for k, v in msg.items()
                     if k in ("role", "content", "name", "tool_calls", "tool_call_id")
                 }
             ]
    
    
     # 3) “MCP SESSION” + TOOL‐INVOCATION LOGIC
     def _make_exec_fn(
         server_url: str, tool_name: str, ws: WorkspaceClient
     ) -> Callable[..., str]:
         def exec_fn(**kwargs):
             mcp_client = DatabricksMCPClient(server_url=server_url, workspace_client=ws)
             response = mcp_client.call_tool(tool_name, kwargs)
             return "".join([c.text for c in response.content])
    
         return exec_fn
    
    
     class ToolInfo(BaseModel):
         name: str
         spec: dict
         exec_fn: Callable
    
    
     def _fetch_tool_infos(ws: WorkspaceClient, server_url: str) -> List[ToolInfo]:
         print(f"Listing tools from MCP server {server_url}")
         infos: List[ToolInfo] = []
         mcp_client = DatabricksMCPClient(server_url=server_url, workspace_client=ws)
         mcp_tools = mcp_client.list_tools()
         for t in mcp_tools:
             schema = t.inputSchema.copy()
             if "properties" not in schema:
                 schema["properties"] = {}
             spec = {
                 "type": "function",
                 "function": {
                     "name": t.name,
                     "description": t.description,
                     "parameters": schema,
                 },
             }
             infos.append(
                 ToolInfo(
                     name=t.name, spec=spec, exec_fn=_make_exec_fn(server_url, t.name, ws)
                 )
             )
         return infos
    
    
     # 4) “SINGLE‐TURN” AGENT CLASS
     class SingleTurnMCPAgent(ResponsesAgent):
         def _call_llm(self, history: List[dict], ws: WorkspaceClient, tool_infos):
             """
             Send current history → LLM, returning the raw response dict.
             """
             client = ws.serving_endpoints.get_open_ai_client()
             flat_msgs = []
             for msg in history:
                 flat_msgs.extend(_to_chat_messages(msg))
             return client.chat.completions.create(
                 model=LLM_ENDPOINT_NAME,
                 messages=flat_msgs,
                 tools=[ti.spec for ti in tool_infos],
             )
    
         def predict(self, request: ResponsesAgentRequest) -> ResponsesAgentResponse:
             ws = WorkspaceClient(profile=DATABRICKS_CLI_PROFILE)
    
             # 1) build initial history: system + user
             history: List[dict] = [{"role": "system", "content": SYSTEM_PROMPT}]
             for inp in request.input:
                 history.append(inp.model_dump())
    
             # 2) call LLM once
             tool_infos = [
                 tool_info
                 for mcp_server_url in (MANAGED_MCP_SERVER_URLS + CUSTOM_MCP_SERVER_URLS)
                 for tool_info in _fetch_tool_infos(ws, mcp_server_url)
             ]
             tools_dict = {tool_info.name: tool_info for tool_info in tool_infos}
             llm_resp = self._call_llm(history, ws, tool_infos)
             raw_choice = llm_resp.choices[0].message.to_dict()
             raw_choice["id"] = uuid.uuid4().hex
             history.append(raw_choice)
    
             tool_calls = raw_choice.get("tool_calls") or []
             if tool_calls:
                 # (we only support a single tool in this “single‐turn” example)
                 fc = tool_calls[0]
                 name = fc["function"]["name"]
                 args = json.loads(fc["function"]["arguments"])
                 try:
                     tool_info = tools_dict[name]
                     result = tool_info.exec_fn(**args)
                 except Exception as e:
                     result = f"Error invoking {name}: {e}"
    
                 # 4) append the “tool” output
                 history.append(
                     {
                         "type": "function_call_output",
                         "role": "tool",
                         "id": uuid.uuid4().hex,
                         "tool_call_id": fc["id"],
                         "output": result,
                     }
                 )
    
                 # 5) call LLM a second time and treat that reply as final
                 followup = (
                     self._call_llm(history, ws, tool_infos=[]).choices[0].message.to_dict()
                 )
                 followup["id"] = uuid.uuid4().hex
    
                 assistant_text = followup.get("content", "")
                 return ResponsesAgentResponse(
                     output=[
                         {
                             "id": uuid.uuid4().hex,
                             "type": "message",
                             "role": "assistant",
                             "content": [{"type": "output_text", "text": assistant_text}],
                         }
                     ],
                     custom_outputs=request.custom_inputs,
                 )
    
             # 6) if no tool_calls at all, return the assistant’s original reply
             assistant_text = raw_choice.get("content", "")
             return ResponsesAgentResponse(
                 output=[
                     {
                         "id": uuid.uuid4().hex,
                         "type": "message",
                         "role": "assistant",
                         "content": [{"type": "output_text", "text": assistant_text}],
                     }
                 ],
                 custom_outputs=request.custom_inputs,
             )
    
    
     mlflow.models.set_model(SingleTurnMCPAgent())
    
     if __name__ == "__main__":
         req = ResponsesAgentRequest(
             input=[{"role": "user", "content": "What's the 100th Fibonacci number?"}]
         )
         resp = SingleTurnMCPAgent().predict(req)
         for item in resp.output:
             print(item)
    
    

Implantar seu agente

Quando você estiver pronto para implantar um agente que se conecta a servidores MCP gerenciados, consulte Implantar um agente para aplicativos de IA generativos.

Especifique todos os recursos de que seu agente precisa no momento do log. Ver autenticação para recursos do Databricks

Por exemplo, se o agente usar as URLs do servidor MCP listadas abaixo, você deve especificar todos os índices de pesquisa de vetor nos esquemas prod.customer_support e prod.billing. Você também deve especificar todas as funções do Catálogo do Unity em prod.billing:

  • https://<your-workspace-hostname>/api/2.0/mcp/vector-search/prod/customer_support
  • https://<your-workspace-hostname>/api/2.0/mcp/vector-search/prod/billing
  • https://<your-workspace-hostname>/api/2.0/mcp/functions/prod/billing

Se o agente se conectar aos servidores MCP no Databricks para descobrir e executar ferramentas, registre, com seu agente, os recursos que esses servidores MCP necessitam. O Databricks recomenda a instalação do databricks-mcp pacote PyPI para simplificar esse processo.

Em particular, se você usar servidores MCP gerenciados, poderá usar databricks_mcp.DatabricksMCPClient().get_databricks_resources(<server_url>) para recuperar os recursos necessários para o servidor MCP gerenciado. Se o agente consultar um servidor MCP personalizado hospedado em um aplicativo do Databricks, você poderá configurar a autorização explicitamente incluindo o servidor como um recurso ao registrar o log do seu modelo.

Por exemplo, para implantar o agente definido acima, execute o seguinte código, supondo que você salvou a definição de código do agente em mcp_agent.py:

import os
from databricks.sdk import WorkspaceClient
from databricks import agents
import mlflow
from mlflow.models.resources import DatabricksFunction, DatabricksServingEndpoint, DatabricksVectorSearchIndex
from mcp_agent import LLM_ENDPOINT_NAME
from databricks_mcp import DatabricksMCPClient

# TODO: Update this to your Databricks CLI profile name
databricks_cli_profile = "YOUR_DATABRICKS_CLI_PROFILE"
assert (
    databricks_cli_profile != "YOUR_DATABRICKS_CLI_PROFILE"
), "Set databricks_cli_profile to the Databricks CLI profile name you specified when configuring authentication to the workspace"
workspace_client = WorkspaceClient(profile=databricks_cli_profile)


# Configure MLflow and the Databricks SDK to use your Databricks CLI profile
current_user = workspace_client.current_user.me().user_name
mlflow.set_tracking_uri(f"databricks://{databricks_cli_profile}")
mlflow.set_registry_uri(f"databricks-uc://{databricks_cli_profile}")
mlflow.set_experiment(f"/Users/{current_user}/databricks_docs_example_mcp_agent")
os.environ["DATABRICKS_CONFIG_PROFILE"] = databricks_cli_profile

MANAGED_MCP_SERVER_URLS = [
    f"{host}/api/2.0/mcp/functions/system/ai",
]
# Log the agent defined in mcp_agent.py
here = os.path.dirname(os.path.abspath(__file__))
agent_script = os.path.join(here, "mcp_agent.py")
resources = [
    DatabricksServingEndpoint(endpoint_name=LLM_ENDPOINT_NAME),
    DatabricksFunction("system.ai.python_exec"),
    # --- Uncomment and edit the following lines to include custom mcp servers hosted on Databricks Apps ---
    # DatabricksApp(app_name="app-name")
]

for mcp_server_url in MANAGED_MCP_SERVER_URLS:
    mcp_client = DatabricksMCPClient(server_url=mcp_server_url, workspace_client=workspace_client)
    resources.extend(mcp_client.get_databricks_resources())

with mlflow.start_run():
    logged_model_info = mlflow.pyfunc.log_model(
        artifact_path="mcp_agent",
        python_model=agent_script,
        resources=resources,
    )

# TODO Specify your UC model name here
UC_MODEL_NAME = "main.default.databricks_docs_mcp_agent"
registered_model = mlflow.register_model(logged_model_info.model_uri, UC_MODEL_NAME)

agents.deploy(
    model_name=UC_MODEL_NAME,
    model_version=registered_model.version,
)

Próximas etapas