03-tools-and-mcp

star 4

Use when wiring tools into an OpenAI Agents SDK agent: local Python function tools, DatabricksMCPClient connections, and MCPServerSse for MCP servers. Track A Step 3. Builds on shared concepts from F3 (Tools and Data Access).

databricks-solutions By databricks-solutions schedule Updated 6/6/2026

name: 03-tools-and-mcp description: > Use when wiring tools into an OpenAI Agents SDK agent: local Python function tools, DatabricksMCPClient connections, and MCPServerSse for MCP servers. Track A Step 3. Builds on shared concepts from F3 (Tools and Data Access). license: Apache-2.0 clients: [ide_cli, genie_code] bundle_resource: none deploy_verb: none deploy_note: "Tool + MCP wiring (local function tools, DatabricksMCPClient, MCPServerSse) — code, no bundle resource. Resolves identically on both clients; on Genie Code use its built-in tool surface for ad-hoc calls and runDatabricksCli for grants. See skills/genie-code-environment." coverage: full metadata: last_verified: "2026-06-05" volatility: high upstream_sources: [] author: "prashanth-subrahmanyam" version: "3.1.0" domain: "genai-agents" pipeline_position: "A3" consumes: "customized_agent, agent_class, mcp_server_knowledge" produces: "agent_with_tools, mcp_connections, resource_grants" grounded_in: "docs.databricks.com/aws/en/generative-ai/agent-framework/author-agent, docs.databricks.com/aws/en/generative-ai/agent-framework/build-agent-tool, openai.github.io/openai-agents-python/tools/" fields_read: - agent.tools - agent.mcp_servers - agent.knowledge_base_backend - docs.agent_tool_plan.selected_tools - docs.agent_tool_plan.selected_mcp_servers

Track A Step 3: Agent SDK Tool Wiring

Wire tools into your OpenAI Agents SDK agent so it can query data, search documents, call functions, and connect to external services.

This step focuses on how to wire tools into the Agent class. For background on which MCP servers exist, how external MCP works, resource grants, and retriever schemas, see F3: Tools and Data Access.

Tool Plan Input Contract

For the Agents Accelerator, prefer docs/agent_tool_plan.yaml over inferred defaults. Wire only the tools listed in selected_tools[].

Tool families not selected are skipped and recorded in verification as skipped, not failed.

For SQL MCP, enforce the read-only guardrails from the plan before any smoke test. Reject generated SQL containing INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, MERGE, or TRUNCATE when readonly: true.

Use docs/agent_tool_plan.yaml.verification.tool_smoke_tests[] as the source of smoke prompts. Every selected tool must produce at least one MLflow TOOL span.

OpenAI Agents SDK SQL MCP wiring example:

from agents.mcp import MCPServerSse

sql_mcp = MCPServerSse(
    url=f"{host}/api/2.0/mcp/sql",
    headers={"Authorization": f"Bearer {workspace_client.config.token}"},
)

When to Use

  • Your agent is running (Steps 1-2) but only generates text — it needs to do things: query data, search documents, call APIs.
  • You want to connect to Databricks managed MCP servers or external MCP servers from an OpenAI Agents SDK agent.
  • You need to add local function tools for custom business logic.

Foundation Prerequisite Check

Foundation Step 3 (Tools and Data Access) should be understood before this step. Verify:

python3 -c "from databricks_mcp import DatabricksMCPClient; print('F3: OK')" 2>/dev/null || echo "F3: FAIL — pip install databricks-mcp"

If F3 fails, install databricks-mcp and review F3: Tools and Data Access.


Canonical Tool Catalog (pick what your agent needs)

Track A custom agents typically combine three classes of tools. Pick from this catalog based on the data your agent must reach:

Class What it answers Backing skill Wire-in pattern
Knowledge Assistant (managed doc Q&A with citations) "What does our policy say about X?" F5: Knowledge Assistant Lifecycle — produces ka_endpoint_name Call the KA Model Serving endpoint from a @function_tool (see Wiring KA as a function tool below)
Genie Space (NL → SQL on UC tables, conversational analytics) "How many active customers signed up last week?" data_product_accelerator/skills/semantic-layer/03-genie-space-patterns and 04-genie-space-export-import-api — produces genie_space_id Call Genie via the Databricks SDK from a @function_tool, or wire as Genie MCP server (see F3)
Unity Catalog functions (deterministic Python or SQL functions, registered in UC) "Compute next-tier-distance for this customer" F3: Tools and Data Access (UC Functions MCP section) Wire as UC Functions MCP server, or call directly via the SDK
Vector Search MCP (custom retrieval pipeline) "Custom hybrid search with re-ranker" F3 (Vector Search MCP) MCPServerSse direct wiring (see below)
Local Python tools (business logic, math, formatting) "Compute margin", "format response" This skill — @function_tool (see below) Decorator

