Appearance
Project layout
An Agent SDK project keeps agent files under bot/. Each file's path determines how Agent SDK loads it.
Existing projects rooted at agent/ remain supported.
Folder structure
For the capabilities below, identity comes from the path.
Path under bot/ | Resolves to |
|---|---|
tools/approve_pr.ts | tool approve_pr |
mcp-connections/linear.ts | MCP connection linear (model + host) |
host-connections/inventory.ts | Host MCP connection inventory (host + mcp oauth only) |
skills/pr-review.md | skill pr-review |
subagents/reviewer/ | subagent reviewer |
extensions/ci.ts | extension mount ci; its contributions become ci__<name> |
extensions/notion.ts | Cursor plugin mount notion (cursorPlugin); its skills, agents, and MCP servers become notion__<name> |
channels/drive.ts | channel drive, routes under /v1/channels/drive |
The root agent takes its name from package.json name, falling back to the directory name. When serving multiple agents, the slug is the directory name and must match [A-Za-z0-9][A-Za-z0-9_-]* (and not the reserved v1, playground, or docs segments).
Project tree
Most projects start with this shape.
text
my-agent/
├── package.json
├── bot/
│ ├── agent.ts # model and local harness config
│ ├── instructions.md # always-on system prompt (required)
│ ├── tools/
│ │ └── approve_pr.ts # one typed tool per file
│ ├── skills/
│ │ └── pr-review.md # on-demand procedures (SKILL.md convention)
│ ├── mcp-connections/
│ │ └── linear.ts # tools from external MCP servers
│ ├── host-connections/
│ │ └── inventory.ts # host-only MCP tools
│ ├── subagents/
│ │ └── reviewer/
│ │ ├── agent.ts
│ │ └── instructions.md
│ ├── channels/
│ │ └── github.ts # messages and external events
│ └── hooks/
│ └── audit.ts # observe session events
└── evals/
└── readiness.eval.ts # regression casesEvals stay in evals/ at the project root, as a sibling of bot/, never inside it. See Evals.
Folder reference
Each path maps to a capability and a reference page.
Path under bot/ | What it is | Reference |
|---|---|---|
agent.ts | defineAgent({ model?, local? }); the model defaults to grok-4.5 with effort=high, fast=true | Agent config |
instructions.md | Always-on system prompt, required on the root agent (.ts and directory forms exist) | Instructions |
tools/<name>.ts | One typed tool; filename = tool name. execution: "server" (in-process, default) or "agent" (a script that runs where the agent runs) | Tools |
skills/* | SKILL.md-convention procedures, loaded on demand | Skills |
mcp-connections/<name>.ts | MCP servers, available to the model, to server tools (ctx.host.mcp), and to channel/schedule handlers (args.host.mcp) | MCP connections |
host-connections/<name>.ts | Privileged MCP servers for ctx.host.mcp and mcp oauth. The model never sees them. | MCP connections |
subagents/<id>/ | Child agent directory; description required | Subagents |
extensions/<ns>.ts or extensions/<ns>/ | A mounted extension or Cursor plugin; its contributions become <ns>__<name> | Extensions |
channels/*.ts | HTTP surfaces beyond the built-in session API; slack.ts and github.ts use the platform packs | Channels |
hooks/*.ts | Observe-only event subscribers, never fatal | Hooks |
artifacts.ts | defineArtifacts kinds, the tag_artifact opt-in, and retention | Artifacts |
schedules/* | Cron-driven runs (UTC, 5-field; never auto-fire under --dev) | Schedules |
reminders/*.ts | Named reminder handlers that stay armed across restarts | Schedules |
sandbox/workspace/** | Seed files copied into each local session workspace | Sessions |
lib/ | Import-only shared code, never discovered | None |
Discovery rejects a bot/result.ts file. To act on a turn's decision, have the model record it with an authored tool, then act on it from a turn.completed hook.
Evals use project-root paths:
| Project-root path | What it is | Reference |
|---|---|---|
evals/evals.config.ts | Shared eval settings (e.g. maxConcurrency); required when evals exist | Evals |
evals/**/*.eval.ts | Filesystem evals; case id = path under evals/ | Evals |
Use bot/lib/ for shared imports. A .ts file in one of the listed discovery folders loads as a definition; unrecognized directories produce a validation warning.
Inspect discovery
Run agent-sdk validate --dir . and agent-sdk info --dir .. validate prints diagnostics, and serve refuses to start on error-severity ones. Warnings print but don't block. info lists the discovered surface, so a missing tool or channel shows up immediately. From there, check the folder reference: the file is usually in the wrong directory or has the wrong extension.
text
agent-sdk validate --dir . # diagnostics; non-zero exit on errors
agent-sdk info --dir . # human-readable surface
agent-sdk info --dir . --json # machine-readable project info (same shape as GET /v1/info)Related
- Agent config: the config at the project root
- Tools: add typed actions under
tools/ - CLI: commands that discover this tree