Appearance
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:
- A channel receives the message from HTTP, Slack, GitHub, or another webhook.
- The channel starts a session or continues an existing one.
- The runtime gives the model its instructions, tools, and workspace.
- The model replies and can call tools along the way.
- 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.
| Path | What it is |
|---|---|
agent/agent.ts | Model and runtime settings |
agent/instructions.md | The always-on system prompt |
agent/tools/<name>.ts | Typed actions the model can call |
agent/skills/* | Procedures loaded when needed |
agent/mcp-connections/<name>.ts | Tools from external MCP servers |
agent/channels/*.ts | HTTP, Slack, and GitHub entry points |
agent/ab.ts or agent/ab/*.ts | Sticky variants and live performance metrics |
evals/**/*.eval.ts | Repeatable 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:
continuationTokentells 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.sessionIdidentifies 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 on | The server host | A Cursor cloud agent |
| Server tools | Supported | Supported 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) | Supported | Not supported (local runtime only) |
| Agent tool scripts | Supported | Supported |
| Skills and seeded files | Added to the session workspace | Must exist in the cloud repository |
| Repository | You provide it | The 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>.ndjsonHow 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, notagent/evals/. - Run a TypeScript check before shipping.
validateandrunexecute TypeScript but don't type-check it. - Return JSON-shaped values from tool
executefunctions. - Keep local session workspaces away from parent rules you don't want the agent to inherit.
- Sign in or set
CURSOR_API_KEYbefore starting a model turn. Discovery, validation, direct tool calls, and server startup work without a credential.