Canonical default for the SkyLoyalty walkthrough: Knowledge Assistant

  • Genie Space + a small set of @function_tool helpers. This pairing covers structured analytics (Genie), unstructured Q&A (KA), and bespoke business logic (functions) without a custom RAG stack.

Serving-endpoint API shape per endpoint kind

Different endpoint kinds use different request shapes. The most common bug in this skill's history is reaching for Chat Completions on every endpoint; KA uses Responses API and Genie uses a two-call SDK sequence. Use this table as the canonical wiring reference:

Endpoint kind Wire via Request shape Notes
Knowledge Assistant Raw requests.post to {host}/serving-endpoints/{name}/invocations Responses API: {"input": [{"role": "user", "content": "..."}]} Parse output[].content[].text. Do NOT use serving_endpoints.query(messages=...) — KA rejects messages and the SDK's typing surfaces it as 'dict' object has no attribute 'as_dict'.
Foundation Model API (Sonnet, llama-3.3, gpt-5-2) databricks_openai.AsyncDatabricksOpenAI or OpenAI(base_url=...) OpenAI Chat Completions: messages=[...] Standard OpenAI-compatible client patterns apply.
Genie Space SDK two-call sequence (1) w.genie.start_conversation_and_wait(space_id=..., content=...) returns description + attachments[] (2) w.genie.get_message_query_result_by_attachment(space_id, conversation_id, message_id, attachment_id) returns rows First call alone surfaces the SQL plan as prose, not the rows — always make both calls. See Wiring Genie as a function tool below.
AI Gateway endpoint REST POST /api/2.0/serving-endpoints external_model.databricks-model-serving shape See F4: AI Gateway for the create-endpoint payload.

Wiring KA as a function tool (Track A pattern)

KA exposes a Model Serving endpoint, but KA serves the Responses API, not Chat Completions. A serving_endpoints.query(name=..., messages=[...]) call against a KA endpoint fails with Invalid request: 'messages' field is not supported (and may surface earlier as a Python 'dict' object has no attribute 'as_dict' typing trap inside the SDK shim).

Call the invocations URL directly with the Responses-API request body:

{"input": [{"role": "user", "content": "question"}]}

and parse the response as output[].content[].text:

import os
import requests
from agents import function_tool
from databricks.sdk import WorkspaceClient

KA_ENDPOINT = os.environ["KA_ENDPOINT_NAME"]  # captured in F5

@function_tool
def search_policy_docs(query: str) -> str:
    """Search policy documents and return cited answers.

    Args:
        query: Natural-language question about loyalty program policy.
    """
    w = WorkspaceClient()
    host = w.config.host.rstrip("/")
    url = f"{host}/serving-endpoints/{KA_ENDPOINT}/invocations"

    # KA uses the Responses API: `input`, NOT Chat Completions `messages`.
    body = {"input": [{"role": "user", "content": query}]}
    resp = requests.post(
        url,
        headers={"Authorization": f"Bearer {w.config.token}",
                 "Content-Type": "application/json"},
        json=body,
        timeout=60,
    )
    resp.raise_for_status()
    payload = resp.json()

    # Responses API: payload["output"][i]["content"][j]["text"]
    parts = []
    for item in payload.get("output", []):
        for chunk in item.get("content", []):
            text = chunk.get("text")
            if text:
                parts.append(text)
    return "\n".join(parts) or "(no answer)"

DON'T use w.serving_endpoints.query(name=..., messages=[...]) against a KA endpoint. KA does not accept Chat Completions messages. Use raw requests.post with {"input": [...]} against the invocations URL as shown above. (Foundation Model API endpoints — Sonnet, llama-3.3, gpt-5-2 — do accept Chat Completions and can use the OpenAI-compatible client.)

Declare the KA endpoint as a serving_endpoint resource (CAN_QUERY) in databricks.yml so the deployed agent has access — see the resource-kind reference below.

