> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Creating and configuring Agents

Create an Agent, configure its model, instructions, limits, and tools, then test it, publish it, and add it to a Product. For what Agents are and when to use them, see [What are Agents?](/user-guide/agents/what-are-agents).

## Create an Agent

To create an Agent, follow these steps:

1. In the sidebar, click **Agents** under **Products**.
2. On the **Agents** page, click **New agent**. The **Create New Agent** panel opens.
3. Select a starting point. To start without template content, click **Start with an empty agent**.
4. In **Name your agent**, enter a name.
5. For a template, select a model in **Model**. For an empty Agent, optionally enter a **Description**.
6. Click the create button, such as **Create AI Assistant** or **Create Agent**. The Agent editor opens.

The following table describes the starting points:

| Starting point                | What you get                                                                                                                                          |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **AI Assistant**              | A single response per message, with a **Persona template** for the system prompt. Use it for chat and Q\&A.                                           |
| **Autonomous Agent**          | A goal-oriented system prompt and an **Enable Agent Loop** option. Use it for multi-step tasks.                                                       |
| **Research Agent**            | The Exa and Firecrawl web tools attached, plus a research system prompt.                                                                              |
| **A2A Agent**                 | An external Agent that you connect over the A2A protocol. See [Connecting external agents](/user-guide/products-surfaces/connecting-external-agents). |
| **Start with an empty agent** | A name and description only. Configure the model, prompt, and tools in the editor.                                                                    |

You can also create an Agent from a [Product](/user-guide/products-surfaces/what-are-products). Open the Product. Click **Add Capability**, then click **New Agent**. This creates the Agent and adds it as a Capability.

### Create an Agent with the API

To create an Agent from code, send a `POST` request to `/v1/agents`. Only `name` is required. Put runtime settings, such as the model and system prompt, in `config`:

```bash
curl -X POST https://api.runtype.com/v1/agents \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support researcher",
    "description": "Answers order questions from the knowledge base",
    "config": {
      "model": "claude-sonnet-5",
      "systemPrompt": "You are a customer research Agent. Be thorough but concise.",
      "tools": { "maxToolCalls": 10 }
    }
  }'
```

Replace `YOUR_API_KEY` with a Runtype API key.

To change an Agent, send `PUT /v1/agents/AGENT_ID`. The request changes only the fields that you send, and Runtype merges `config` onto the stored configuration. To remove a value, send that field as `null`. The configuration fields in the rest of this page go in the same `config` object.

From the command line, run `runtype agents create --name "Support researcher"`. To keep Agent definitions in a repository, see [Manage agents as code](/user-guide/agents/manage-agents-as-code).

## Configure your Agent

The Agent editor shows the system prompt in the main area and groups the other settings into collapsible sections in a side panel. The sections that you see depend on the kind of Agent. For example, an A2A Agent has no **Model** section because its model is set where it's hosted.

### About

Use **About** to edit the Agent's description. To rename the Agent or change its icon, edit the name or icon at the top of the editor.

### Model

Select the model that generates responses and calls tools. If you need step-by-step logic that a [Flow](/user-guide/flows/what-are-flows) defines, attach that Flow to the Agent as a Flow tool so the model can call it. You can also run the Flow directly instead of routing it through an Agent.

Open the model's **Advanced settings** to set sampling parameters, **Max output tokens**, and, for models that support it, **Reasoning**. For the reasoning options of each provider, see [Reasoning](/user-guide/flows/using-prompt-steps#reasoning).

### System prompt

The system prompt defines the Agent's role, goals, constraints, and priorities. Describe the outcome that you want. Let the model choose the tool sequence when the path varies.

Use a system prompt such as the following:

*You are a customer research Agent. Your goal is to gather information about customer requests by searching knowledge bases, looking up order history, and analyzing previous interactions. Be thorough but concise. Prioritize recent information over historical data.*

