Cereal docs
Get started

Agent definition

Define the model, instructions, tools, and policies once, in TypeScript or JSON.

An agent definition is the configuration Cereal uses to run an agent. It describes which model to call, what instructions to follow, which tools are available, and what rules govern execution. You can author it in TypeScript or send JSON over HTTP.

Cereal stores each changed definition as a version. A session pins one version when it starts, so updating the agent affects new sessions. Your application continues to host its custom tool code on your existing server or serverless platform.

One definition, two ways to write it

These examples register the same agent. First register a provider named primary with your own model key and select a model available to that account. The example uses Anthropic; a different supported provider changes only model.

agent.ts
import { createCerealClient, defineAgent } from "@trycereal/sdk"

export const research = defineAgent({
  agent: {
    slug: "research",
    name: "Research",
    model: { provider: "primary", model: "claude-sonnet-4.6" },
    system: "Research the question and cite the evidence. Ask for missing details.",
    policies: {},
    limits: { maxTurns: 12 }
  }
})

// Uses CEREAL_API_KEY with control scope.
const client = createCerealClient({})
await client.agents.upsert({ slug: research.slug, definition: research.definition() })

The SDK fills in tools: []. research.definition() returns the JSON document sent to Cereal. It does not include slug, which identifies the agent in the upsert request. See SDK setup if you have not installed the repository SDK.

The HTTP definition requires name, model, system, tools, policies, and limits. Use [] for no tools and {} for default policies and limits. The TypeScript authoring helper supplies those empty values and defaults name to the slug when omitted.

The parts of an agent

FieldWhat it controlsDetails
name, descriptionThe agent's display name and optional description.The slug belongs to the registration request.
modelA registered provider name, model ID, reasoning level, and optional fallback models.Providers, reasoning, fallback
systemInstructions used across the agent's sessions.Keep customer-specific context in session inputs.
toolsMCP connections, inline MCP servers, and provider tools.Connect tools
policiesWhich tool calls run, wait for approval, or are denied; approval expiry.Approvals
limitsModel-step and session token limits. maxTurns caps model steps within a turn.Usage and budgets
toolLoadingWhen tool schemas are loaded into context.Deferred tools
compactionWhen long context is compacted and what recent messages are kept.Context and caching
overridesWhich instructions, model settings, and tools a session may change.Session overrides
identityWhether a session must identify the user or system it acts for.Application identity
sandboxA managed workspace, image, resources, lifecycle, and available sandbox tools.Sandboxes
subagents, subagentPolicyOther agents it may delegate to and limits on their work.Sub-agents
experiment, evaluatorsVariant assignment and evaluation configuration.Experiments and evaluations

See the AgentDefinition schema for every nested field and allowed value. Model credentials are stored in providers, separately from the agent. Session messages, metadata, and the current user's identity are inputs to each session, rather than properties to hard-code in the reusable definition.

Connect the definition to your tools

A tool definition tells Cereal how to reach a capability. The tool's implementation runs in your application or the service you connect. For an existing MCP connection named sources, add this entry to the definition's tools array:

{ "type": "mcp", "connection": "sources", "allow": ["read_source"] }

With TypeScript, defineAgent({ agent: { ... }, tools: [tool({ ... })] }) keeps handlers beside the agent configuration. Its definition() adds an MCP connection entry for those handlers. Agent actions initialize the connection and definition on first use; agent.init() does this early, and sync() explicitly registers configuration. Mount agent.fetch or agent.handlers in your app. Use configureCereal({ publicUrl }) or CEREAL_PUBLIC_URL for your app's HTTPS origin. See write tools in TypeScript for the complete example.

Provider tools run with the model provider. Sandbox tools run in Cereal-managed sandboxes. Adding a sandbox makes its permitted tools available without hosting a machine in your application.

How a session uses the definition

  1. Your app creates a session and supplies its first message, optional metadata, and authenticated user identity. Cereal pins the agent version and validates overrides.
  2. Cereal sends the instructions, conversation context, and available tool schemas to the configured model provider.
  3. When the model requests a tool, Cereal checks the tool policy. It executes an allowed call, waits for a decision, or returns a denial.
  4. The tool result returns to the model. Cereal records the work and continues until the model finishes, a limit is reached, or the session needs an external action.
  5. Your app reads the response and status through the API or session stream. A later message starts another turn in the same session.

Cereal keeps this work independent of your app's request lifetime. Your app remains responsible for authenticating users and authorizing access to its data and sessions. See sessions and turns for lifecycle and recovery behavior.

Versions

agents.upsert finds an agent by slug and creates a version only when the definition changes. agents.update can require an expected version to prevent overwriting a concurrent edit:

await client.agents.get({ id: agentId })
await client.agents.versions({ id: agentId })
await client.agents.update({ id: agentId, definition, expectedVersion: 7 })

A mismatch returns VersionConflict. Existing sessions retain their pinned definition. Versioning does not freeze the code behind a tool URL; keep that code compatible or use versioned callback URLs for breaking changes.

An agent with a sandbox must finish its image build before a session can start. Check agents.imageStatus({ id: agentId }); baking means wait, and failed means inspect the build error. Starting early returns AgentNotReady. agents.rebake rebuilds the latest image without creating a definition version.

Reasoning

model.reasoning accepts none, minimal, low, medium, high, or max. Support depends on the provider and model. If the adapter cannot represent a level, it omits that option. The effective setting appears in model.request.started.

Fallback

Add a fallback list when another model should handle a failed request:

model: {
  provider: "primary",
  model: "claude-sonnet-4.6",
  fallback: {
    models: [{ model: "claude-haiku-4.6" }],
    on: ["unavailable", "rate_limited", "timeout", "server_error"]
  }
}

A fallback inherits the primary provider and reasoning unless it supplies its own. Cereal retries the current model before moving to the next one. Errors outside the configured reasons fail the turn. Each attempt appears separately in the trace.

Deployments

Code-defined agents register in the environment bound to CEREAL_API_KEY when the SDK initializes. Deploy your application with the appropriate key for each environment. See deployment. Agents managed in the console can be copied to another environment.

On this page