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.

Confirmation on destructive tools

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_id returns 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.