Search⌘KHide sidebarOpen menu
Switch to dark mode
Copy page content as Markdown⌘⌥C
Login
MCP and programmatic access

MCP setup

Create a key, pick a scope, wire it into Claude or Cursor.

Connecting an MCP client to Beetl takes 1 API key and 1 config block. A key belongs to you and to one tenant, so every call the client makes runs as you, inside that tenant.

Create an API key

Open Settings. TenantAdmins see a Tenant and a User tab and choose User; other users land there directly. Under MCP API keys, choose Create API key, give the key a label you will recognize later, such as claude-desktop-laptop, and pick a scope.

The next dialog shows the key once, together with config for Claude Code, Cursor and Claude Desktop with the key already filled in. Copy what you need before you close it. Beetl cannot show the key again, so if you lose it, delete the key and create a new one.

Pick a scope

ScopeWhat the client can do
readRun SQL through execute_query, page an existing result, list datasets and pipelines, inspect pipeline runs, preview a stored pipeline definition with run_pipeline, trace lineage with get_lineage, read automations and their runs, read apps and their runs, read reports, their documents and templates, and read the platform reference docs.
writeEverything in read, plus build_pipeline, update_pipeline and deploy_pipeline, the tools that create, update, run, pause, resume or delete an automation, and the tools that create and update reports, tag their documents, save templates and run a report with render_report.

read is the default in the dialog, and a read key only sees the read tools in tools/list. run_pipeline is a read tool: it previews the stored definition and writes nothing.

Keep read unless you intend the client to author and deploy pipelines, change automations or manage reports. Over MCP, a write key deploys a pipeline without the confirmation chat asks for, and the deploy starts a run that writes the destination dataset. render_report also runs without asking and writes PDFs to your storage. A read key that calls a write tool gets an error result naming the scope the tool needs.

Wire it into your client

The endpoint is https://app.beetl.io/mcp, and the key goes in the X-API-Key header.

claude mcp add --transport http beetl https://app.beetl.io/mcp \
  --header "X-API-Key: PASTE_YOUR_KEY_HERE"

Verify the handshake

The server is stateless, so a single POST is enough to prove the key works.

curl -sS https://app.beetl.io/mcp \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BEETL_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-11-25",
      "capabilities": {},
      "clientInfo": { "name": "curl", "version": "1.0" }
    }
  }'

A working key returns a result with protocolVersion, a tools capability with listChanged: false, serverInfo and instructions, a short guide that tells the model how to use the tools. A missing key returns HTTP 401 with the code MISSING_API_KEY, and an unknown or deleted key returns 401 with INVALID_API_KEY.

To see what your key can call, follow up with tools/list:

curl -sS https://app.beetl.io/mcp \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BEETL_API_KEY" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'

Using the tools

Before writing SQL, a client should call list_data_sets to see what data exists. search_files and read_file open the platform reference docs, including the SQL dialect.

execute_query requires a purpose argument alongside the SQL: a short, user-facing sentence saying what the query should establish.

execute_query returns the first page of up to 50 rows, fewer when rows are wide, with a result_id, the exact total_rows and a has_more_rows flag. When has_more_rows is true, call get_query_result with the result_id and next_page_offset instead of running the query again. A result stores up to 1,000 rows, so paging stops there. For larger reads, see Export.

Good practice

  • Create 1 key per client and machine, so you can remove one without breaking the others.
  • Label keys so you recognize them later. The key list shows when each key was last used.
  • Delete keys you no longer use.
  • Treat a write key like a deploy credential, and keep it out of shared config and repositories.
  • Deactivating a user or a tenant disables their keys immediately.

Last updated on

On this page