Wiring Genie as a function tool

Genie spaces require a two-call sequence via the SDK. The first call returns the planner description and message metadata; the rows live on the attachment and must be fetched in a second call. Tools that return only the first call's output deliver SQL-as-prose to the LLM, not data.

  1. w.genie.start_conversation_and_wait(space_id=..., content=...) — starts the conversation, runs the planner, and returns a GenieMessage whose attachments[] carry the query metadata (each attachment has an attachment_id). The message's content/text is the description, not the rows.
  2. w.genie.get_message_query_result_by_attachment(space_id=..., conversation_id=..., message_id=..., attachment_id=...) — pulls the actual SQL execution result (rows + columns) for the chosen attachment.

Combine both into a single tool so the Agents SDK gets both the description and the rows in one return value:

import os
from agents import function_tool
from databricks.sdk import WorkspaceClient

GENIE_SPACE_ID = os.environ["GENIE_SPACE_ID"]  # captured during semantic-layer setup

@function_tool
def query_loyalty_analytics(question: str) -> str:
    """Answer analytics questions over loyalty data using Genie.

    Args:
        question: Natural-language analytics question (e.g. "active members by tier").
    """
    w = WorkspaceClient()

    # CALL 1: start_conversation_and_wait — planner runs, returns description.
    msg = w.genie.start_conversation_and_wait(
        space_id=GENIE_SPACE_ID,
        content=question,
    )
    description = (msg.content or "").strip()
    if not msg.attachments:
        return description or "(no answer)"

    # CALL 2: get_message_query_result_by_attachment — fetches the rows.
    attachment_id = msg.attachments[0].attachment_id
    result = w.genie.get_message_query_result_by_attachment(
        space_id=GENIE_SPACE_ID,
        conversation_id=msg.conversation_id,
        message_id=msg.message_id,
        attachment_id=attachment_id,
    )

    # Render rows as a small markdown-ish table for the LLM.
    rows_text = "(no rows)"
    sm = getattr(result, "statement_response", None)
    if sm and getattr(sm, "result", None) and getattr(sm.result, "data_array", None):
        rows = sm.result.data_array
        cols = [c.name for c in (sm.manifest.schema.columns or [])] if sm.manifest else []
        header = " | ".join(cols)
        body = "\n".join(" | ".join(str(c) for c in row) for row in rows)
        rows_text = f"{header}\n{body}" if header else body

    return f"{description}\n\n{rows_text}"

DON'T stop after start_conversation_and_wait. The first call may return only a description (and zero attachments for refusals); always fetch get_message_query_result_by_attachment for each attachment whose rows you want to surface to the LLM.

Declare a genie_space resource in databricks.yml. Bundle bindings use name + space_id (not a bare id):

- name: genie-space
  genie_space:
    space_id: ${var.genie_space_id}
    permission: CAN_RUN

The outer name: is the resource binding (referenced by valueFrom: in app.yaml); the inner space_id: is the Genie Space identifier the platform looks up. Plus declare the underlying sql_warehouse the space uses.


Local Function Tools

OpenAI Agents SDK: @function_tool

The simplest way to give your agent capabilities — define Python functions and decorate them:

from agents import Agent, function_tool
from datetime import datetime

@function_tool
def get_current_time() -> str:
    """Get the current date and time in ISO format."""
    return datetime.now().isoformat()

@function_tool
def calculate_metrics(revenue: float, cost: float) -> dict:
    """Calculate profit margin and ROI from revenue and cost.

    Args:
        revenue: Total revenue in dollars.
        cost: Total cost in dollars.
    """
    profit = revenue - cost
    margin = (profit / revenue * 100) if revenue > 0 else 0
    return {"profit": profit, "margin_pct": round(margin, 2)}

@function_tool
def search_knowledge_base(query: str, max_results: int = 5) -> list[dict]:
    """Search the internal knowledge base for relevant documents.

    Args:
        query: Natural language search query.
        max_results: Maximum number of results to return (default 5).
    """
    from databricks.sdk import WorkspaceClient
    w = WorkspaceClient()
    results = w.vector_search_indexes.query_index(
        index_name="prod.docs.knowledge_index",
        columns=["content", "source", "score"],
        query_text=query,
        num_results=max_results,
    )
    return [
        {"content": r["content"], "source": r["source"], "score": r["score"]}
        for r in results.result.data_array
    ]

