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
| Scope | What the client can do |
|---|---|
read | Run 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. |
write | Everything 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
writekey like a deploy credential, and keep it out of shared config and repositories. - Deactivating a user or a tenant disables their keys immediately.
Related
Last updated on