# Local MCP server > Connect Claude Code, Claude Desktop, Codex, Gemini CLI, Cursor or VS Code to Querylab.io. Your AI tool can explore BigQuery schemas, check SQL, estimate costs and run queries through the desktop app, within limits you set. Source: https://docs.querylab.io/desktop-app/local-mcp-server/ Querylab.io Desktop provides a local MCP (Model Context Protocol) server. A connected AI tool uses your Querylab.io session to work with BigQuery. The project it bills, its cost limits and the approval of writes are handled in the app. ## Connect an AI tool 1. Open the [desktop app](https://docs.querylab.io/desktop-app) and connect to your BigQuery project. 2. Open **Settings → MCP**. 3. Find your AI tool and click **Install**. The first installation turns on **AI tools can connect** automatically. 4. Complete any installation prompt in the AI tool. | AI tool | Setup | | -------------- | --------------------------------------------------------------------- | | Claude Code | Install the CLI first, then click **Install** in Querylab.io. | | Claude Desktop | Quit Claude Desktop before installing the connection, then reopen it. | | Codex | Install the CLI first, then click **Install** in Querylab.io. | | Gemini CLI | Install Gemini CLI, then click **Install** in Querylab.io. | | Cursor | Click **Install** and finish the connection setup in Cursor. | | VS Code | Click **Install** and finish the connection setup in VS Code. | For Claude Code, Codex and Gemini CLI, installation can include **MCP + skills**: the connection plus instructions that help the AI use Querylab.io's BigQuery tools. The status shows which form is installed. If plugin installation fails, **Install MCP only** lets you install just the connection; an existing MCP-only installation can be upgraded later. ## Try it In your connected AI tool, ask: > Use Querylab.io to find the tables in my project and show me their columns. Don't run a query yet. Then try a query workflow: > Write a SELECT query for this table, validate it and estimate its cost before running it. The tools can search schemas, sample tables, validate SQL, estimate query costs, explain routing, suggest optimizations, look up BigQuery documentation and run queries. Supply SQL directly from your conversation or project files. Available data and query execution depend on the project and permissions in your Querylab.io session. ## Tools | Tool | Purpose | | ------------------------ | ------------------------------------------------------------------------------------------- | | `search_schema` | Browse projects, datasets, tables, columns and property graphs. Also searches descriptions. | | `sample_table` | Read sample rows and column profiles without query cost. | | `validate_sql` | Check SQL and return errors, warnings and hints. | | `estimate_cost` | Estimate query cost, recommend a route and check budgets. | | `get_routing` | Show where a query would run and why, without running it. | | `get_optimization_tips` | Find opportunities to reduce query costs. | | `get_bq_docs` | Look up BigQuery SQL documentation, including forecasting and contribution analysis. | | `execute_query` | Run a query and return rows, or write them to a file. | | `get_job_result` | Wait for a query that was still running and return its result. | | `cancel_job` | Ask BigQuery to stop a running query. | | `get_limits` | Report every limit the AI tool runs under, with today's usage and budget. | | `request_limit_increase` | Ask you to allow one call above one of those limits. | | `get_approval_result` | Wait again for an answer you owe a call: an approval, a lifted limit, or sharing rows. | ### Searching descriptions A table search also matches table and column descriptions. A search for `revenue after refunds` finds a table whose description says so, even if no table name contains those words. Each result says whether the name or a description matched, and shows the matching text. Descriptions are searched only for tables whose details Querylab.io has already saved, for example tables you or the AI tool have opened. Nothing is fetched for the search, because an account can hold thousands of tables. The result lists how many tables were not searched and in which datasets, so the AI tool knows a missing match is not proof. Asking for the columns of a table saves its details, and the next search covers it. ## Approvals and the MCP tab Reads run as soon as the AI tool asks: schema searches, samples, checks, cost estimates and SELECT queries. Your AI tool's own permission prompt is where you approve those. The limits below still apply. Writes wait for you by default. When write access is on and an AI tool sends INSERT, UPDATE, DELETE, MERGE or a schema change, Querylab.io shows a card with the SQL, the kind of change, the table and the project it runs in. Choose **Run**, **Reject**, or **Open in a new tab** to run it yourself. With no answer, the request is rejected after about ten minutes. You do not have to answer quickly. The AI tool's own call ends after about 25 seconds with a request id instead of a result, and the tool comes back for the answer with `get_approval_result` — every AI tool gives up on a call of its own after a minute or so, so a card held open longer than that used to leave it with a dead call. Nothing runs until you choose, and a card you answer minutes later still reaches the tool that asked. The card looks and behaves the same either way. ### Taking the statement over **Open in a new tab** answers neither Run nor Reject: it hands the statement to a query tab you drive. The tab opens with the route the AI tool asked for, nothing runs until you run it, and the AI tool is told its call did not run and that you took it over. The log records the decision as _You opened it in a new tab_. It is on the write card and on the limit card below. ### How you know something is waiting A call that waits comes back to the AI tool with a link that opens the request in Querylab.io. The link only opens it. The decision stays in the app, where the statement, the table it changes and the bytes it bills are on screen. Outside the window: - The **MCP** button in the header shows how many requests wait. - The tray icon, which is the menu bar item on macOS, lists them. **Show in Querylab.io** opens one and **Reject** says no to it. **Approve** is offered only for a question about sharing rows, because its line says everything the answer needs: how many rows, and whether they go to the AI tool or to a file. A write and a lifted limit are answered on their card. - **Settings → Notifications → MCP approvals** sends a system notification. It is on by default. ### Running one call above a limit An AI tool that is stopped by a limit can ask you to lift it for that one call. Every refusal for a cost cap, the daily limit, write access, a dataset rule or the project and routing settings tells it so. When it asks, a card appears under **Waiting for you** with the AI tool's own reason, the statement, and a line for each limit it would lift: the GB it wants to bill against your cap, how much of today's limit is left, the rows it wants over your row limit, the statement it wants to run, the dataset it wants to read or change, or a connection or AI function (named on the card) that can bill beyond your GB limits. Choose **Allow once**, **Don't run it**, or **Open in a new tab** to run the statement yourself. **Allow once** runs that one call with exactly those limits lifted and nothing else. Here too the AI tool may have stopped waiting on its first call and come back for the answer; what you choose is what it gets. A write runs without a second Run or Reject card only when one of the lines on the card named that write, with the statement and the table it changes. Nothing is saved: the next call is held to your saved limits again, and a restart clears anything in flight. With no answer the request is rejected on the same ten-minute clock as a write. A dataset you set to **No access** can only be asked for when the AI tool's own SQL names it. Anything else it runs into in such a dataset, a table behind a view for instance, is refused without being named, so the rule never tells an AI tool what is in there. The row limit can be lifted to 10,000 rows at most, however many the AI tool asks for. After **Don't run it** the same request is refused if the AI tool asks again, even reworded, and at most three requests can wait at once. An AI tool cannot ask for a statement Querylab.io never runs for AI tools, for a dataset list it could not read, or for your **Share query results** setting. Those stay in **Settings → MCP**. The **Write approval** setting changes which writes wait. With **Ask for schema changes only**, INSERT, UPDATE, DELETE and MERGE run as soon as the AI tool sends them, and CREATE, ALTER, DROP and TRUNCATE still wait. With **Don't ask**, no write waits. The log marks a write that ran this way as _Ran without approval (setting)_. ### The MCP activity tab The cards are at the top of this tab, under **Waiting for you**. Click the **MCP** button in the header to open it. Below them the tab is, from the top: - **MCP is on** and the port. Clicking the status turns the server off and back on. **Other settings and limits** opens Settings → MCP. - **Running now**, while a call is working. - the summary strip: four or five limits over four totals. - one panel with a **Log** tab and an **Activity** tab. The time range (today, 7, 30 or 90 days) and the filters for client, tool and status sit beside those tabs and govern both, so the chart draws the calls the log lists. The totals in the strip are the whole range, filters or no filters. **The summary strip.** The top row is what AI tools are allowed to do right now, whoever set it. Each reading is also where that limit is changed: click one and its editor opens over it, with the explanation under the field. | Cell | What it states | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Daily limit** | The most BigQuery may bill for AI tools in one day, with a meter of what they have used, jobs still running included. With no limit of their own it falls back to your own daily budget, which every query counts toward and which no AI tool can ask you to lift. | | **Per query** | The most one AI tool query may bill. Without one of its own it follows your single query limit. | | **Slot limit** | The most slot time one AI tool query may use, shown only when AI tools could be billed in slot time. Without one of its own it follows your default slot limit. Querylab.io cancels a query that passes it, so it is approximate, and the slot time the query used is still billed. | | **Rows** | The most rows an AI tool is given back from one query. | | **Writes** | Whether AI tools may change data, schema or nothing, and which of those changes wait for your answer. | The bottom row is what the chosen range did: **Queries run**, **Data billed** (what BigQuery charged for, with a count of finished queries that report no billed figure), **Cost**, and **Blocked or failed** (with how many of those Querylab.io's own limits turned away). **The Log tab** lists every call with its time, client, tool, status, route, data, cost, rows and duration. Click a call to see the rest beside the log: the full SQL, the parameters the AI tool sent, the job, the approval decision and the error. **Open SQL in a new tab** copies the query into the editor, and **Open job** shows the BigQuery job. The log opens filtered to `execute_query`, `request_limit_increase` and `get_approval_result`, the calls that spend money or wait for you. Clear the tool filter to see every call. The **Activity** tab charts calls, data billed or cost per day, stacked by AI tool. The log keeps 90 days on this computer. **Settings → MCP → Activity history → Clear history** deletes it for all accounts, and leaves today's usage and the daily limit as they are. ## Where AI tools run their queries AI tools never use the project, limit or routing of the query tab you have open. They use the settings in **Settings → MCP**: | Setting | Default | What it does | | --------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Billing project** | Your default billing project | The project AI tool queries run and are billed in. If it is no longer one of your billing projects, AI tool calls fail until you choose another one. | | **Let AI tools choose another project** | Off | Lets the AI tool pass a `project` to `execute_query` and `estimate_cost`. Only your own billing projects are accepted. When off, a call that passes one fails. | | **Maximum GB per query** | Your single query limit | A query that would bill more than this fails. | | **Slot limit per query** | Your default slot limit | Querylab.io cancels an AI tool query that passes this many slot-hours. Shown only when AI tools could be billed in slot time. It is approximate: slot use is reported about every 30 seconds, so a query can pass the limit before it is stopped, and the slot time it used is billed. | | **Routing** | Same as new query tabs | The project default, Auto, on-demand or a reservation. | | **Let AI tools choose routing** | Off | Lets the AI tool pass `routing` to `execute_query`, `estimate_cost` and `get_routing`. When off, a call that passes it fails. | | **Daily limit for AI tools** | No limit | A query is refused when it would take today's total above this amount. The day ends at midnight on this computer. With none set, your own daily budget is what stops them. | | **Allow AI functions and connections** | Off | Lets AI tools run queries that use a connection or an AI function. See [AI functions and connections](#ai-functions-and-connections). | The daily limit counts what each query is estimated to scan when it starts, and replaces the estimate with the billed amount when the query ends. Queries that run at the same time, or that are still running, count too. Settings shows how much was used today and how much of it is held for queries still running. If the saved count cannot be read, AI tool queries are refused until you click **Start today's count from zero**. `estimate_cost` tells the AI tool whether a query fits within these limits before it runs, and `get_limits` reports the limits themselves with today's numbers, so the AI tool can plan a query instead of finding out by being refused. ## Limits and access These settings are in **Settings → MCP**. They apply to connected AI tools only. Prism AI inside the app keeps its own behavior. They are saved on this device and stay after you sign out. - AI tools can connect (selected): Lets an AI tool you install below reach Querylab.io. On by default. - Start Querylab.io when an AI tool uses it (selected): If Querylab.io is closed when an AI tool needs it, it starts by itself. You may still need to sign in. - Max rows returned to AI tools: 1,000 - Max rows written to a file: 100,000