Skip to main content
Actions transform your agent from a reasoning engine into an action-taker. In code, you give an agent four kinds of callable capability on defineAgent:
agents/sdr.ts
export const sdr = defineAgent("sdr", {
  connector: openai,
  languageModel: "gpt-4o",
  systemPrompt: "Qualify inbound leads and route hot ones to Slack.",

  // Your own tools (defineTool handles)
  tools: [enrich, { ref: scoreLead, description: "Score ICP fit 1–10.", isBulkAllowed: true }],

  // Actions from a connected integration
  connectorActions: [{ integration: "hunter", actionSlug: "findEmail" }],

  // Specialist agents this one can delegate to
  subAgents: [{ ref: researcher, waitUntilFinished: true }],

  // External MCP servers whose tools the agent can call
  mcpClients: [{ kind: "custom", name: "notion", url: "https://mcp.notion.com/mcp", authentication: null, disabledToolSlugs: [] }],
});
tools, connectorActions, and subAgents all accept the same per-call options — { name, description, isBulkAllowed, waitUntilFinished } — wrapped around a bare handle ({ ref, …options }) or, for connector actions, alongside integration / actionSlug. The description is the AI contract — the agent reads it to decide when to call the action.
Connect an integration with defineConnector before referencing its actions, and see Tools for building the tools you pass in. Run cargo-ai cdk types so actionSlug values autocomplete from the real registry.

How actions work

When an agent receives a task, it:
  1. Analyzes the goal and available actions
  2. Selects the appropriate action(s) based on their descriptions
  3. Executes the action with the right inputs
  4. Uses the output to continue reasoning or complete the task
The action’s description is critical. The agent reads this description to decide when and how to use the action. Write descriptions that clearly explain what the action does and when to use it.

Configuring an action

Description (the AI contract)

This plain-language description tells the agent:
  • What the action does
  • When to use it
  • What inputs it expects
Good example:
"Enriches a company using its domain. Returns firmographic data including
employee count, industry, funding, and tech stack. Use this when you need
company information for qualification or research."
Poor example:
"Gets company data"

Fixed vs. agent-decided inputs

By default the agent decides every input field of a connector action at runtime, from conversation context and the action’s description. To lock a field to a fixed value, set it in the action’s config — anything you put there is sent as-is and never left to the agent:
connectorActions: [{
  integration: "hubspot",
  actionSlug: "createRecords",
  config: { objectType: "deals" },   // always deals — the agent fills in the rest
}],
Mix fixed and agent-decided fields when some inputs should always be the same (e.g., a specific CRM pipeline ID) while others depend on the conversation context (e.g., a lead’s email address).
In the UI, each field additionally has a mode selector — Default (fixed value), Auto (agent decides), or Disable (field skipped entirely). Disabling a field is UI-only today; in code, fields are either fixed via config or agent-decided.

Bulk execution

Set isBulkAllowed: true when the agent should apply the action across multiple records in a single run. Useful for batch operations like:
  • Enriching a list of companies
  • Updating multiple CRM records
  • Sending notifications to several recipients

Waiting for completion

waitUntilFinished (default true) blocks the agent until the action finishes so it can use the result. Set it to false for fire-and-forget calls — e.g. a Slack notification the agent doesn’t need to read back.

Common action types

CategoryExamplesTypical use
EnrichmentClearbit, Apollo, FullEnrichGather company or contact data
CRMSalesforce, HubSpot, AttioCreate/update records, log activities
CommunicationSlack, Email, OutreachSend messages, add to sequences
Data lookupInternal APIs, SQL queriesRetrieve custom data from your systems

MCP servers

Cargo agents support the Model Context Protocol (MCP) — an open standard for connecting AI models to external actions and data sources. Declare the servers an agent can call with mcpClients; Cargo discovers and registers their tools automatically:
mcpClients: [
  // Any MCP-compatible server, by URL
  { kind: "custom", name: "notion", url: "https://mcp.notion.com/mcp", authentication: null, disabledToolSlugs: [] },

  // An MCP server backed by one of your connectors (by uuid)
  { kind: "connector", name: "hubspot", connectorUuid: "9c26…", integrationSlug: "hubspotMcp", disabledToolSlugs: [] },
],
Use disabledToolSlugs to hide individual tools from the agent, and authentication to pass an OAuth token set for servers that require one (or null for unauthenticated servers). In the UI, the same thing is configured by pasting the server URL on the agent’s Actions tab.
This is the agent consuming external MCP servers. To expose your own Cargo tools and agents as an MCP server, see MCP servers.

Best practices

Write clear descriptions

The agent relies on descriptions to choose actions. Be specific about what the action does and what it returns.

Name actions descriptively

Use names like Enrich-Company or Slack-Notify-Rep instead of generic names like Action1.

Handle failures gracefully

In your agent’s instructions, specify what to do if an action call fails (retry, skip, report error).

Limit scope

Only give agents access to the actions they need. Fewer actions = faster, more accurate action selection.

Next steps

Connectors

Connect integrations with defineConnector before referencing their actions.

Tools

Build reusable tools with defineTool to pass into an agent.