Skip to content
abhinavbhatia
Sheet 02 / 05 — Blogs← Archive

Let people ask your lakehouse questions: wiring Gemini Enterprise to Databricks Genie

Your data already sits in a modelled, governed lakehouse, but the business user with the question still cannot reach it. This post explains, step by step, four ways to connect Gemini Enterprise to Databricks Genie so that every answer runs as the user who asked.

Most companies have already done the hard groundwork. Their data is in a lakehouse (one platform that holds both raw files and modelled, query-ready tables), and it is modelled and governed. Yet the person who actually has the question still cannot reach it. Think of a brand manager trying to understand why a product missed its target last month. They message an analyst, describe what they need, wait a day or two, and get back a chart that answers a slightly different question from the one they asked.

The two pieces that close this gap usually exist inside the company already. Databricks Genie turns a question written in plain English into SQL and runs it against governed tables. Gemini Enterprise is the assistant many employees keep open all day. So the real question is how to connect them: how can a user type a question into Gemini Enterprise and have Genie answer it as that user, without copying data or keeping a second set of permissions?

I built this end to end for a fictional consumer goods company, and this post is the guide I wish I had had at the start. It covers four ways to connect the two, what governance really gives you in this design, and the specific problems that each cost me an afternoon.

Who is asking, and about what?

The demo company is Abhinav Consumer Brands (ACB), a fictional CPG (consumer packaged goods) business, so none of the data belongs to a real organisation. I will use ACB as the example all the way through. It sells through retailers, so its questions fall into three areas:

  • Brand and market: how well products sell. Two measures matter here. Sell-in is the volume ACB ships to retailers, and sell-out is the volume shoppers actually buy. The difference between them is stock sitting in the channel. Each product also has a plan, which is its target for the period, so “sell-out vs plan” tells you how close a product came to its target.
  • Trade and revenue: money spent on promotions. A promotion is a temporary price cut or offer, and trade spend is the amount paid to retailers to run it. Promo ROI (return on investment) tells you whether a promotion brought in more than it cost. A negative ROI means it lost money.
  • Supply and service: whether orders arrive correctly. The headline measure is OTIF (on time in full), the share of orders delivered both on time and complete.

You don’t need a retail background to follow the architecture. These terms matter because business users ask for them in exactly these words, and Genie has to understand them correctly. Teaching Genie that “promotions that lost money” means a particular column and filter is the heart of what you are setting up.

How do the two talk to each other?

Gemini Enterprise asks, Databricks answers, and MCP is the agreed format for the question and the reply.

Think of a waiter and a kitchen that have agreed on one order slip. The waiter does not need to know how the kitchen cooks; the kitchen does not need to know which table is asking. As long as the order goes in on the agreed slip, any trained waiter can order from any kitchen that reads it. The waiter is the MCP client, the kitchen is the MCP server, and the slip is the Model Context Protocol. For ACB, the waiter is Gemini Enterprise and the kitchen is the Genie Agent behind a Databricks managed MCP server.

Gemini Enterprise can call outside tools through the Model Context Protocol (MCP), an open standard for connecting an AI assistant to tools and data. Databricks now hosts managed MCP servers (MCP endpoints that Databricks runs for you) in front of Genie, Unity Catalog functions and AI Search (formerly Vector Search). So the simplest picture is this: Gemini Enterprise is the MCP client, Databricks provides the MCP servers, and a question travels from one to the other.

One update since I first wrote this (checked 8 November 2026). Databricks renamed Genie spaces to Genie Agents, and its Databricks-provided MCPs page now describes two kinds of server. The per-resource endpoints this post uses, such as one Genie Agent’s endpoint, “are in Public Preview”, need a workspace administrator to enable Managed MCP Servers on the Previews page, and “bypass Unity Gateway”, so they rely on the permissions of the Genie Agent and its data. The Genie One MCP server (system.ai.genie_one_mcp) “is generally available”, is governed by Unity Gateway grants and policies as well as the underlying permissions, and answers questions across the workspace rather than one curated agent. For new integrations Databricks recommends the system.ai MCPs when they support the use case. For ACB that means a quick test: if Genie One answers “promotions that lost money” from the same metric views, it is the simpler endpoint to register; if the brand team needs one curated agent with its own instructions and examples, the per-agent endpoint is still the right one.

