Skip to content

Project layout

The Agent SDK builds an agent by walking the filesystem under agent/. Each folder has a defined purpose. The path a file lands in determines how the Agent SDK loads it.

Folder structure

For the capabilities below, identity usually comes from the path. A/B experiments can override their file-derived name.

PathResolves to
agent/tools/approve_pr.tstool approve_pr
agent/mcp-connections/linear.tsMCP connection linear
agent/skills/pr-review.mdskill pr-review
agent/subagents/reviewer/subagent reviewer
agent/channels/drive.tschannel drive, routes under /v1/channels/drive
agent/ab.tsA/B experiment ab unless name overrides it
agent/ab/concise.tsA/B experiment concise unless name overrides it

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).

Full project layout

A full project looks like this.

text
my-agent/
├── package.json
├── agent/
│   ├── agent.ts               # runtime config (model, runtime, cloud/local)
│   ├── 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
│   ├── subagents/
│   │   └── reviewer/          # child agents (agent.ts + instructions.md)
│   ├── channels/
│   │   ├── webhook.ts         # custom HTTP surfaces
│   │   ├── slack.ts           # the Slack channel pack
│   │   └── github.ts          # the GitHub webhook channel pack
│   ├── hooks/
│   │   └── audit.ts           # observe the runtime event stream
│   ├── otel.ts                # optional OpenTelemetry export
│   ├── ab.ts                  # optional live A/B experiment
│   ├── ab/
│   │   └── concise.ts         # optional: more experiments
│   ├── schedules/
│   │   └── heartbeat.md       # cron-driven runs
│   ├── sandbox/workspace/     # files seeded into each session's workspace
│   └── lib/                   # shared code (import-only, never discovered)
└── evals/
    ├── evals.config.ts        # required when evals exist (maxConcurrency)
    └── readiness.eval.ts      # filesystem evals

Evals live in evals/ at the project root, a sibling of agent/, never inside it. agent/evals/ is silently ignored. See Evals.

Folder reference

Each path maps to a capability and a reference page.

PathWhat it isReference
agent/agent.tsdefineAgent({ model?, runtime?, cloud?, local? }); the model defaults to grok-4.5 with effort=high, fast=trueAgent config
agent/instructions.mdAlways-on system prompt, required on the root agent (.ts and directory forms exist)Instructions
agent/tools/<name>.tsOne typed tool; filename = tool name. execution: "server" (in-process, default) or "agent" (a script that runs where the agent runs)Tools
agent/skills/*SKILL.md-convention procedures, loaded on demandSkills
agent/mcp-connections/<name>.tsMCP servers, available to the model, to server tools (ctx.host.mcp), and to channel/schedule handlers (args.host.mcp)MCP connections
agent/subagents/<id>/Child agent directory; description requiredSubagents
agent/channels/*.tsHTTP surfaces beyond the built-in session API; slack.ts and github.ts use the platform packsChannels
agent/hooks/*.tsObserve-only event subscribers, never fatalHooks
agent/otel.tsdefineOtel OTLP export (traces, metrics, optional logs)OpenTelemetry
agent/ab.ts, agent/ab/*.tsdefineAB experiments with sticky variants and live metricsLive A/B metrics
agent/ab.config.tsdefineABConfig shared A/B settingsLive A/B metrics
agent/storage.tsdefineStorage backend for the durable host.kv / host.files APIsStorage
agent/artifacts.tsdefineArtifacts kinds, the tag_artifact opt-in, and retentionArtifacts
agent/schedules/*Cron-driven runs (UTC, 5-field; never auto-fire under --dev)Schedules
agent/sandbox/workspace/**Seed files copied into each local session workspaceSessions
agent/playground/Custom playground tool chips for the Vite dev playgroundPlayground
agent/lib/Import-only shared code, never discoveredNone
evals/evals.config.tsShared eval settings (e.g. maxConcurrency); required when evals existEvals
evals/**/*.eval.tsFilesystem evals; case id = path under evals/Evals

agent/lib/ is the only place for shared code. Everything else under agent/ is discovery surface. A stray .ts file in one of these folders is treated as a definition.

Why didn't the Agent SDK discover my file?

Run agent-sdk validate --dir . and agent-sdk info --dir .. validate prints diagnostics, and serve refuses to start on error-severity ones. Warnings, such as cloud runtime combined with local-only capabilities, 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.

bash
agent-sdk validate --dir .    # diagnostics; non-zero exit on errors
agent-sdk info --dir .        # human-readable surface
agent-sdk info --dir . --json # machine-readable manifest (same shape as GET /v1/info)

What's next

Continue with these pages: