Skip to main content

Recipes

Worked end-to-end flows over MCP. Each is a sequence of tools/calls — phrased here as what you'd ask an agent, with the tools it uses. All run through the same scopes/auth as REST.


1. Author, test, and run a workflow — entirely over MCP

"Build a workflow that sends a Slack message whenever a deal moves to Won, then test it."

The agent chains:

  1. get_workflow_authoring_guide — learn the YAML authoring spec (workflows:read).
  2. list_workflow_nodes / get_workflow_node_schema — find the trigger + Slack node and their config fields.
  3. validate_workflow — compile the YAML spec; fix any blocking errors before saving.
  4. create_workflow — save it (as a draft — it won't fire until activated) → returns workflow_id.
  5. test_workflow_node or run_workflow — dry-run it. Both are confirm-gated: the first call returns a confirmation summary; re-call with confirm: true to actually execute (real side effects, no sandbox).
  6. activate_workflow — once happy, let it fire on its trigger (workflows:author).
Real execution, human-in-the-loop

There is no sandbox — a run hits live data and integrations. That's why run/test tools require an explicit confirm: true on the second call. Build with workflows:author; keep run rights (workflows:run) on a separate key if you want approve-only agents.


2. Ask your knowledge base (RAG)

"What's our refund policy for annual plans?"

  1. list_knowledge_bases — find the KB id (knowledge:read).
  2. ask_knowledge_base{ kb_id, question } → returns { answer, sources } (retrieval + LLM; incurs credits).

Prefer search_knowledge_base when you want the raw relevant chunks (with scores) rather than a synthesized answer.

{
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "ask_knowledge_base",
"arguments": { "kb_id": "…", "question": "What is our refund policy for annual plans?" }
}
}

Add a document first with add_kb_document (raw text/markdown, or a base64 file — pdf/docx/…); it's chunked, embedded, and searchable on return.


3. Natural language → SQL → chart

"What was our total Meta ad spend last quarter, by campaign? Chart it."

  1. get_data_model — the grounded schema: tables, columns, real enum values, join graph, custom-field refs (analytics:read). Read this so the agent uses real names, not guesses.
  2. generate_sql or run_query with question — the NL→SQL agent grounds + validates read-only SQL and (in validate mode) returns sample rows + the generated_sql.
  3. create_dataset — save the SQL as a reusable dataset (analytics:write).
  4. create_chart — build a chart on the dataset (chart_type, chart_config with dimensions/metrics).
  5. run_chart — get the server-side aggregated rows to render.

Only SELECT is allowed — writes are blocked and queries are org-scoped.


4. Single-node test before you commit

"Show me exactly what this API Request node returns for this contact."

test_workflow_node runs one node in isolation with sample inputs — no saved workflow needed. Give node_type, an optional config (with {{templates}}), and sample inputs. Confirm-gated: the first call returns the resolved config + node schema to review; re-call with confirm: true to execute and see the real output. Great for debugging a node's config before wiring it into a workflow.


5. Enrich a contact from the CRM

"Find the contact for jane@acme.com and log a note that she requested a demo."

  1. search_contacts{ q: "jane@acme.com" } (contacts:read).
  2. create_note{ entity_type: "contact", entity_id: "<id>", content: "Requested a demo" } (notes:write).
  3. optionally create_task — a follow-up task linked to the contact.

Associations work the same way: list_contact_companies, link_contact_to_company, etc. — each requiring read/write on both entities.


6. Bulk update 1,000 records — chunked, with a per-chunk report

"Set lead_status to 'nurture' for these 1,000 contacts, and don't fire my automations."

Batch tools take the entity as a parameter and up to 200 items per call — the agent chunks 1,000 into 5 calls and reports each chunk's outcome:

  1. batch_update_records × 5 — { entity: "contacts", updates: [ ...200 × { id, lead_status: "nurture" } ], suppress_automations: true } (contacts:write).
  2. Each call is atomic: it returns count on success, or a per-index error (batch_validation_error / unknown-id) and nothing in that chunk is written — so the agent always knows exactly which rows are committed:

✅ chunk 1 (rows 1–200): 200 updated ❌ chunk 2 (rows 201–400): rejected — row 237: lead_score must be an integer; no rows in this chunk were written ✅ chunk 3 (rows 401–600): 200 updated ✅ chunk 4 (rows 601–800): 200 updated ✅ chunk 5 (rows 801–1000): 200 updated

  1. The agent fixes row 237 and resends only chunk 2 — the committed chunks must not be resent.

batch_create_records and batch_delete_records work the same way. suppress_automations: true is the bulk-import switch: records are written and stay searchable, but per-record workflow triggers don't fire (no surprise credit burn). Leave it off when the automations are the point. Full semantics + REST equivalents: Bulk Operations.


Discover, don't guess

Every tool's exact input schema + required scope is in the Tool catalog. tools/list shows the full catalog (plus your org's exposed workflow tools when authenticated); your key's scopes are enforced when a tool is called.