Tool reference
Every tool an MCP client can call, with its scope and arguments.
Each tool needs the read or the write scope. A read key gets the read tools and a write key
gets all of them. tools/list returns only the tools your key's scope allows, with each tool's full
input and output schema. Calling a write tool by name with a read key fails with an error naming
the scope it needs.
Every tool acts as the user who owns the key, inside that key's tenant, and none of them changes data in a system you connected. See The agent trust boundary.
Data and SQL
| Tool | Scope | What it does |
|---|---|---|
list_data_sets | read | Finds datasets by name, with exact SQL names, columns and lineage. |
get_lineage | read | Traces where a dataset, pipeline or report gets its data and what depends on it. |
execute_query | read | Runs a SQL query and saves the result. Queries cannot change data. |
get_query_result | read | Returns another page of a saved result without running the SQL again. |
list_data_sets
| Argument | Notes |
|---|---|
name_query | Case-insensitive match on the dataset name or qualified name. Omit it only to browse. |
limit | Default 20, maximum 100. The reply's omitted count says whether to narrow the search. |
Each dataset lists the source event fields a pipeline's run_mapping can use.
get_lineage
| Argument | Notes |
|---|---|
entity_type required | data_set, pipeline or report. |
id required | The UUID from list_data_sets, list_pipelines or list_reports. |
The reply lists the upstream and downstream datasets, pipelines and reports of that entity.
execute_query
| Argument | Notes |
|---|---|
sql required | DataFusion SQL; see DataFusion SQL. Don't add a small LIMIT just because the reply shows one page. |
purpose required | 1 to 200 characters for a person, saying what the query should establish. |
The reply holds the first page of up to 50 rows (fewer when rows are wide), each an array of
strings, booleans and nulls, plus result_id, has_more_rows and total_rows, which counts every
row the SQL produced. A result stores at most 1,000 rows, expires after 7 days and opens only for
you. See Query results.
get_query_result
| Argument | Notes |
|---|---|
result_id required | From execute_query or run_pipeline. |
page_offset | Zero-based row offset. Pass the next_page_offset from the previous page. |
page_limit | 1 to 50 rows. |
Pipelines
| Tool | Scope | What it does |
|---|---|---|
list_pipelines | read | Lists pipelines with lineage, deployment state and each source's trigger mapping. |
get_pipeline | read | Returns one pipeline's stored Working definition and, if deployed, its Deployed definition. |
run_pipeline | read | Previews the stored Working version as a dry run. Writes nothing. |
list_pipeline_runs | read | Lists one pipeline's runs. |
get_pipeline_run | read | Returns one run, with its status, error and run values. |
build_pipeline | write | Creates a new pipeline's Working version. Deploys nothing. |
update_pipeline | write | Changes an existing pipeline's Working version. Deploys nothing. |
deploy_pipeline | write | Promotes Working to Deployed and starts a run that writes the destination. |
list_pipelines takes the optional filters name_query, status (Active or Disabled),
source_dataset_id, destination_name and limit (default 50, maximum 100). Whether a pipeline
is deployed is in deployment.is_deployed.
get_pipeline needs pipeline_id. It returns the stored definition, which is shaped
differently from update_pipeline input, plus the versions and required run.* values.
build_pipeline
| Argument | Notes |
|---|---|
pipeline_name required | Must not match an existing pipeline's name. |
purpose required | 1 to 200 characters saying what the change is for. |
description required | 1 to 3 sentences giving the output grain and business rules. |
sources required | Each has dataset_id (a UUID, name or qualified name), an optional alias for the SQL, trigger_enabled (default true) and run_mapping, such as {"dt": "{{ source.partition.values.dt }}"}. |
stages required | Each has name and sql. SQL can use {{ vars.<key> }}, {{ run.<key> }} and {{ fn.today() }}. |
destination_name required | The output dataset name, without tenant or tier prefixes. |
destination_tier required | bronze, silver or gold. |
vars | Values the SQL references as vars.*. Put dates, rates and thresholds here instead of in the SQL. |
destination_partition_by | Partition columns. They must exist in the final stage's output. |
write_mode | "overwrite", "append", or an object for overwrite with a partition_predicate or for merge. Defaults to overwrite, a full rebuild. |
See Template variables and Write modes and partitioning.
update_pipeline needs only pipeline_id and accepts the other build_pipeline fields except
pipeline_name. Send only what changes: omitted fields keep their stored values, but a sources,
stages or vars you send replaces the whole collection. Within a source, omitting
trigger_enabled or run_mapping keeps the current setting; run_mapping: {} clears it.
run_pipeline
| Argument | Notes |
|---|---|
pipeline_id required | The pipeline to preview. |
stage_name | Defaults to the final stage. The earlier stages it depends on run too. |
row_limit | 1 to 1,000, default 50. The reply holds up to 50 rows; page the rest with get_query_result. |
run_variables | Values for run.*, such as {"dt": "2026-10-03"}. Required when the SQL uses run.*. |
The reply also says whether the output fits the destination's schema and partitioning, so preview the final stage after every change and before you deploy.
list_pipeline_runs needs pipeline_id and accepts status (Queued, Dispatched,
Running, Completed, Cancelled or Failed) and limit (default 20, maximum 100).
get_pipeline_run needs a job_id from that list.
deploy_pipeline
| Argument | Notes |
|---|---|
pipeline_id required | The pipeline to deploy. |
initial_run_context | {"run": {"dt": "2026-10-03"}}. Required when the pipeline uses run.*; Beetl checks the pipeline with these values and gives them to the first run. |
The checks match Deploy in the app; see Deploy and trigger.
Deploys over MCP are not confirmed
In chat, a deploy waits for you to allow it. Over MCP, deploy_pipeline with a write key
deploys at once, and render_report writes PDF documents to your storage without asking. Treat a
write key like a deploy credential. No tool reruns a deployed pipeline; use Run in the app.
Automations
These tools manage the checks described in Automations. In the editor, goal is
labeled Instructions, instructions is What should the report include? and
suggested_queries are Starting queries.
| Tool | Scope | What it does |
|---|---|---|
list_automations | read | Lists automations with schedule, status, latest run and next run. |
get_automation | read | Returns one automation's definition, status and next run. |
list_automation_runs | read | Lists saved runs, newest first. |
get_automation_run | read | Returns one run's finding, summary, findings list, report, rendered PDF and investigation steps. |
create_automation | write | Creates an automation. |
update_automation | write | Replaces an automation's whole definition. |
delete_automation | write | Deletes an automation. Refused while a run is in progress. |
run_automation | write | Starts a run and returns its run_id right away. |
pause_automation | write | Stops scheduled runs. |
resume_automation | write | Restarts scheduled runs. |
get_automation, delete_automation, run_automation, pause_automation and
resume_automation take only automation_id.
create_automation
| Argument | Notes |
|---|---|
name required | Up to 255 characters. |
goal required | What to check, up to 8,000 characters. |
schedule required | cron (6 fields, starting with seconds) and timezone (IANA, such as Europe/Vienna). Runs at least 15 minutes apart. |
suggested_queries required | Up to 20 objects with name and sql. Pass [] for none. |
use_previous_runs required | true lets a run compare against earlier runs. |
instructions | What the report should include, up to 16,000 characters. |
model | A model ID your workspace offers. Omit it to use the workspace default. |
reasoning_effort | low, medium or high. Omit it for the default. |
template | Name of a report template from list_report_templates. Every completed run's findings are then rendered as a PDF. Omit it for none. |
Creating or running an automation needs AI in the tenant; see AI in a tenant.
update_automation takes automation_id plus the same required fields. It replaces the whole
definition, so read the current one with get_automation and send back every value you want to
keep, including model, reasoning_effort and template.
run_automation returns with status running; poll get_automation_run for the outcome. If
the reply never arrived, check list_automation_runs for a recent run before you start another.
list_automation_runs needs automation_id and accepts limit (default 20, maximum 100) and
cursor. Pass the next_cursor from one page to get the next.
get_automation_run needs automation_id and run_id. findings lists up to 20 findings,
each with a title, detail and references, and document describes the rendered PDF when the
automation has a template (otherwise it is null). Its query_result_ids point to evidence you open
in the app; get_query_result cannot open them.
Apps
Apps are applications Beetl provides; see Apps. These tools only read. Creating, changing, running and deleting apps is not available over MCP: make those changes in the app, or in chat, where you confirm them.
| Tool | Scope | Arguments | What it does |
|---|---|---|---|
list_app_types | read | None | Lists the app types you can create and whether each is available. |
get_app_type | read | app_type_id required | Returns an app type's expected input columns and default input query. |
list_app_instances | read | app_type_id, name_query, offset | Finds your apps by type or name, 50 per page. |
get_app_instance | read | app_instance_id required | Returns an app's settings, bound inputs, input queries, outputs and schedule. |
preview_app_input_query | read | app_instance_id, name, sql (all required) | Runs an input query without saving it and returns its schema and up to 50 rows. |
list_app_runs | read | app_instance_id required, cursor | Lists an app's runs, newest first, with status and errors. |
get_app_run | read | app_instance_id, run_id (both required) | Returns one run, including its processing and publication status. |
To read what an app published, query its output datasets with list_data_sets and execute_query.
File processors
File processors turn the files in a File Set into a dataset; see Documents and spreadsheets. These tools only read. They never start processing or an AI request, and setting up or changing a processor is not available over MCP: do that in the app, or in chat, where you confirm it.
| Tool | Scope | What it does |
|---|---|---|
list_file_processors | read | Lists processors with their file set, lifecycle and configuration version. |
get_file_processor | read | Returns one processor's settings, its dataset and its publication state. |
list_processor_documents | read | Lists a processor's documents with their record and issue counts. |
read_processor_records | read | Returns one document's current records and their issues. |
read_processor_source | read | Returns the document's retained source text, a page, a search match or a worksheet range. |
list_file_processors takes the optional offset and limit (1 to 50, default 20). The reply
holds processors, each with its processor_id, name and file_set_id, and a next_offset
when more follow.
get_file_processor needs processor_id. The reply holds the processor's settings, its
outputs (the dataset each writes to) and whether the latest records have been published to it.
Query the dataset itself with list_data_sets and execute_query.
list_processor_documents
| Argument | Notes |
|---|---|
processor_id required | The processor whose documents to list. |
query | Keeps documents whose file name contains this text. |
offset, limit | limit is 1 to 50, default 20. Pass the next_offset from the previous page. |
Each document has a result_id, which read_processor_records and read_processor_source need, plus its file name, format, record_count,
issue_count and any error.
read_processor_records needs processor_id and result_id, and accepts offset and limit
(1 to 50). Each record holds its current values and its validation issues.
read_processor_source
| Argument | Notes |
|---|---|
processor_id required, result_id required | The document to read. |
selection required | What to read. Set type to metadata, page, search or worksheet. |
The selection takes these shapes:
type | Other fields | Returns |
|---|---|---|
metadata | None | The file name, format, page count or worksheet list, and any notes from reading the file. |
page | page: a page number from 1, for documents that have pages | The text on that page. |
search | query: 1 to 500 characters | The passages that contain the text. |
worksheet | sheet and range, a one-based A1 range such as B7:F20 | The cells in that range. |
page, search and worksheet also accept offset and limit (1 to 50). A reply
that is cut short says so and gives a next_offset.
Each of these tools accepts an optional pointer, an RFC 6901 pointer into the reply. A reply that is too
large to return in one piece lists the pointers of its parts instead. Call again with the same
arguments and one of those pointers to read that part.
Document text and the values read from it are your data, so they can contain instructions addressed to a model. A client should treat them as data, as it does query rows.
Reports and templates
These tools manage the PDF reports described in Reports. A report is a Typst layout plus named SQL bindings, and each run writes PDF documents to your object storage.
| Tool | Scope | What it does |
|---|---|---|
list_reports | read | Lists reports with the datasets each reads, its trigger, and its latest run and document. |
get_report | read | Returns a report's layout source, bindings, vars, per-row query, trigger and latest run. |
list_report_documents | read | Lists a report's issued documents, newest first. |
list_report_templates | read | Lists the shared report templates. |
get_report_template | read | Returns a template's source and images. |
create_report | write | Creates a report. |
update_report | write | Changes a report. |
render_report | write | Runs a report now and writes its PDFs to your storage. |
tag_report_document | write | Replaces a document's tags. |
save_report_template | write | Creates or replaces a shared template. |
get_report and render_report take only report_id. get_report_template takes only name.
list_reports and list_report_templates take no arguments.
list_report_documents
| Argument | Notes |
|---|---|
report_id required | The report whose documents to list. |
q | Matches the document key and its per-row values, such as an order number. |
tag | Keeps only documents with this tag. |
limit | 1 to 100. |
create_report
| Argument | Notes |
|---|---|
name required | 1 to 255 characters. |
source required | The Typst layout, up to 256 KiB. |
bindings | Up to 10 objects with name (lowercase letters, digits and underscores, starting with a letter, up to 64 characters) and sql (up to 32,000 characters). The layout reads each as /data/<name>.json. |
vars | Values the binding SQL references as vars.*. |
per_row | {sql, key}. The query returns one row per document and key names the column that identifies it. Each key value is issued once. |
trigger | {"kind": "schedule", "cron": "...", "timezone": "Europe/Vienna"}. cron has 6 fields, starting with seconds, and runs must be at least 15 minutes apart. Omit it to run only on demand. |
backfill | true issues documents for the rows the per-row query returns now. Otherwise they count as already issued. |
Saving renders one document as a check, so SQL or layout errors come back as diagnostics instead of a saved report. Each binding returns at most 10,000 rows and 8 MiB of JSON, and the per-row query at most 10,000 rows. A report needs object storage configured for the tenant.
update_report needs report_id and accepts the other create_report fields. Omitted fields
keep their values. bindings and vars replace the whole collection, and null for per_row or
trigger removes it.
render_report renders one document for a report without per_row, or one for each key that
has none yet, including keys whose documents failed earlier. The reply holds the run and its
documents; a failed document carries its error. It fails if the report is already running.
tag_report_document
| Argument | Notes |
|---|---|
report_id required, document_id required | The document to tag. |
tags required | The full list: up to 20 tags of 1 to 64 characters. An empty list removes all tags. |
save_report_template needs a name of 1 to 64 lowercase letters, digits and hyphens, and a
source, the template's Typst source of up to 256 KiB. Changing a template changes every report that
imports it from its next render.
Platform reference
These tools read Beetl's built-in knowledge base, which holds platform reference pages such as the DataFusion SQL guide. Read it before writing SQL or building pipelines.
| Tool | Scope | Arguments | What it does |
|---|---|---|---|
list_files | read | prefix, such as /platform/ | Lists document paths. |
search_files | read | query required, path_prefix | Full-text search with ranked snippets. Supports several words, "quoted phrases" and -exclusion. |
read_file | read | path required, offset, limit | Returns lines of one document. offset is 1-based; limit defaults to 500 lines, which is also the maximum. |
Related
Last updated on