A subagent is a named, separately configured agent that the main agent can delegate a task to. Each subagent has its own system prompt, tools, and tool-approval policy, and it runs in isolation — the main agent sees only its final answer.
Use a subagent when part of a job needs a different set of instructions or a different tool surface than the main agent: a contract reviewer with a legal prompt and read-only access, a form filler restricted to a single Model Context Protocol (MCP) server, or a researcher that may only search.
Overview
Subagents are configured with the subagents field. Each entry either defines an inline agent configuration with a name and a description or references a saved agent by its agentId:
{ "subagents": [ { "name": "contract-reviewer", "description": "Reviews contracts for key terms, dates and liability clauses.", "systemPromptTemplate": "You are a contract specialist. Cite the clause number for every finding." } ]}Send the configuration in context with the agent run request:
{ "assistant_id": "agentic", "input": { "messages": [{ "role": "user", "content": "Review clause 4 of the lease." }] }, "context": { "subagents": [{ "name": "contract-reviewer", "description": "Reviews contracts." }] }}The main agent uses each subagent’s description to choose the right specialist for a task. Make each description specific about what the subagent should handle.
Configuration schema
interface SubagentConfiguration { name: string // Required. 1–64 chars, /^[a-zA-Z0-9_-]+$/ description: string // Required. 1–500 chars. Shown to the main agent.
systemPromptTemplate?: string // The subagent's own instructions. seedMessages?: SeedMessages // Messages injected on every model call. mcps?: MCPServerConfig[] // The subagent's own MCP servers. skills?: Skill[] // The subagent's own skills. toolApproval?: ToolApproval // The subagent's own approval policy. toolCalling?: "direct" | "code" // The subagent's own tool-calling mode. responseSchema?: object // JSON Schema for the subagent's answer. modelServices?: ModelServicesInput // Run this subagent on a different model than the main agent.}
interface SubagentReferenceConfiguration { agentId: string // Required. ID of the saved agent. name: string // Required. 1–64 chars, /^[a-zA-Z0-9_-]+$/ description?: string // Uses the saved agent's description when omitted.}
type SubagentEntry = SubagentConfiguration | SubagentReferenceConfigurationAn inline subagent contains its configuration directly in the request. A reference instead loads a saved agent from the agent catalog:
{ "subagents": [ { "agentId": "saved-contract-reviewer", "name": "contract-reviewer", "description": "Reviews contracts for key terms and liability clauses." } ]}Every reference requires a name. You can omit description when the saved agent already defines one. To change other fields, update the saved agent or define the subagent inline.
A subagent may declare its own modelServices to use a different model from the main agent. For example, a fast model can summarize pages, while a more capable model handles complex review. When modelServices is omitted, the subagent inherits the main agent’s model configuration.
An inline subagent can’t declare subagents of its own. However, a referenced saved agent may have its own saved subagents, allowing bounded delegation trees. For example, save contract-team with a reference to clause-reviewer:
{ "subagents": [ { "agentId": "saved-clause-reviewer", "name": "clause-reviewer" } ]}The main agent can then reference contract-team:
{ "subagents": [ { "agentId": "saved-contract-team", "name": "contract-team" } ]}This creates the delegation path main agent → contract-team → clause-reviewer. See limits.
Inheritance
A subagent inherits every field it doesn’t declare. A subagent that declares only a name, a description, and a prompt is the main agent with different instructions — same tools, same MCP servers, same approval policy, same model.
Referenced saved agents follow the same inheritance rules: their declared fields replace inherited values, while omitted fields come from the parent agent. Configure fields such as toolApproval explicitly when a saved agent needs a different policy.
{ "mcps": [{ "transport": "inmemory", "name": "nutrient-ai-assistant" }], "toolApproval": { "defaults": { "default": "allow", "write": "ask" } }, "subagents": [ { "name": "contract-reviewer", "description": "Reviews contracts.", "systemPromptTemplate": "You are a contract specialist." } ]}Here contract-reviewer gets the main agent’s mcps and its toolApproval — writes still require approval inside the subagent — and only the prompt differs.
Declaring a field replaces the inherited value; it doesn’t merge with it. A subagent that declares mcps gets only the servers it lists:
{ "mcps": [ { "transport": "inmemory", "name": "nutrient-ai-assistant" }, { "transport": "inmemory", "name": "document-engine" } ], "subagents": [ { "name": "researcher", "description": "Searches documents. Cannot modify them.", "mcps": [{ "transport": "inmemory", "name": "nutrient-ai-assistant" }], "toolApproval": { "defaults": { "default": "deny", "read": "allow" } } } ]}researcher can reach only the nutrient-ai-assistant server, and only its read tools — regardless of what the main agent is allowed to do.
nutrient-ai-assistant and document-engine are Nutrient’s built-in MCP servers. List the built-in servers a subagent can use with the inmemory transport. To connect an external MCP server, use the http transport described in MCP servers.
responseSchema is an exception to inheritance. Declare it on the subagent when its answer must use structured output; otherwise, the subagent returns text.
Delegation behavior
The main agent delegates tasks based on the available subagent names and descriptions. After a subagent finishes, the main agent uses its answer to continue the run and respond to the user.
Only the subagent’s final answer is returned to the main agent. Intermediate steps and tool calls aren’t streamed to the client.
Tool approval inside a subagent
A subagent’s tools use its toolApproval configuration, inherited from the main agent, unless the subagent declares its own. The modes match the main agent’s tool approval modes:
allow— The subagent’s tool runs automatically.ask— The run pauses and presents the approval through the main run.deny— The tool is never surfaced to the subagent’s model.defer— The tool is made available only when it’s relevant to the turn.
Because approval is inherited, a subagent that declares no policy of its own doesn’t escape the main agent’s policy:
{ "toolApproval": { "defaults": { "default": "allow", "write": "ask" } }, "subagents": [{ "name": "form-filler", "description": "Fills form fields." }]}form-filler inherits write: "ask", so a form-field write inside the subagent still pauses for approval.
To give a subagent a stricter policy than the main agent, declare one:
{ "toolApproval": { "defaults": { "default": "allow" } }, "subagents": [ { "name": "researcher", "description": "Read-only research.", "toolApproval": { "defaults": { "default": "deny", "read": "allow" } } } ]}Examples
A specialist with the same tools
Different instructions, everything else inherited. This is the most common shape.
{ "subagents": [ { "name": "summarizer", "description": "Produces a one-paragraph summary of a document.", "systemPromptTemplate": "Summarize in one paragraph. No preamble, no bullet points." } ]}A saved agent by reference
Reference an agent from the agent catalog instead of repeating its configuration inline:
{ "subagents": [ { "agentId": "saved-contract-reviewer", "name": "contract-reviewer" } ]}Here, the main agent exposes the saved agent as contract-reviewer. Because the reference omits description, the saved agent must provide one.
A subagent with restricted tools
Declare mcps and toolApproval to give a subagent a restricted tool set and policy:
{ "subagents": [ { "name": "external-lookup", "description": "Looks up counterparties in the company registry.", "systemPromptTemplate": "Use the registry to resolve company names to registration numbers.", "mcps": [ { "transport": "http", "name": "registry", "url": "https://registry.example.com/mcp" } ], "toolApproval": { "defaults": { "default": "deny", "read": "allow" } } } ]}A cheap subagent alongside an expensive one
Each subagent declares its own modelServices, so a fast model handles routine summarization, while a stronger model handles complex review:
{ "subagents": [ { "name": "summarizer", "description": "Produces a one-paragraph summary of a document section.", "systemPromptTemplate": "Summarize in one paragraph. No preamble, no bullet points.", "modelServices": { "models": [{ "labels": ["default-llm"], "model": "openai:gpt-4o-mini" }] } }, { "name": "reviewer", "description": "Reviews contracts for liability exposure and non-standard terms.", "systemPromptTemplate": "You are a senior contract reviewer. Flag every non-standard clause with a risk rating.", "modelServices": { "models": [{ "labels": ["default-llm"], "model": "openai:gpt-4o" }] } } ]}A subagent with structured output
Declare responseSchema on the subagent to require a structured answer instead of free text:
{ "subagents": [ { "name": "clause-extractor", "description": "Extracts clause numbers and their risk level.", "responseSchema": { "type": "object", "properties": { "clauses": { "type": "array", "items": { "type": "object", "properties": { "number": { "type": "string" }, "risk": { "type": "string", "enum": ["low", "medium", "high"] } }, "required": ["number", "risk"] } } }, "required": ["clauses"] } } ]}Limits
- Subagent names must be unique within the configuration. Don’t use the reserved name
discover_tools. - An inline subagent can’t set
modelOverridesoruserId. - An inline subagent can’t declare
subagents. - A referenced saved agent may contain its own
subagents. References can be nested up to five levels, with up to 64 subagents in a run. Circular references aren’t supported. toolCalling: "code"can’t be combined withsubagents.- A subagent that uses
toolCalling: "code"can’t useaskordefertool approval. - Only the subagent’s final answer is available to the main agent and client.
- A subagent is part of the main agent’s run and can’t be resumed independently.
toolCalling: "code" and subagents are mutually exclusive. A configuration that sets both is rejected at startup.
What’s next
- Agents — Choose the built-in agent the subagents delegate from.
- Agent configuration — Configure the shared fields a subagent inherits or overrides.