---
title: "AI agent"
description: "Use `ai.agent` and `ai.preset_agent` for tool-calling agent runs inside Tracecat workflows: configure tools, secrets, and instructions for autonomous reasoning."
---

{/* Auto-generated by scripts/generate_ai_docs.py; do not edit by hand. */}

Use `ai.agent` when the model needs tool calls. You give the agent a prompt, instructions, and an allowlist of actions it can call during the run.

## Capabilities

- `ai.agent`: Prompt plus tool calls. Use the `actions` list to control which Tracecat actions the agent can use.
- <Badge icon="lock" color="blue" size="sm" shape="pill">EE</Badge> `ai.preset_agent`: Prompt plus a saved agent configuration. Use this when you want reusable instructions, tools, and MCP integrations across workflows.
- `tool_approvals`: Require approval before selected tools run. This is an enterprise feature.
- `max_tool_calls` and `max_requests`: Bound how much work the agent can do in a single run.

## Structured outputs

`ai.agent` also supports `output_type`.

- Use it when the agent should return a final object or typed value after tool use.
- Keep the schema focused on the final answer, not the intermediate tool steps.

## MCP

<Badge icon="lock" color="blue" size="lg" shape="pill">Enterprise Edition</Badge>

`ai.agent` does not take MCP servers directly in the workflow action. If you need MCP, save that configuration in an agent preset and run it with `ai.preset_agent`.
`ai.preset_agent` supports both remote and stdio MCP servers.

Internet access is controlled by the root preset for the shared sandbox process. Subagent presets can define their own tools and MCP integrations, but their internet setting does not grant network access unless the root preset also enables it.

See [MCP integrations](/automations/integrations/mcp-integrations) to learn more.

## Reference

### `ai.agent`

AI agent with tool calling capabilities. Returns the output and full message history.

#### Inputs

<ParamField path="model_name" type="string" required>

Name of the model to use.

</ParamField>

<ParamField path="model_provider" type="string" required>

Provider of the model to use.

</ParamField>

<ParamField path="user_prompt" type="string" required>

User prompt to the agent.

</ParamField>

<ParamField path="actions" type="array[string] | null">

Actions (e.g. 'tools.slack.post_message') to include in the agent.

Default: `null`.

</ParamField>

<ParamField path="base_url" type="string | null">

Base URL of the model to use.

Default: `null`.

</ParamField>

<ParamField path="instructions" type="string | null">

Instructions for the agent.

Default: `null`.

</ParamField>

<ParamField path="max_requests" type="integer">

Maximum number of requests for the agent.

Default: `45`.

</ParamField>

<ParamField path="max_tool_calls" type="integer">

Maximum number of tool calls for the agent.

Default: `15`.

</ParamField>

<ParamField path="model_settings" type="object | null">

Model settings for the agent.

Default: `null`.

</ParamField>

<ParamField path="output_type" type="string | object | null">

Output type for agent responses. Select from a list of supported types or provide a JSONSchema.

Default: `null`.

</ParamField>

<ParamField path="retries" type="integer">

Number of retries for the agent.

Default: `3`.

</ParamField>

<ParamField path="tool_approvals" type="map[string, boolean] | null">

Per-tool approval overrides keyed by action name (e.g. 'core.cases.create_case'). Use true to require approval, false to allow auto-execution.

Default: `null`.

</ParamField>

#### Examples

**Investigate an alert with tools**

```yaml
- ref: investigate_alert
  action: ai.agent
  args:
    model_name: gpt-4.1
    model_provider: openai
    instructions: |
      You are a security triage agent.
      Review the alert, gather missing context, and write a concise analyst summary.
    user_prompt: |
      Investigate this alert and explain whether it needs escalation:

      ${{ TRIGGER.alert }}
    actions:
      - tools.slack.lookup_users_by_email
      - tools.github.search_code
      - core.cases.create_comment
    max_tool_calls: 6
    output_type:
      type: object
      properties:
        verdict:
          type: string
        summary:
          type: string
      required:
        - verdict
        - summary
```

**Require approval for sensitive tools**

```yaml
- ref: draft_case_update
  action: ai.agent
  args:
    model_name: claude-3-5-sonnet-latest
    model_provider: anthropic
    instructions: |
      Investigate the incident, then propose the next action.
      Create or update records only if the required approval is granted.
    user_prompt: |
      Review the latest evidence for case ${{ TRIGGER.case_id }} and decide what to do next.
    actions:
      - core.cases.get
      - core.cases.create_comment
      - core.cases.update
    tool_approvals:
      core.cases.update: true
    max_tool_calls: 4
```

### `ai.preset_agent`

<Badge icon="lock" color="blue" size="lg" shape="pill">Enterprise Edition</Badge>

Run an AI agent using a saved agent preset.

#### Inputs

<ParamField path="preset" type="string" required>

Preset of the agent to run (e.g. 'security-analyst').

</ParamField>

<ParamField path="user_prompt" type="string" required>

User prompt to the agent.

</ParamField>

<ParamField path="actions" type="array[string] | null">

Optional override for the actions (e.g. 'tools.slack.post_message') that the agent should be allowed to call.

Default: `null`.

</ParamField>

<ParamField path="instructions" type="string | null">

Additional instructions to append to the preset instructions for this run.

Default: `null`.

</ParamField>

<ParamField path="max_requests" type="integer">

Maximum number of requests for the agent.

Default: `45`.

</ParamField>

<ParamField path="max_tool_calls" type="integer">

Maximum number of tool calls for the agent.

Default: `15`.

</ParamField>

<ParamField path="preset_version" type="integer | null">

Optional preset version number to pin for this run.

Default: `null`.

</ParamField>

#### Examples

**Run a saved agent preset**

```yaml
- ref: run_security_analyst
  action: ai.preset_agent
  args:
    preset: security-analyst
    preset_version: 3
    user_prompt: |
      Review the incident below and decide whether to escalate it:

      ${{ TRIGGER.incident }}
    max_tool_calls: 8
```

## FAQ

<AccordionGroup>
  <Accordion title="When should I use ai.action, ai.agent, or ai.preset_agent?">
    - Use `ai.action` when you only need one model response and no tools.
    - Use `ai.agent` when the model must call Tracecat actions during the run.
    - Use `ai.preset_agent` when you want a reusable saved configuration, especially for shared instructions, approvals, or MCP integrations.

    <CodeGroup>
    ```yaml Use ai.agent for tool calls
    - ref: analyze_input
      action: ai.agent
      args:
        model_name: gpt-4.1-mini
        model_provider: openai
        instructions: |
          Investigate the alert and summarize the next step.
        user_prompt: |
          Review this alert:

          ${{ TRIGGER.alert }}
        actions:
          - tools.github.search_code
          - core.cases.create_comment
        max_tool_calls: 4
    ```

    ```yaml Use ai.preset_agent for saved configuration
    - ref: analyze_with_preset
      action: ai.preset_agent
      args:
        preset: security-analyst
        user_prompt: |
          Review this alert and write a short analyst summary:

          ${{ TRIGGER.alert }}
    ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Why does ai.agent not accept MCP servers directly, and where do I configure MCP instead?">
    MCP integrations are configured on the preset, not on the `ai.agent` workflow action itself.
    If the run needs MCP tools, create or update an agent preset, attach the MCP integrations there, and execute it with `ai.preset_agent`.

    Use `ai.agent` when Tracecat workflow actions alone are enough.
    Use `ai.preset_agent` when the agent needs access to MCP servers in addition to regular Tracecat actions.
  </Accordion>
</AccordionGroup>