There is also a richer option. MCP-Apps lets a tool send back an interactive screen that appears inside the Gemini Enterprise chat: a small dashboard with charts, a “Show SQL” toggle and action buttons. If you only need questions and answers, you don’t need it. If you want the experience to feel like a product rather than a chat reply, you build a small server that speaks MCP-Apps to Gemini Enterprise and MCP to Databricks.

That server sits at the centre of the design, so the next sections explain what it does and whether you need it at all.

Whose permissions does the query use?

The question runs as the person who asked it, never as a shared account, so the chat can see exactly what that person could already see.

Picture sending a colleague to the library with your own library card. The librarian lends them only what your card allows: if your card does not cover the rare books room, your colleague comes back without the rare book, however politely they ask. Lending them a master card that opens every room would be quicker, and it is exactly the mistake to avoid. Your colleague is the assistant, your card is your access token, the librarian is Unity Catalog, and the master card is a shared service account.

Everything else depends on one rule: when a user asks a question, the query must run in Databricks as that user, not as a shared service account (a non-human identity used by software). Gemini Enterprise does this with an OAuth on-behalf-of (OBO) flow, which means the assistant acts on the user’s behalf with the user’s own permissions. The user gives consent once, and their access token (the short-lived credential that proves who they are) is passed along on every call that follows. Databricks runs the query as that person, and Unity Catalog, the Databricks governance layer, applies the same permissions it would anywhere else.

How does this apply to ACB? A supply planner and a brand manager can type exactly the same question and get different answers, because the planner was never given access to revenue data: the planner’s card does not cover that room. Nobody wrote a special access rule for the chat. The same grant that controls a notebook or a dashboard controls the chat too. No data is copied, and there is no second access model to keep in step. If you have ever watched a self-service analytics project turn into a governance problem, this is the main reason to like this design.

What are the four ways to connect them?

The four options trade code you maintain for control you get, and the fourth changes what Gemini Enterprise sees at the front door: an agent instead of a tool.

All four use the same data and the same demo. The first three differ in how much you build yourself. The fourth keeps the same Databricks back end but changes the protocol at the front door. I go from most control to least infrastructure, and then cover the standards-based option.

Option 1: a Cloud Run gateway calling the Databricks REST APIs

You deploy a small service on Cloud Run, which I will call the gateway. To Gemini Enterprise, it is an MCP-Apps server that draws the dashboard and offers the actions: ask a question, forecast demand, run a job. To Databricks, it is a client of the REST APIs: the Genie Agents API (formerly the Genie Conversation API) for questions, the Statement Execution API for functions, and the Jobs API for anything that writes data.

Choose this when you want the most control over the experience. You own the routing, the guardrails, the charts and the monitoring. The cost is more code to maintain, including the connection to each Databricks API and its own quirks.

Option 2: a Cloud Run gateway calling managed MCP

The gateway and dashboard stay the same, but instead of the REST APIs the gateway calls the Databricks managed MCP servers for Genie, functions and search. Databricks looks after the conversation loop, the retries and the response format. The gateway passes on the user’s token and draws the result. Jobs are the exception: there is no managed MCP server for Databricks Jobs yet, so running a job still uses the REST API.

My view: this is where most teams should start. You keep the full product experience of Option 1 (the dashboard, the actions, one connector for Gemini Enterprise and your own monitoring) while writing and maintaining less integration code, because the managed servers handle the Genie-specific logic. Where a capability has no managed MCP server yet, that one action falls back to REST and everything else stays on MCP.

Option 3: register managed MCP directly, with no gateway

This option removes the gateway. Each Databricks managed MCP endpoint is registered in Gemini Enterprise as its own data store (a source the assistant can call): one per Genie Agent, plus optional stores for functions and search. Gemini Enterprise calls them directly and picks between them based on each store’s name and description.

You can set it up in about an hour, and there is no code to maintain. In return, you lose everything the gateway gave you: the interactive dashboard, running jobs, multi-step workflows and your own monitoring. You also register several connectors instead of one, and Gemini Enterprise has to do the polling itself, which can slow things down (I explain why below). Choose this when governed questions and answers are all you need and you would rather not run any infrastructure.