The **AI Assistant** starting point offers the Helpful Assistant, Customer Support, and Technical Expert persona templates as a first draft.

### Temperature

Use **Temperature** in the model's **Advanced settings** to control variation in responses. Lower values produce more consistent output. Higher values produce more variation. The dashboard control accepts values from 0 to 1. To set a value up to 2, update the Agent through the API.

Some models, such as `claude-sonnet-5`, `gpt-5`, and `gpt-5-mini`, don't support Temperature. Runtype omits the setting when it runs those models.

### Safety

The **Safety** section controls tool approval, **Max tool calls**, and **Tool call strategy**.

**Tool approval** pauses execution before a tool runs and requires approval. Use it when a person must review an action before it happens. An approval request can include a short justification in **Agent's stated reason**. Treat this text as context, not as a system guarantee. Review the tool name and parameters before you approve the call.

When tool approval is on, choose a scope:

* **All tools**: Require approval for every tool call.
* **Only selected**: Require approval for selected attached tools and Capabilities.

Add a custom pattern in **Only selected**. Use a wildcard such as `mcp:*` or `builtin:*` to match every tool of that type. The same patterns work in dispatch requests and code. For dispatch overrides, see [dispatch-time approval overrides](/developer-guides/guides/runtime-tools#dispatch-time-approval-overrides).

Approval rules match tool names. Renaming a tool clears its rule. An empty selection turns off tool approval when you save. Select at least one tool before saving.

To offer remembered grants, turn on **Allow 'always allow'**. Supported approval interfaces then offer **Always allow**, **Allow once**, and **Deny**. When you select **Always allow**, Runtype remembers your decision. It skips the prompt for that tool on later runs. Authorization still applies. Tool access, ownership, and secrets don't change. The setting is off by default.

Slack and Telegram use channel approval prompts for Agent loop runs. These prompts offer one-time **Approve** and **Deny** choices. They don't offer **Always allow** or create a remembered approval.

SMS and iMessage have no approval buttons. For Agent loop runs on these Surfaces, reply to the approval question. Runtype adds a line with the exact tool and its parameters. It interprets your reply as an approval or a denial. Attach approval-required tools to an Agent loop Agent on an SMS or iMessage Surface to use reply-based approval. No additional setting is required.

For a Runtype Agent on Slack, Telegram, SMS, or iMessage, enable **Agent loop** and set **Max turns** to 2 or higher. A Claude Managed Agent always runs multi-turn, so it doesn't need **Agent loop** or **Max turns**. Telegram, SMS, and iMessage still require their Surface's inbound verification credential.

> **Warning**
>
> Reply-based approval uses free-form text, so a reply can be misinterpreted. A language model helps
> classify replies that don't match exact keywords. This creates a prompt-injection risk. Runtype
> checks exact keywords first. It limits the model result to approve, deny, or unclear. It doesn't
> treat unclear text as approval. It also excludes the Agent's own wording from this interpretation.
> For high-stakes tools, use a Surface with explicit approval controls. On SMS, reply `NO` to deny.
> `STOP` and `CANCEL` are carrier opt-out keywords. They can unsubscribe the number before Runtype
> receives the message. For details, see [Approvals on messaging surfaces](/user-guide/products-surfaces/approvals-on-messaging-surfaces).

Single-pass Agents on messaging Surfaces stop the approval-gated path without showing a prompt that the Surface can't resume. The same behavior applies to Surfaces without approval controls, such as email, WhatsApp, Discord, and generic messaging.

Unattended runs behave the same way and are refused before the Agent starts. Schedules, Batches, Evals, Webhooks, and API or JSON requests with no live caller have nobody to answer the prompt. Each one fails with an error naming the tool approval policy, and no gated tool runs. Turn off **Tool approval** (`tools.approval.require` in the API), or route the work through a Surface that can answer approvals.

Remembered approvals appear in the **Remembered approvals** card. Each entry shows the tool and its scope, such as a specific user or **All users**. Revoke an entry to show the approval prompt on the next run.

Set **Max tool calls** to limit tool calls in one turn. The dashboard control accepts values from 1 to 50. To set a value up to 100, update the Agent through the API.

**Tool call strategy** sets whether the model can, must, or must not call a tool on each step. Use **Auto (recommended)** for most Agents. **Required** forces a tool call on every step, so a multi-step run can't end with a text answer and returns empty output. For details, see [Tool call strategy](/user-guide/agents/agent-tools#tool-call-strategy).

### Agent loop

Enable **Agent loop** in the **Loop** section to let an execution take more than one turn. Each turn can include model reasoning, tool calls, and tool results.

When Agent loop is enabled, configure these settings:

* **Max turns**: The dashboard control sets values from 2 to 20. To set a value up to 100, update the Agent through the API. **Max turns** is a cap, not a target.
* **Reflection**: Enable periodic self-assessment and set the reflection interval.
* **Cost budget (USD)**: Set the maximum spend for one execution. The runtime stops the execution when it reaches this limit.

Within one turn, the model sees each tool result and can call more tools. The execution ends when the model finishes its turn with an answer. The loop starts another turn only in specific cases, such as when the turn reached **Max tool calls** or a Skill load added tools. For the full list, see [Tool call limits](/user-guide/agents/agent-tools#tool-call-limits).

Test with 5 to 10 max turns, then adjust the limit based on your results.

### Sandbox

The **Sandbox** section gives the Agent a Linux computer where it can run shell commands and edit files. To set it up, follow these steps:

1. In the **Sandbox** section, turn on **Linux computer**.
2. Click **Sandbox configuration**.
3. Set the options, then close the dialog and save the Agent.

The following options are available:

* **Persistence**: What survives between runs. **Conversation**, the default, keeps files across turns of a conversation. **Ephemeral** starts each run with a fresh machine.
* **Network access**: The outbound network that the machine can reach. **Essentials**, the default, allows package registries, OS mirrors, and GitHub. **None** blocks outbound traffic. **Unlimited** allows any host, so an Agent under prompt injection could send data anywhere. Use **Unlimited** only for trusted workloads.
* **Sleep after**: The idle time before the machine pauses. The default is 15 minutes. Resuming restores files.
* **Retention**: How long an idle machine is kept before Runtype deletes it. The default is 1 hour.

When the sandbox is on, Runtype adds the sandbox tools to the Agent, such as `bash`, `read_file`, and `write_file`. For the full list, see [Agent Sandbox tools](/user-guide/tools/built-in-tools#agent-sandbox-tools).

In the API, the sandbox is `config.sandbox`. The API also accepts these fields, which the dashboard doesn't show:

* `networkAccess.allow`: A custom list of allowed hostnames, combined with a `networkAccess.profile`.
* `setupCommands`: Commands that run once when the machine starts.
* `secretEnv`: Environment variables whose values are managed secret keys. You can set up to 32 variables. `RUNTYPE_SECRET_COMMAND` is reserved.
* `codingAgents`: Set to `["opencode"]` to let the Agent run opencode inside the sandbox as a typed session. This adds the tools described in [Coding-agent sessions](/user-guide/tools/built-in-tools#coding-agent-sessions).

The sandbox runs on the `runtype-sandbox` provider with the `standard-4` instance size. If you enable a configuration with another provider, instance size, or persistence value, Runtype returns an `unsupported_sandbox_capability` error that names the field and the supported values. If a saved Agent already has an unsupported value, the **Sandbox** section shows **Sandbox needs configuration**. Choose supported settings or turn off **Linux computer** before you run the Agent.

### Context compaction

Context compaction keeps long conversations within the model's context window. It's enabled by default. Before model calls, Runtype first reduces older tool output. When needed, it then condenses older conversation content. The stored transcript is not rewritten.

The model receives a smaller view, so summaries can omit detail. Keep critical requirements in the Agent's instructions rather than relying only on earlier messages.

To configure compaction in the dashboard, open the **Context** section:

* **Condense long conversations**: Turn compaction on or off.
* **Strategy**: Select **Automatic**, **Provider native**, or **Summary**.
* **Condense at**: Enter a percentage of the usable context budget, such as `85`. A value in **Or condense at a fixed input-token count** overrides the percentage.
* **Recent tokens kept in full**: Set how much recent content stays unsummarized.
* **Summary instructions**: Describe what the summary must preserve.

Clearing a numeric field restores its displayed default. Settings that you don't change keep following platform defaults. **Test agent** uses your current edits, even before you save.

The model receives every new tool result in full. The separate **Tool results** controls govern masking of older results. **Keep every result** turns off masking only. It doesn't turn off conversation compaction, and the compaction toggle doesn't change the tool-result settings.

In the API, set `contextManagement.compaction` in the Agent configuration:

```json
{
  "contextManagement": {
    "compaction": {
      "enabled": true,
      "strategy": "auto",
      "thresholdRatio": 0.85,
      "retainRecentTokens": 8000,
      "instructions": "Preserve decisions, unresolved questions, and artifact references."
    }
  }
}
```

To override compaction for one execution, send the same `contextManagement` object in the body of `POST /v1/agents/AGENT_ID/execute`.

The fields behave as follows:

* `enabled: false` prevents new compaction. An existing valid conversation summary stays in use, so turning off compaction doesn't restore summarized history to the model. Tool-output masking stays on.
* `strategy: "auto"` uses provider-native compaction only when both the model provider and the Surface support native history. Otherwise, it uses a summary that the Agent's model generates. Text-only messaging Surfaces use summaries even with a native-capable model. `"summary"` selects summarization explicitly. `"provider_native"` also falls back to summarization when the provider or Surface can't preserve native history.
* `thresholdRatio` controls when compaction starts, relative to the usable context budget. `thresholdTokens` sets an absolute token threshold instead. Triggering earlier leaves more room for new input, tool output, and the model's answer.
* `retainRecentTokens` controls the recent content kept alongside a summary.
* `instructions` adds guidance for the summarizer. The summarizer uses the Agent's model.

Summary generation adds model calls, latency, and token usage. These calls count toward execution cost and the Agent loop's cost budget. If a provider rejects the first request for exceeding its context window before any output streams, Runtype can compact and retry once. Recovery can still fail. Reduce the input or trigger compaction earlier rather than assuming an unlimited conversation fits.

The streaming `context_notice` event reports compaction activity. It's informational, not assistant text or an execution-completion event. Compaction manages the current conversation's model context. It's separate from [Memory](#memory), which stores information across conversations.

### Busy-message routing

A client can send a message with automatic routing while the Agent is still running a turn. A classifier then decides whether the message joins the running turn or queues as the next turn. The Agent's `busyMessageRouting` configuration controls that classifier.

Configure these fields:

* `mode`: Set to `enforced` (the default) to route by the decision, or `off` to queue every such message without a classifier call. With `off`, the response reports the source as `disabled`.
* `classifierModel`: Set the decision model that classifies the message. Use an `id` from `GET /v1/decision-models`; Runtype rejects any other value when you save the agent. It defaults to Jev (`typesafe-ai/jev`).

Runtype bills each classifier call to your organization. For the request options and the routing decision in each response, see [Route a busy message automatically](/developer-guides/guides/busy-message-auto-routing).

### Memory

Memory stores information across conversations. When memory is on, Runtype adds three memory tools: `save_memory`, `recall_memory`, and `memory_summary`. Runtype also records each user and assistant exchange in the background. The Agent can use these tools to recall facts from earlier conversations.

To turn on memory in the dashboard, follow these steps:

1. In the **Memory** section, turn on **Long-term memory**.
2. Click **Memory configuration**.
3. In **Memory scope**, select **Shared by this agent**, **Per end user**, **Per Runtype user**, or **Custom template**.
4. Optional: Turn off **Inject memory summary** to omit the profile summary from the prompt.

In the API, set these fields in the Agent's `memory` configuration:

* `enabled`: Set this field to `true` to turn on memory. The three memory tools become available automatically. Don't add them to the Tools list.
* `profileTemplate`: Set the profile scope that each execution reads and writes. **Memory scope** sets this field. If you omit it, a saved Agent uses its own ID, `{{_agent.id}}`, which creates one shared bucket per Agent. Use `{{_user.id}}` for a Runtype account. Use `{{_tenant.id}}` for a Product Tenant, which is a company or workspace shared by its users. Use `{{_endUser.id}}` for an individual SaaS end user.
* `injectSummary`: **Inject memory summary** sets this field. It defaults to `true` when memory is on, and Runtype adds a profile summary to the system prompt on each turn. Set it to `false` for task Agents that don't need a profile overview.
* `pointerScope`: This field applies only to Agents that set a `tenancyStrategy`, where Runtype computes the namespace and ignores `profileTemplate`. Set it to `"alias"` or `"version"` to give each release alias or each version its own bucket. It defaults to `"shared"`. On an Agent without a Tenancy Strategy, the field does nothing and validation reports `MEMORY_POINTER_SCOPE_IGNORED`. Key the template instead.

The `profileTemplate` resolves these variables:

| Variable               | Description                                                                                                                                        |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{_agent.id}}`        | The Agent's own ID, which is the default template                                                                                                  |
| `{{_user.id}}`         | The Runtype account that owns the execution                                                                                                        |
| `{{_organization.id}}` | That account's organization                                                                                                                        |
| `{{_endUser.id}}`      | The end user passed on the request, for per-end-user memory                                                                                        |
| `{{_tenant.id}}`       | The Product Tenant passed on the request, for memory shared by that tenant's end users                                                             |
| `{{_agent.alias}}`     | The release alias this execution resolved through, such as `live` or `pr-482`                                                                      |
| `{{_agent.versionId}}` | The immutable version this execution is pinned to                                                                                                  |
| `{{_agent.version}}`   | That version's human label, when it has one. Display only: free text, not unique, and absent on an unlabelled version, so never key a bucket on it |

The three release-pointer variables are absent on an execution that named no version selector. `{{_agent.alias}}` is also absent when the request pinned a bare `versionId`. Give any reference to them a fallback, such as `{{_agent.alias || "live"}}`, or memory switches off on those runs. By default, a new version, a preview alias, and a pinned version all share one bucket. For when to key memory by the pointer, see [Memory namespaces and release pointers](/user-guide/agents/agent-versioning-and-publishing#memory-namespaces-and-release-pointers).

The injected summary includes standing preferences, recent decisions, and active tasks. Runtype caches the summary per profile, so it generates the summary once per profile.

If a `profileTemplate` variable can't be resolved at run time, Runtype turns off memory for that execution and logs a warning. It doesn't fall back to a shared bucket.

To override memory for one dispatch, include `memory` in the `agentInput` of a `/v1/dispatch` request. The per-call `memory` object accepts `enabled`, `profileTemplate`, `injectSummary`, and `pointerScope`. Use this option when you know the end-user identity only at dispatch time, or to send a CI run to its own bucket without editing the Agent. `pointerScope` matters here only when the saved Agent sets a `tenancyStrategy`. On any other Agent, override `profileTemplate` instead.

An inline dispatch Agent without a saved Agent ID must set an explicit `profileTemplate`. Without a saved Agent, Runtype can't select a per-Agent default profile, so memory stays off until you set a profile scope.

Memory applies to Runtype Agents. Claude Managed Agents use Claude's native memory, so the `memory` configuration has no effect on them.

### Temporal awareness

Models don't receive the current time or elapsed-time context by default. The Agent's `temporal` configuration adds three opt-in capabilities: a default time zone for the [temporal tools](/user-guide/tools/built-in-tools#temporal-tools), the current date and time on every message, and an elapsed-time notice between messages. Set it through the API, or as the `temporal` override of a `POST /v1/dispatch` request.

Configure these fields:

* `timezone`: Set the Agent's default Internet Assigned Numbers Authority (IANA) time zone, such as `America/New_York`. Temporal tools use it when no explicit time zone is passed. They also use it when the conversation has no stored time zone.
* `injectElapsed`: Set this field to `true` to add a short "time has passed" notice at the start of a turn after a gap. The notice applies inside a conversation from the second message onward, and only where Runtype stores the conversation: messaging, Persona and client chat, AG-UI, voice, and `history: "stored"` requests. A request that sends its own message history has no stored previous message, so it gets no notice.
* `elapsedThresholdSeconds`: Set the minimum gap, in seconds, before Runtype adds the notice. The default is 30. Set it to `300` to annotate only gaps of several minutes.
* `groundNow`: Set this field to `true` to add the current date, time, and day of the week, in the resolved time zone, to every message, including the first one. It doesn't need `injectElapsed`. When both are on and the gap is longer than the threshold, the current time is added to the elapsed-time notice, so the message gets one notice.

Runtype resolves the time zone in this order: the conversation's stored time zone, the Agent's default `timezone`, and UTC.

The notices go only to the model. Stored transcripts, execution logs, and Agent memory keep each message as the user wrote it. These settings apply on every hosted surface that runs the Agent, including an `execute-agent` Flow step and a subagent. A call with no previous turn, such as a Flow step, gets the current time when `groundNow` is on, and never gets an elapsed-time notice. One place still rejects an Agent with a `temporal` block: a detached subagent tool run by the self-hosted runtime.

### Logging

Use **Verbose logging** in the **Logging** section to control whether runs store token counts, cost, and full outputs. Select one of the following values:

* **Default**: Inherit the setting of the Surface or Product that runs the Agent.
* **On**: Store full detail for every run.
* **Off**: Don't store full outputs, token counts, or cost.

For what logs show, see [What are Logs?](/user-guide/logs/what-are-logs).

### Error handling

The **Error handling** section controls what happens when the model fails or returns no text. If you don't configure it, the Agent retries the model twice, after 5 seconds and then after 10 seconds, and then fails.

To change it, click **Configure** in the section and choose one mode:

* **Continue on error**: Skip the failure and continue the execution.
* **Stop on error**: Stop the execution when the model fails.
* **Use fallbacks**: Try alternatives before the execution stops.

Configure a fallback chain when you choose **Use fallbacks**. Runtype tries each fallback in order until one succeeds. Use these fallback types:

* **Retry**: Run the same model again.
* **Different model**: Switch to a backup model and optionally override `temperature` and `maxTokens`.
* **Fixed message**: Return a predefined reply without calling a model.

A **Retry** or **Different model** fallback accepts an optional **Delay**, in milliseconds, before it runs. The maximum is 60,000.

A fallback never runs a tool twice. If the failed attempt already called a tool, **Retry** reuses the recorded results of those calls instead of calling the tools again. Runtype does this for multi-turn Agents. When Runtype cannot reuse the results, it skips the **Retry** fallback. It always skips a **Different model** fallback, because a different model can make different calls. Runtype then moves to the next fallback, or the execution fails with the original error. Tools marked `idempotent` do not count as a tool call here.

Select what triggers the fallback chain. Select **The step errors** when the model fails with a provider error, timeout, or thrown failure. Select **The reply is empty** when the model finishes without an error but returns no visible text. You can select both triggers.

### Skills

Use the **Skills** section to attach Agent Skills, which are instruction bundles that the Agent loads when a task needs them. For details, see [Agent Skills](/user-guide/agents/agent-skills).

## Add tools

The model selects tools from the attached set based on the task, so you don't script the order. To attach tools, click **Add tool** in the Agent editor. For each tool type, the attach procedure, and how to write tool descriptions, see [Agent tools](/user-guide/agents/agent-tools).

Two editor sections change how the Agent uses its tools:

* **Subagents**: Turn on **Dynamic spawning** to let the Agent delegate focused tasks to child Agents that it creates at run time. To attach saved Agents as subagents instead, see [Subagent tools](/user-guide/agents/agent-tools#subagent-tools).
* **Code mode**: Turn on **Code execution** to let the Agent call several tools from one sandboxed JavaScript program. See [Code mode](/user-guide/agents/agent-tools#code-mode).

## Test your Agent

To test your Agent, follow these steps:

1. In the Agent editor, click **Test agent**. The test panel opens.
2. Optional: In **Target**, choose what to run. The default, **Draft (unsaved)**, runs your current edits. You can also run a release alias, such as **Live**, or a saved version.
3. Enter a test message or goal, and send it. The response appears in the panel.

The test panel shows tool calls and tool results. Use these details to tune the system prompt, tool selection, and loop settings.

A test run is stored with its full transcript, so it appears in the Runs list and in Logs like a production run, tagged as a dashboard run.

Test realistic inputs, including edge cases. To test from code, send `POST /v1/agents/AGENT_ID/execute` with a `messages` array.

## Save and publish your Agent

Click **Save version** to save your changes as a version of the Agent. Saving doesn't always change what production traffic runs. To publish, open the save options menu next to the button and click **Save & publish**. If your changes are already saved, the item reads **Publish to live**. To publish every save, select **Publish on save** in the same menu. The button then reads **Save & publish**.

Whether a save or a publish changes what your Surfaces run depends on your organization's settings. For details, see [Agent versioning and publishing](/user-guide/agents/agent-versioning-and-publishing).

## Add your Agent to a Product

After you configure and test an Agent, add it to a Product so people can use it through connected Surfaces. To add it, follow these steps:

1. Open your **Product**.
2. Click **Add Capability**.
3. Select your Agent.
4. Click **Add Capability** to finish.

For more detail on Capabilities in a Product, see [Adding capabilities to a product](/user-guide/products-surfaces/adding-capabilities-to-a-product).

After you add the Agent, it's available through any Surface connected to that Product, including chat, the API, and Model Context Protocol (MCP) Surfaces.

## Best practices

Use these practices when you configure an Agent:

* **Start with a template.** Use a starting point, then tailor it to your use case.
* **Keep tools focused.** Start with two or three tools. Add more when the task requires them. Fewer, well-described tools reduce ambiguity during selection.
* **Write clear instructions.** State the goals and constraints in the system prompt.
* **Test iteratively.** Try varied inputs and refine the Agent based on the results.
* **Use Agent loop thoughtfully.** Turn it on when the task needs multiple rounds. Set a **Max turns** limit and a **Cost budget (USD)**.

## Next steps

Continue with these guides:

* [Agent versioning and publishing](/user-guide/agents/agent-versioning-and-publishing): manage drafts and published versions, and return to an earlier configuration.
* [Agent tools](/user-guide/agents/agent-tools): configure tool types, descriptions, and subagent delegation.
* [Agent Skills](/user-guide/agents/agent-skills): give the Agent loadable instructions for specific tasks.
* [Manage agents as code](/user-guide/agents/manage-agents-as-code): keep Agent definitions in your repository and converge them at deploy time.
* [What are Surfaces?](/user-guide/products-surfaces/what-are-surfaces): connect Agents to user-facing channels.
* [Tool approvals](/user-guide/tools/tool-approvals): require approval before a tool runs, and approve or resume from the API.
* [Agent execution failures](/user-guide/troubleshooting-faq/agent-execution-failures): diagnose failed Agent runs, stop reasons, and tool errors.