agent = Agent(
    name="analyst",
    instructions="You are a data analyst. Use tools to answer questions accurately.",
    model="databricks-claude-sonnet-4-6",
    tools=[get_current_time, calculate_metrics, search_knowledge_base],
)

Tool docstrings are critical. The LLM uses them to decide when and how to call each tool. Write clear descriptions with typed arguments.


Wiring MCP Servers with DatabricksMCPClient

The databricks-mcp library (covered in F3) is the recommended way to connect to managed and external MCP servers. For the OpenAI Agents SDK, you can wire MCP tools alongside local function tools.

Using MCPServerSse (Direct Wiring)

The OpenAI Agents SDK natively supports MCP via MCPServerSse:

from agents import Agent
from agents.mcp import MCPServerSse
from databricks.sdk import WorkspaceClient

ws = WorkspaceClient()
host = ws.config.host

ai_search_mcp = MCPServerSse(
    # AI Search (formerly Vector Search); legacy /mcp/vector-search/ prefix still works
    url=f"https://{host}/api/2.0/mcp/ai-search/prod/docs/knowledge_index",
    headers={"Authorization": f"Bearer {ws.config.token}"},
)

sql_mcp = MCPServerSse(
    url=f"https://{host}/api/2.0/mcp/sql",
    headers={"Authorization": f"Bearer {ws.config.token}"},
)

github_mcp = MCPServerSse(
    url=f"https://{host}/api/2.0/mcp/external/github_connection",
    headers={"Authorization": f"Bearer {ws.config.token}"},
)

agent = Agent(
    name="analyst",
    instructions="Use tools to search documents, query data, and check code.",
    model="databricks-claude-sonnet-4-6",
    mcp_servers=[ai_search_mcp, sql_mcp, github_mcp],
)

Combining Local Tools and MCP Servers

Mix @function_tool definitions with MCP servers:

agent = Agent(
    name="analyst",
    instructions="Use tools to answer questions. Use calculate_metrics for math.",
    model="databricks-claude-sonnet-4-6",
    tools=[calculate_metrics, get_current_time],
    mcp_servers=[ai_search_mcp, sql_mcp],
)

Environment-Aware Auth for MCP

Handle auth consistently across local dev and Databricks Apps:

import os
from databricks.sdk import WorkspaceClient

def get_mcp_headers():
    w = WorkspaceClient()
    return {"Authorization": f"Bearer {w.config.token}"}

def get_workspace_host():
    return os.environ.get("DATABRICKS_HOST", "").rstrip("/")

Use get_mcp_headers() when constructing MCPServerSse. Adjust if using OBO (see A4: Authentication).


Resource Grants for Deployment

When your agent uses MCP servers or other Databricks resources, you need to declare workspace resource attachments and UC grants.

For the complete grant matrix, app.yaml/databricks.yml examples, UC SQL patterns, MLflow resources declarations, and the get_databricks_resources() auto-discovery pattern, see F3: Resource Grants.

Resource-kind quick reference

When declaring resources in databricks.yml, the kind depends on what the resource is. Use uc_securable only for UC objects that have no dedicated top-level resource type (functions, tables, schemas, volumes, models). Warehouses, serving endpoints, and UC connections have their own top-level kinds — do not wrap them in uc_securable.