Option 4: A2A and A2UI, the standards-native front door

Options 1 to 3 all register the gateway (or the raw endpoints) as a Custom MCP data store. Option 4 registers it as an A2A agent instead. Gemini Enterprise finds it through an Agent Card (a small description of what the agent can do) and calls it over Agent2Agent (A2A), using JSON-RPC with server-sent events, just as it would call any other agent. Instead of sending back an HTML dashboard, the agent replies with A2UI: a compact description of the screen’s components, which Gemini Enterprise draws natively in its own style. The back end does not change. It still calls Databricks over managed MCP, on behalf of the user, exactly as in Option 2.

The reason to choose this option is that A2A and A2UI are the open agent standards that both Google and Databricks are building on, so your front door is not tied to the MCP-Apps way of drawing screens. The demo shows how it feels. “How did the brand sell out versus plan by region” returns a bar chart with the table and SQL underneath. A follow-up such as “break that down by retailer” carries on in the same Genie conversation. “Run the monthly brand review” shows a confirmation button that starts the Databricks job when you press it.

One honest gap: A2A and A2UI registration in Gemini Enterprise is still in Preview, so you pin the versions (A2A v0.3, A2UI v0.8) and should expect some rough edges. The surface needs a fresh ID for each answer, the OBO token arrives in a specific header, and jobs need a confirmation step that you build yourself.

Is A2A a replacement for MCP?

It is easy to read Option 4 as swapping MCP for A2A, but that is not right, and getting it right changes how you decide. MCP connects an agent to its tools; A2A connects an agent to other agents. Option 4 uses both.

A head chef makes the point in a kitchen. To cook, the chef uses the oven, the mixer and the fridge: tools that do one job when asked. To cater a wedding, the chef phones a pastry chef at another restaurant, agrees who makes the cake, and gets back a finished cake, not a list of oven settings. The oven is a tool reached over MCP; the pastry chef is a peer agent reached over A2A, who uses their own tools to do the job.

The two protocols solve different problems. MCP is an agent-to-tool protocol: it defines how an agent connects to its tools, data and APIs. You can picture this as the vertical connection. A2A is an agent-to-agent protocol: it defines how separate agents find each other, hand off work and share results. That is the horizontal connection. A2UI sits alongside A2A as the agent-to-UI layer, defining how an agent shows an interactive screen to the user. Google introduced A2A to complement MCP, not to replace it, and in practice the two are used together.

How does this apply to ACB? Option 4 actually uses both, each where it belongs. Gemini Enterprise talks to the ACB agent over A2A because that is one agent talking to another. The agent then talks to Databricks over managed MCP because that is an agent calling a tool. So the real difference is what Gemini Enterprise sees at the front door. In Options 1 to 3, it sees a tool (a Custom MCP data store), and its own model does the orchestration. In Option 4, it sees a peer agent (through an Agent Card) that does its own reasoning and returns a finished, drawn result. The Databricks back end is the same in both cases.

That makes the choice clearer. Use MCP at the front door (Options 1 to 3) when you want to offer governed questions, answers and actions as capabilities for the Gemini Enterprise assistant to orchestrate. It is the simpler and more mature path today, and the MCP-Apps dashboard is a convincing product surface. Use A2A with A2UI (Option 4) when your service should be a full agent in the Gemini Enterprise agent ecosystem: discoverable through an Agent Card, able to work with other agents, responsible for its own multi-step reasoning, and drawing its screens through the open standard rather than MCP-Apps. If you are heading towards a setup where several agents work together, A2A is the right interface. If you need one governed connector in production this quarter, MCP gets you there faster.

To sum up: Option 2 for a production-quality product with less code to maintain, Option 3 for the fastest path, Option 1 when you need something the managed servers do not cover yet, and Option 4 when your connector should be a standards-based agent rather than a tool, built on A2A and A2UI instead of MCP-Apps. This is a decision about the front door only. It does not move you away from MCP, because every option still reaches Databricks over MCP or REST.

As a test, ask these in order, least infrastructure first, and stop at the first yes:

