Skip to content

How the Agent SDK works

An agent is a folder of instructions and capabilities. The Agent SDK discovers those files, runs conversations, and records what happened.

What happens when someone sends a message?

Follow one message through the system:

  1. A channel receives the message from HTTP, Slack, GitHub, or another webhook.
  2. The channel starts a session or continues an existing one.
  3. The runtime gives the model its instructions, tools, and workspace.
  4. The model replies and can call tools along the way.
  5. The Agent SDK appends every message and tool call to the session's event stream.

The channel is the front door. The runtime does the work. The event stream is the record you inspect later.

How do files become an agent?

Each capability has a home in the project. The path tells the Agent SDK what to load. The filename becomes the capability's name. For example, agent/tools/get_weather.ts creates a tool named get_weather.

PathWhat it is
agent/agent.tsModel and runtime settings
agent/instructions.mdThe always-on system prompt
agent/tools/<name>.tsTyped actions the model can call
agent/skills/*Procedures loaded when needed
agent/mcp-connections/<name>.tsTools from external MCP servers
agent/channels/*.tsHTTP, Slack, and GitHub entry points
agent/ab.ts or agent/ab/*.tsSticky variants and live performance metrics
evals/**/*.eval.tsRepeatable checks at the project root

Other folders add subagents, hooks, schedules, and workspace files. You don't register them elsewhere. Run agent-sdk validate to catch invalid files before serving the project.

See Project layout for every supported path.

How does the Agent SDK identify a conversation?

A session is one durable conversation. It has two identifiers:

  • continuationToken tells a channel which conversation to resume. A Slack channel can use its thread ID. A GitHub channel can use the pull request. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up.
  • sessionId identifies the stored session. Use it to stream events, inspect the session, resolve approvals, or bind a tool call to the session.

Use the continuation token to keep talking. Use the session ID to observe or manage the conversation.

How do I see what an agent did?

Each session writes an append-only NDJSON file: sessions/<id>/events.ndjson. It includes:

  • Messages and streamed text
  • Requested tool calls and their results
  • Approval requests and decisions
  • Turn completion and token usage

Sessions and their event streams survive server restarts. The playground renders the stream. Evals assert against it. The agent-sdk trajectory command turns a saved stream into a short summary.

When a run surprises you, inspect its event stream first. See Sessions and streaming for every event.

What does a channel control?

A channel connects the agent to a surface such as HTTP, Slack, GitHub, or a custom webhook. It controls:

  • Routes and input schemas
  • Authentication
  • Conversation identity
  • How replies return to the user

The built-in HTTP session API is always available. Custom routes accept loopback callers by default. Add an auth policy before sharing them over a network.

Channels should also prepare deterministic input for the model. For example, a GitHub channel can fetch the pull request, collect the diff, and seed the workspace before the turn starts. The model can then focus on the review instead of gathering files.

See Channels for route and authentication details.

Where does a turn run?

Choose a runtime in agent/agent.ts:

Local (default)Cloud
Turn runs onThe server hostA Cursor cloud agent
Server toolsSupportedSupported when the server has --public-url or --cloud-tools-url; the cloud turn reaches them over authenticated HTTP MCP. Without one of those flags, the server warns and cloud turns omit them.
Approvals (needsApproval)SupportedNot supported (local runtime only)
Agent tool scriptsSupportedSupported
Skills and seeded filesAdded to the session workspaceMust exist in the cloud repository
RepositoryYou provide itThe cloud agent checks it out

Use the local runtime when the host has the tools and files the agent needs. Use the cloud runtime when each turn needs an isolated repository checkout. agent-sdk validate warns when a cloud agent uses a local-only capability.

See Cloud runtime for setup and trade-offs.

What files can a local session access?

Each local session gets its own workspace. The Agent SDK writes the instructions as AGENTS.md, installs authored skills, copies sandbox files, and adds agent tool scripts.

The workspace is a real Cursor project. It can inherit AGENTS.md and .cursor settings from parent directories. If your agent lives inside a large monorepo, set defineAgent({ local: { cwd } }) to a clean directory or pass a separate --state-root. The run and eval commands already use temporary state.

Durable local state uses this shape:

text
<project>/.agent-serve/
  sessions/<id>/events.ndjson
  sessions/<id>/workspace/
  traces/<sessionId>.ndjson

How can one agent call another?

Every mounted agent also serves MCP at /<slug>/v1/mcp. Another agent or MCP client can use ask, check, and call_tool to delegate work. A peer MCP connection such as defineConnection({ agent: "weather-agent" }) adds those tools to the calling agent.

See Agent-to-agent for a complete example.

Which rules prevent common setup problems?

  • Use Node 22.13 or newer. Bun isn't supported.
  • Put evals under the project-root evals/ directory, not agent/evals/.
  • Run a TypeScript check before shipping. validate and run execute TypeScript but don't type-check it.
  • Return JSON-shaped values from tool execute functions.
  • Keep local session workspaces away from parent rules you don't want the agent to inherit.
  • Sign in or set CURSOR_API_KEY before starting a model turn. Discovery, validation, direct tool calls, and server startup work without a credential.