Cereal docs
Tools and integrations

Third-party MCP servers and secrets

Naming a server you do not host, and the credential it authenticates with.

An agent may call an MCP server Cereal does not host and cannot sign for: Linear, Notion, whatever your team already runs. Declare it inline in the definition.

defineAgent({
  agent: { /* … */ },
  mcpServers: [
    {
      name: "linear",
      url: "https://mcp.linear.app/mcp",
      auth: { type: "bearer", secret: "linear-token" },
      allow: ["list_issues", "create_issue"]
    }
  ]
})

Equivalently, in a raw definition:

{ "type": "mcp", "name": "linear", "url": "https://mcp.linear.app/mcp",
  "auth": { "type": "bearer", "secret": "linear-token" },
  "allow": ["list_issues"] }

auth.secret is a name, never a value

The agent definition is versioned, immutable and committed to your repository. A credential has no business being in one. Register the value once, out of band:

await client.secrets.upsert({
  secret: {
    name: "linear-token",
    value: process.env.LINEAR_TOKEN!,
    description: "Linear MCP, workspace-level token"
  }
})

await client.secrets.list()          // names, descriptions and two timestamps, never a value
await client.secrets.delete({ id })   // refused while an agent version still names it

The API has no endpoint that returns a secret's value, so the control plane's Secrets page is a table of names. Rotating one is another upsert.

agent.init() verifies that every named secret exists and refuses to write a version when one does not, naming the missing ones. It never creates them, and a secret value never passes through a definition in source code.

A name that does not resolve at connect time is a ConnectionError. The turn records it as a session.error and continues without those tools rather than failing.

Authentication

Inline servers use their configured authentication, such as a stored bearer token. For your own tool handlers, use the signed MCP connection registered by sync().

Per-user credentials

auth: { type: "bearer" } is one credential for the whole environment. When the server should act as the person the session is for instead, register it as a connection with auth: { type: "oauth" }. See per-user OAuth.

On this page