Resource Bundle kind Permission Inner identifier field
SQL warehouse sql_warehouse CAN_USE id:
LLM / chat model endpoint (route from runtime_config.llm) serving_endpoint CAN_QUERY name:
Knowledge Assistant endpoint serving_endpoint CAN_QUERY name: (the KA's serving endpoint name)
Vector Search endpoint serving_endpoint CAN_QUERY name:
Genie Space genie_space CAN_RUN space_id: (NOT id: — see note below)
UC connection (external HTTP/MCP) connection USE CONNECTION name:
UC function (incl. system.ai.python_exec) uc_securable with securable_type: FUNCTION EXECUTE (via USAGE + EXECUTE grants on the securable) securable_full_name:
UC table / view uc_securable with securable_type: TABLE SELECT securable_full_name:
UC schema uc_securable with securable_type: SCHEMA USE_SCHEMA securable_full_name:
UC model uc_securable with securable_type: MODEL USE_MODEL or EXECUTE per scenario securable_full_name:
Another Databricks App (backend) app CAN_USE — see 06d-appkit-agent-app-proxy name:

genie_space resource shape: The DAB binding takes the outer name: (the resource binding label, used by valueFrom: in app.yaml) plus the inner space_id: (the Genie Space identifier). It does not accept a bare id: like sql_warehouse does. Using id: silently fails validation in some CLI versions and leaves the app unable to resolve the resource at runtime. Always use name + space_id.

Model grants are derived from docs/agent_tool_plan.yaml.runtime_config.llm.

  • When provider == "databricks", grant CAN_QUERY on runtime_config.llm.endpoint.
  • When provider == "ai_gateway", do not create or configure Gateway. Verify the pre-provisioned endpoint and required permissions are documented, then leave provisioning to the optional Gateway hardening step.

Verify the bundle schema accepts each kind your agent needs before deploying:

Client note: IDE runs this in a terminal; Genie Code runs the databricks bundle … command via runDatabricksCli. See skills/genie-code-environment.

# Generic "does this kind exist in my CLI's schema?"
databricks bundle schema \
  | jq '.definitions | keys[]' \
  | grep -i 'AppResource_'

Expected output includes AppResource_SQL_WAREHOUSE, AppResource_SERVING_ENDPOINT, AppResource_UC_SECURABLE, AppResource_CONNECTION, AppResource_GENIE_SPACE, and (for CLI >= 0.295.0) AppResource_APP. If a needed kind is missing, upgrade the CLI.

Canonical agent-app app.yaml + databricks.yml (KA + Genie + LLM)

Most Track A agents need a triad of resources: an LLM endpoint, a KA endpoint, and a Genie Space (with its underlying SQL warehouse). The canonical declaration is:

# app.yaml — Agent App
command:
  - mlflow
  - genai
  - agent-server
  - serve
  - --module
  - agent
env:
  - name: LLM_ENDPOINT
    valueFrom: llm-endpoint
  - name: KA_ENDPOINT_NAME
    valueFrom: ka-endpoint
  - name: GENIE_SPACE_ID
    valueFrom: genie-space
  - name: WAREHOUSE_ID
    valueFrom: sql-warehouse
# databricks.yml — Agent App resource block
resources:
  apps:
    ${var.agent_app_name}:
      source_code_path: ./
      resources:
        - name: llm-endpoint
          serving_endpoint:
            name: databricks-claude-sonnet-4-6
            permission: CAN_QUERY
        - name: ka-endpoint
          serving_endpoint:
            name: ${var.ka_endpoint_name}
            permission: CAN_QUERY
        - name: genie-space
          genie_space:
            space_id: ${var.genie_space_id}
            permission: CAN_RUN
        - name: sql-warehouse
          sql_warehouse:
            id: ${var.warehouse_id}
            permission: CAN_USE

This is the resource shape the SkyLoyalty walkthrough (canonical) uses. The valueFrom: <resource-name> mapping in app.yaml resolves to the resource's URL or id at runtime — your agent reads os.environ["KA_ENDPOINT_NAME"] etc. without hardcoding workspace identifiers.


Custom Retriever Schemas

If your agent includes a custom retriever (not using AI Bridge tools like VectorSearchRetrieverTool), you must declare the retriever's output schema for AI Playground source links and evaluation judges.

For the complete pattern, see F3: Custom Retriever Schemas.

SDLC connection: The retriever schema declared here feeds directly into the SDLC evaluation pipeline. S4: Evaluation Runs uses doc_uri to run groundedness and relevance judges against your eval dataset's expected_retrieved_context.


Testing Tools Locally

Interactive test

uv run start-app
# Then in browser at http://localhost:8000:
# "What time is it?" -> should invoke get_current_time
# "Calculate margin for $1M revenue and $600K cost" -> should invoke calculate_metrics

Programmatic test

import asyncio
from agents import Runner

async def test_tools():
    result = await Runner.run(agent, "What time is it?")
    print(f"Output: {result.final_output}")
    print(f"Tools called: {[s.name for s in result.raw_responses]}")

asyncio.run(test_tools())

Verify in MLflow traces

After calling the agent, check MLflow traces for TOOL spans alongside AGENT and LLM spans. Each tool call should appear as a distinct span with:

  • Input: the tool arguments
  • Output: the tool return value
  • Span type: TOOL

DO / DON'T

DO — Write detailed tool docstrings with typed args

@function_tool
def search_products(
    query: str,
    category: str = "all",
    max_results: int = 10,
) -> list[dict]:
    """Search the product catalog by keyword.

    Args:
        query: Natural language search query for products.
        category: Filter by product category. Use "all" for no filter.
        max_results: Maximum number of products to return.
    """
    ...

DON'T — Use vague docstrings or skip type hints

@function_tool
def search(q, n=10):
    """Search for stuff."""  # LLM won't know what or how to search
    ...

DO — Handle tool errors gracefully

@function_tool
def query_database(sql: str) -> str:
    """Execute a SQL query against the analytics warehouse."""
    try:
        result = execute_sql(sql)
        return format_results(result)
    except Exception as e:
        return f"Query failed: {str(e)}. Please try a simpler query."

DON'T — Let tools raise unhandled exceptions

@function_tool
def query_database(sql: str) -> str:
    """Execute a SQL query."""
    return execute_sql(sql)  # Exception crashes the agent loop

Common Issues

Issue Fix
Tool not called by agent Improve the tool's docstring — the LLM needs clear description of when to use it
MCPServerSse connection refused Check MCP URL format and auth headers; verify the endpoint exists
PermissionDenied on Vector Search Grant SP access — see F3: Resource Grants
Tool returns but agent ignores result Check that the tool return type is str or simple dict — complex objects may confuse the LLM
MCP tools not appearing Verify the MCP server URL is correct and the server is running
ModuleNotFoundError in tool Move imports inside the tool function for serialization safety

Validation Gate

All must pass before proceeding:

  • At least one local @function_tool added and callable by the agent
  • Agent correctly invokes the tool when prompted (visible in chat and traces)
  • MCP connection configured for at least one Databricks service (if applicable)
  • Resource grants identified for all tools that need workspace resources
  • Tool calls appear as TOOL spans in MLflow traces
  • Tool errors are handled gracefully (no unhandled exceptions)
  • If using custom retrievers: mlflow.models.set_retriever_schema() called at module level
  • KA tool uses Responses API — request body is {"input": [...]} against /serving-endpoints/{name}/invocations, NOT serving_endpoints.query(messages=[...])
  • Genie tool issues both callsstart_conversation_and_wait followed by get_message_query_result_by_attachment for each attachment whose rows are returned to the LLM
  • databricks.yml genie_space resource uses name + space_id (not bare id:)

Next Step

After passing this gate, load and execute tracks/A-custom-agent-apps/04-authentication/SKILL.md (A4: Authentication).

Notes to Carry Forward

Key Value
local_tools List of @function_tool function names
mcp_servers List of MCP server URLs configured
app_yaml_resources Resources declared in app.yaml
uc_grants_needed UC GRANT statements for deployment

Related Skills

Skill Relationship
F3: Tools and Data Access Foundation — MCP servers, grants, retrievers
F5: Knowledge Assistant Lifecycle Tool catalog — managed doc Q&A; produces ka_endpoint_name
Genie Space Patterns Tool catalog — NL → SQL on UC tables; produces genie_space_id
Genie Space Export/Import API Tool catalog — versioning Genie spaces across environments
A2: Agent Framework Previous step — produces agent_class
A4: Authentication Next step
S4: Evaluation Runs Custom retriever schemas enable groundedness/relevance judges

References

Version History

Version Date Changes
3.1.0 2026-04-26 Document tool/data-product API shapes (Phase 3.8): KA serving uses Responses API ({"input": [...]}) not Chat Completions messages; Genie requires the two-call sequence (start_conversation_and_wait returns description, get_message_query_result_by_attachment returns rows); DAB genie_space resource uses name + space_id, not bare id. Added serving-endpoint-API-shape table covering KA / FMAPI / Genie / AI Gateway.
3.0.0 2026-04-12 Refactored: MCP concepts, resource grants, retriever schemas moved to F3. Focus on Agent SDK wiring with DatabricksMCPClient and MCPServerSse.
2.0.0 2026-04-10 Progressive disclosure: MCP config and resource grants in references/
1.0.0 2026-04-10 Initial skill: function tools, MCP servers, resource grants, testing patterns
Install via CLI
npx skills add https://github.com/databricks-solutions/vibe-coding-workshop-template --skill 03-tools-and-mcp
Repository Details
star Stars 4
call_split Forks 4
navigation Branch main
article Path SKILL.md
More from Creator
databricks-solutions
databricks-solutions Explore all skills →