Tool reference
The server registers 14 tools. In your host's tools/list they appear as a flat list; here they're grouped by journey for readability. Each tool declares MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) so your host knows when to ask for confirmation.
Tools that change data (confirm_save, add_record, update_record, trigger_workflow, send_via_integration, abort_build) declare destructiveHint: true. Compliant hosts prompt you before running them. A key can also be scoped to never allow them at all.
Build
build_system
Build a brand-new system from a description. Returns a preview; it does not save. You must call confirm_save(build_id) after approving.
- Scope:
workspace:build - Annotations: not read-only, not destructive, open-world, not idempotent (send an
Idempotency-Key) - Streams: yes (progress as it plans and builds)
Input
{
"intent": "a lead capture form, a table to store entries, and a workflow that pings me on Slack",
"preferred_integrations": ["slack"],
"extend_build_id": null
}
Output
{
"build_id": "bld_...",
"status": "preview_ready",
"summary": "Form + table + Slack follow-up workflow",
"assets": [{ "type": "form", "name": "Lead Capture", "...": "..." }],
"warnings": [],
"requires_oauth": [],
"next_action": { "tool": "confirm_save", "arguments": { "build_id": "bld_..." } },
"expires_at": "2026-05-30T12:00:00Z"
}
Example: "Build me a lead intake system: a form, a table to store entries, and a Slack follow-up." → build_system(intent) → preview with a build_id → you approve → confirm_save(build_id).
update_asset
Modify an existing asset. Like build_system, it returns a preview to approve with confirm_save.
- Scope:
workspace:build+workspace:read - Annotations: not destructive, open-world, not idempotent
- Streams: yes
Input
{ "asset_id": "ast_...", "intent": "add an auto-responder email when someone submits" }
Output: same shape as build_system; the summary describes the diff.
confirm_save
Persist a previewed build. Only call after the user explicitly approves.
- Scope:
workspace:write - Annotations: destructive, idempotent (calling twice with the same
build_idreturns the same result)
Input
{ "build_id": "bld_...", "publish_immediately": false }
Output
{
"status": "saved",
"assets": [{ "asset_id": "ast_...", "type": "form", "product_url": "https://..." }],
"push_errors": [],
"message": "Saved 3 assets"
}
status may be saved, partial_save, expired, or already_saved. Previews expire one hour after the build.
abort_build
Cancel an in-flight build_system or update_asset. Per the MCP spec, a dropped connection is not a cancellation; use this tool to intentionally stop a build.
- Scope: same as the original build
- Annotations: destructive, idempotent
Input: { "build_id": "bld_..." }
Output: { "status": "aborted" | "already_complete" | "not_found", "message": "..." }
Discover
list_my_assets
List assets in the workspace. Use it before suggesting new builds, or to find an asset_id for update_asset and the operate tools.
- Scope:
workspace:read - Annotations: read-only, idempotent
Input
{ "type": "all", "limit": 50, "cursor": null }
type is one of form, workflow, table, email, agent, sequence, or all.
Output
{
"assets": [
{ "asset_id": "ast_...", "type": "workflow", "name": "Onboarding", "publish_status": "published", "product_url": "https://..." }
],
"next_cursor": null
}
describe_my_workspace
Workspace context: connected integrations, asset counts, recent activity, and credit balance. Call this before build_system when the request is open-ended.
- Scope:
workspace:read - Annotations: read-only, idempotent
Input: {}
Output
{
"workspace": { "id": "ws_...", "name": "Acme" },
"asset_counts": { "form": 4, "workflow": 7, "table": 3 },
"connected_integrations": ["gmail", "slack"],
"credit_balance": 1240,
"recent_builds": []
}
Operate
query_records
Query records from a table with filters, sorts, field projection, and pagination.
- Scope:
workspace:read - Annotations: read-only, idempotent
Input
{
"table_id": "tbl_...",
"filters": [{ "field": "status", "op": "eq", "value": "active" }],
"sort": [{ "field": "created_at", "dir": "desc" }],
"fields": ["name", "company", "status"],
"limit": 50
}
Filter operators: eq, neq, gt, lt, gte, lte, contains, in, is_empty, is_not_empty.
Output
{ "records": [{ "id": "rec_...", "fields": { "name": "Ada", "status": "active" } }], "total_estimate": 12, "next_cursor": null }
add_record
Add a single record to a table.
- Scope:
workspace:execute - Annotations: not destructive, not idempotent; send an
Idempotency-Key(calling twice otherwise creates two rows)
Input: { "table_id": "tbl_...", "fields": { "name": "Ada Lovelace", "company": "Analytical" } }
Output: { "record_id": "rec_...", "fields": { "...": "..." }, "created_at": "..." }
update_record
Update fields on an existing record.
- Scope:
workspace:execute - Annotations: destructive, idempotent
Input: { "table_id": "tbl_...", "record_id": "rec_...", "fields": { "status": "contacted" } }
Output: { "record_id": "rec_...", "fields": { "...": "..." }, "updated_at": "..." }
trigger_workflow
Trigger a published workflow with a payload. Runs synchronously (workflows typically finish in under 30 seconds).
- Scope:
workspace:execute - Annotations: destructive, open-world, not idempotent
Input
{ "workflow_id": "ast_...", "payload": { "email": "ada@analytical.com", "plan": "pro" } }
Output
{ "execution_id": "exe_...", "status": "completed", "result": { "...": "..." }, "duration_ms": 4200 }
Common errors: workflow_not_found, workflow_not_published, workflow_failed, execution_timeout. See Errors.
send_via_integration
Invoke one operation on a connection the user has already set up (Gmail, Slack, HubSpot, …). For one-shot sends and posts, not for building workflows.
- Scope:
workspace:execute - Annotations: destructive, open-world, not idempotent (send the same email twice and you spam)
Input
{
"integration": "gmail",
"operation": "send-email",
"params": { "to": "ada@analytical.com", "subject": "Following up", "body": "Hi Ada…" },
"connection_id": null
}
Output: { "status": "succeeded", "integration_response": { "...": "..." }, "used_connection_id": "conn_..." }
Common errors: integration_not_connected (response includes a connect_url), operation_not_found, oauth_token_expired, provider_error.
run_agent
Send a message to a published agent and stream the reply.
- Scope:
workspace:execute - Annotations: not destructive, open-world
- Streams: yes
Input: { "agent_id": "agt_...", "message": "Draft a reply to this ticket: …", "thread_id": null }
Output: { "thread_id": "thr_...", "response": "…", "tool_calls_summary": [] }
To continue a conversation, pass the returned thread_id on the next call.
run_enrichment
Submit a person, company, or email for enrichment. Returns a job handle immediately; poll with check_enrichment.
- Scope:
workspace:execute - Annotations: not destructive, idempotent
- Async: yes
Input: { "type": "email", "input": { "email": "ada@analytical.com" } }
Output: { "job_id": "job_...", "status": "submitted", "estimated_completion_seconds": 30 }
check_enrichment
Check the status of a previously submitted enrichment job.
- Scope:
workspace:read - Annotations: read-only, idempotent
Input: { "job_id": "job_..." }
Output
{ "job_id": "job_...", "status": "completed", "result": { "company": "Analytical Engines Ltd", "...": "..." }, "completed_at": "..." }
status is pending, completed, or failed.