1. Governed questions and answers are all you need?          -> Option 3, no gateway
2. You need the dashboard, actions or your own monitoring?   -> Option 2, gateway on managed MCP
3. You need something the managed servers do not cover yet?  -> Option 1, gateway on REST
4. Your service should be an agent among other agents?       -> Option 4, A2A and A2UI

Why define each metric only once?

One decision pays off whichever option you choose: define your headline metrics as Unity Catalog metric views (governed, reusable definitions of a business measure) and point Genie at those rather than at raw tables. A ratio written once and computed from summed parts gives the same answer at every grouping; a ratio worked out afresh each time does not.

Small numbers show why. Two shops have a plan of 100 and 200 units, and sell 90 and 300. Shop one is 10% under plan and shop two is 50% over. Ask “how did we do against plan overall?” and there are two tempting answers:

Average the two percentages:  (-10% + 50%) / 2                                 = +20%
Ratio of the sums:            ((90 + 300) - (100 + 200)) / (100 + 200) x 100   = +30%

Only the second is right for the business, because shop two carries twice the plan. Two people, or one model on two different days, can reach for different formulas and both sound confident.

How does this apply to ACB? A metric view defines “sell-out vs plan” or “promo ROI” once, as a governed object. Genie queries it with a MEASURE() call, and the value comes out the same whether the user groups by region, retailer or week. The alternative is to let Genie work out the ratio from base tables every time. That holds up until two users get slightly different ROI figures for the same promotion and nobody can say which is right. One shared definition prevents that. It also gives Genie a smaller, cleaner target to understand, which makes the SQL it writes both faster and more consistent.

Here is the brand metric view from the demo, shortened to the parts that matter. The measure is worked out from summed parts at query time, the ratio of the sums above, so it stays correct at any grouping:

CREATE OR REPLACE VIEW acb_managed.analytics.brand_metrics WITH METRICS LANGUAGE YAML AS $$
version: 1.1
source: acb_managed.analytics.brand_performance
fields:
  - name: region
    expr: region
    synonyms: ["market region", "geography"]
measures:
  - name: vs_plan_pct
    expr: (SUM(units_soldout) - SUM(plan_units)) / NULLIF(SUM(plan_units), 0) * 100
    display_name: "Sell-out vs plan %"
    synonyms: ["vs plan", "plan attainment", "sell-out vs plan"]
$$;

-- Genie, a dashboard or a person queries it the same way:
SELECT region, MEASURE(vs_plan_pct) AS vs_plan FROM acb_managed.analytics.brand_metrics GROUP BY region;

The Databricks documentation on metric view syntax explains every field.

In practice, I set up each Genie Agent with its metric view as a source and left out the raw fact table, so the model could not go around the definition.

How do you monitor it without reading people’s questions?

With a gateway (Options 1 or 2), you need to see how the system behaves in production without administrators reading users’ questions and answers. Keep the health numbers open to the operations team and lock the content away, in two separate tiers.

A hospital already works this way. Waiting times, bed counts and how many patients came through A&E are on a board in the corridor for any manager to see. The clinical notes sit in a records system that only a few people can open, and even then names are only there when they must be. The corridor board is the open telemetry tier, the records system is the restricted tier, and removing names is what Cloud DLP does.

How does this apply to ACB? Seeing how the system behaves and not reading what people ask pull against each other, so the design splits telemetry (the logs, metrics and traces a system emits) into two tiers.

The open tier holds metrics only and contains no content by design. Every tool call writes a structured log entry with the tool name, whether it succeeded, how long it took and how the user signed in, and never the arguments. These logs feed log-based metrics and a Cloud Monitoring dashboard with p50, p95 and p99 latency (the response times that half, 95% and 99% of requests stay under) and an alert on the success rate. Traces go to Cloud Trace, so you can break a single request into its steps and see the hop into Databricks. This tier answers “is it healthy?” and “where did it fail?” for anyone on the operations team.

The restricted tier holds the question itself, the SQL that was generated and a short summary of the answer. That is the data you need to debug a wrong answer, and exactly the data that must not leak. Before any of it is stored, Cloud DLP (data loss prevention) removes names, email addresses and postal addresses. This content is only visible in an admin view protected by a token and in the trace span, never in the general logs, and the result rows are never stored. An administrator can see that a query was slow and what kind of question caused it without seeing a customer’s name.

