Queries
Queries are saved table operations in your workspace. You pick a type (select, insert, update, delete, archive, or aggregation), target a table, configure filters and values in the visual builder, and optionally declare inputs so callers pass validated arguments.
Use them to encapsulate table reads and writes behind a clear name — then attach the same operation as an agent tool, MCP tool, function resource, or widget resource. Queries are not raw SQL; the builder compiles your filters against table rows.
When to use
- Reuse the same table read or write from agents, functions, widgets, and workflows
- Keep filters and field mappings in one place instead of duplicating workflow table blocks
- Expose a typed tool surface with an input schema and a server-generated result schema
Prefer inline table blocks only for one-off ops that will not be reused.
Create a query
Open Build → Queries for a workspace-wide query, or open an agent’s builder and use the Queries panel for one scoped to that agent.
- Click Create Query (or Build With AI to draft it in Studio).
- Enter a Name, Type, Table, and optional Description.
- Click Create — Vettero opens the query detail page.
Type and Table are fixed after create. The Result schema is generated on the server when you save — you do not edit it by hand.
Open the query builder
From the query detail page, click Edit to open the Query Builder. Use Save when the config is valid.
| Section | What you configure |
|---|---|
| Name / Description | Identity; the description becomes agent/MCP tool help text |
| Input schema | Arguments callers pass in (bound as args.<name> in filters and values) |
| Type editor | Filters, values, pagination, and sorting for the chosen operation |
| Result schema | Read-only; regenerated on save from type, config, and table fields |
Anywhere a filter or field value can be set, pick a fixed value or bind an argument from the input schema.
Run a query
Open the query editor and click Run. Fill in the arguments from the input schema. Vettero saves that input on the query so the next run starts from the same values.
Run executes the saved query and shows the output. If you still have unsaved edits, Vettero saves them first. Insert, update, delete, and archive queries write real rows. Agents, functions, and widgets do not use this sample input — they pass their own arguments.
Configure by type
Select
Read rows from the table.
| Setting | What it does |
|---|---|
| Mode | By Row ID loads one row; By Query matches rows with filters |
| Row ID | Shown in By Row ID mode — the row to load (fixed or from an input) |
| Filters | Shown in By Query mode — conditions on table fields |
| Pagination | One, All, Limit/Skip, or Limit/Page |
| Limit / Skip / Page | Shown for Limit/Skip or Limit/Page |
| Sorting | Optional field and ascending/descending order |
Returns — By Row ID or pagination One:
{ "row": { /* table fields */ }, "total": 1 }
Pagination All / Limit/Skip / Limit/Page:
{ "rows": [ { /* table fields */ } ], "total": 0 }
Insert
Add a new row.
| Setting | What it does |
|---|---|
| Fields / Field values | Map each table field to a fixed value or a query input |
Returns:
{ "row": { /* inserted table fields */ } }
Update
Change existing rows.
| Setting | What it does |
|---|---|
| Mode | By Row ID or By Query |
| Row ID / Filters | Which row(s) to update |
| Update One / Update Many | In By Query mode — update one match or many |
| Fields / Field values | Fields to change and their new values |
Returns:
{ "success": true, "matchedCount": 0, "modifiedCount": 0 }
Delete
Permanently remove rows.
| Setting | What it does |
|---|---|
| Mode | By Row ID or By Query |
| Row ID / Filters | Which row(s) to delete |
| Delete One / Delete Many | In By Query mode — delete one match or many |
Returns:
{ "success": true, "matchedCount": 0, "modifiedCount": 0 }
Archive
Soft-remove rows without deleting them. Configured like delete (Archive One / Archive Many in By Query mode).
Returns:
{ "success": true, "matchedCount": 0, "modifiedCount": 0 }
Aggregation
Group and summarize rows (count, sum, average, min, max).
| Setting | What it does |
|---|---|
| Filters (WHERE) | Optional conditions on rows before grouping |
| Aggregations | Operations to compute, with field and optional alias |
| Group By | Optional table field to group on |
| Having | Optional conditions on the grouped results |
| Sort (ORDER BY) | Optional sort on group results |
| Pagination | One, All, Limit/Skip, or Limit/Page |
Returns — each row has _id (group key) plus a property per operation alias:
{
"rows": [ { "_id": null, "count": 0 } ],
"total": 0
}
Attach to an agent
In the agent builder, open Config → Tools → Manage Tools → Table. Saved queries appear under Global (and agent-scoped queries from the builder panel). You can also attach table functions for one-off table ops.
You can also type # in the agent Task and select the query to mention and attach it.
Use from functions and widgets
Bind the query as a Query resource, then call it:
- Functions:
await vt.runQuery(key, input?) - Widgets:
vt.runQueryorvt.watchQueryfor live updates when related rows change
Callers pass a plain object whose keys match your input argument names.
Limits
- Target table must exist in the workspace; filter fields must be real table fields.
- Type is chosen at create time and cannot change afterward.
- Result schema is regenerated on update — do not set it manually.
- Runs consume credits and are billed by affected or returned rows.
- Delete moves the query to trash for the workspace retention period.
Where queries are used
| Place | How |
|---|---|
| Agents | Tools → Table (saved queries), or # mention in the Task |
| Functions | Bind as a Query resource and call vt.runQuery |
| Widgets | Bind as a Query resource; call runQuery or watchQuery |
| MCP Servers | List queries on an MCP server; each becomes an MCP tool |
| Workflows | Invoke the saved query, or use inline table blocks for one-offs |