Both tiers are native to Google Cloud. The design plugs into Cloud Logging, Cloud Trace and Cloud Monitoring, so you don’t need a separate monitoring stack.

What can go wrong

None of this was hard in the way I expected. The trouble was concentrated in a few specific places, and they are worth knowing before you meet them.

Genie answers in the background, so you have to poll. Genie is asynchronous: the managed Genie MCP server does not answer in a single call. The first call submits the question and returns a “still processing” status with a conversation ID. You then call a second tool repeatedly (polling) until the query finishes. In a gateway, your code polls in a tight loop and the response is quick. If Genie is registered directly in Gemini Enterprise (Option 3), the Gemini model has to recognise the “still processing” reply and decide to poll. If it resubmits the question instead, each attempt starts a new query and the wait grows sharply. Telling that data store explicitly to poll rather than resubmit fixed the problem.

The first question waits for the warehouse to start. A Genie answer runs SQL on a SQL warehouse (the compute that runs the queries). If the warehouse has stopped automatically after a quiet period, the next question waits around thirty seconds for it to start, on top of the time Genie spends writing the SQL. This cold start is the biggest single factor in how fast the system feels. Before a demo, run a warm-up query, or point the Genie Agent at a serverless warehouse that starts instantly.

You can use PKCE or a client secret, not both. When you register the Databricks OAuth app in Gemini Enterprise, a confidential client (an app that can keep a secret safe on a server) proves who it is with its secret, so PKCE (Proof Key for Code Exchange, a protection designed for apps that cannot keep a secret) must be turned off. If PKCE is on, the secret field disappears and sign-in fails with an unhelpful “failed to obtain refresh token” error. This cost me time and is easy to avoid.

A separate workspace does not keep data apart. Unity Catalog metastores (the top-level containers for catalogs and their permissions) are shared per region. So two builds of the same demo in two workspaces in the same region share a metastore and can read and overwrite each other’s tables. What keeps builds apart is a separate catalog, not a separate workspace. Once each version had its own catalog, they lived side by side without trouble.

What does the user actually see?

Picture an ACB brand manager. They type “how did our refill product sell out versus plan by region last month” into the assistant they already have open. Within seconds they have the figures, a chart and, if they want it, the exact SQL that produced them. They ask a follow-up. They never write SQL, never sign in to Databricks, never raise a ticket, and never see a row they are not allowed to see.

For the business user, the answer comes to them instead of being requested through someone else. For the data platform team, the quieter benefit is that governance does not change. The grants that protect a notebook now protect a chat message, and analysts who had been acting as a query desk can get back to analysis.

Try it

My view: start with Option 2. Put a small gateway on Cloud Run in front of the Databricks managed MCP servers, define your metrics once as metric views, and put a serverless warehouse behind the Genie Agents. That combination gives you the product experience with the least code to own, and it falls back to REST for the one or two actions the managed servers do not cover yet. Before you build, test whether the generally available Genie One MCP server covers your questions, since the per-agent endpoints are still in Public Preview.

What did we learn?

  • Every question must run in Databricks as the user who asked, through the OAuth on-behalf-of flow, so the grants that protect a notebook also protect a chat message.
  • There are four ways to connect Gemini Enterprise to Genie: a Cloud Run gateway on the REST APIs, a gateway on managed MCP, managed MCP registered directly, and an A2A agent that answers with A2UI.
  • A2A does not replace MCP: A2A is how Gemini Enterprise talks to a peer agent, and MCP is how that agent reaches its tools.
  • Defining each headline measure once, as a Unity Catalog metric view, keeps every answer consistent at any grouping.
  • Monitoring splits into an open tier with metrics only and a restricted tier with redacted content, so you can debug without reading people’s questions in the general logs.
  • The real problems were specific: polling an asynchronous Genie, warehouse cold starts, PKCE versus a client secret, and catalogs (not workspaces) keeping builds apart.

What comes next?

The idea at the centre of this post, an agent that queries Databricks as the signed-in user, is built step by step in Production-ready agents, Part 7: Identity. If you are new to running Databricks on Google Cloud itself, the Databricks on Google Cloud series starts from the basics.

Sources

View original.