Skip to content

A project is a folder, usually a Git repository, that holds a set of agents and the tool packages they use as plain files. The project commands (caplo validate, diff, push, test, eval, publish and pull) read the folder, compare it with a workspace, and create or update what changed. Review changes in pull requests, then publish from your terminal or from CI.

Terminal window
caplo init support
caplo init shop --template summit

caplo init [dir] creates the project in dir, or in the current directory, which must be missing or empty. The project name defaults to the folder name; set another with --name. A name starts with a lowercase letter and uses only lowercase letters, digits and hyphens.

Template What you get
blank (default) One agent with a starter eval case
summit A sample outdoor shop: a concierge agent with fast routing, three specialist sub-agents, and two tool packages with test fixtures

The summit template creates this layout:

shop/
caplo.yaml the project file
agents/
concierge.yaml one agent file per agent
gear.yaml
orders.yaml
returns.yaml
tools/
order-desk/ one directory per tool package
caplo.yaml the package's own caplo.yaml
package.json
tsconfig.json
src/
tests/
store-stock/
...

Each tool package gets package.json and tsconfig.json from the current tool SDK templates. Run npm install in each package before you run its fixtures; caplo init prints the commands. To start from an agent that already exists in a workspace, use caplo pull instead.

The project’s caplo.yaml sits at the root of the folder:

apiVersion: v1
kind: Project
name: shop
agents: agents/*.yaml
tools: tools/*
Field Required Description
apiVersion Yes Always v1.
kind Yes Always Project. This is what tells it apart from a tool package’s caplo.yaml.
name Yes The project name: a lowercase letter, then lowercase letters, digits and hyphens. Releases published from the project record it.
agents No Glob for agent files, relative to the project root. Default agents/*.yaml.
tools No Glob for tool package directories, relative to the project root. Default tools/*.
environments No Named workspaces the project publishes to. See Environments.

Unknown fields are an error. Globs must stay inside the project, and they skip hidden files and folders such as .DS_Store. A directory the tools glob matches is a package only if it contains a caplo.yaml; others are ignored.

Each agent is one YAML file in the agent YAML format the console exports, with apiVersion: v2.0.0. Files with apiVersion v1 are refused. See Agent YAML for how to write one and the agent YAML reference for every field.

The file name without .yaml is the agent’s key, for example orders for agents/orders.yaml. Keys start with a lowercase letter and use only lowercase letters, digits and hyphens. Other agents in the project link to an agent by its key, and selectors can use it, so renaming the file is a breaking change inside the project. The agent’s name field is what customers and the console see.

Inside a project, agent files refer to other resources like this:

In the agent file Refers to
subAgents: [{local: orders}] The project agent with key orders
subAgents: [{agentId: <ID>}] Any agent already in the workspace
tools: [order-desk/lookup_order] Tool lookup_order of the project package named order-desk; order-desk alone selects all its tools
tools: [crm/find_contact] A published tool of the workspace’s remote MCP server named crm, when no project package has that name
tools: [<PACKAGE_ID>/<TOOL>] A tool of any workspace package, by package ID
knowledgeBases: [Returns policy] The workspace knowledge base with that name, or an ID

A package’s name is the name in its own caplo.yaml, not its folder name. Names of remote MCP servers and knowledge bases are looked up in the workspace a command acts on, so the same file works in several workspaces. A sub-agent link with release: latest, or with no release, follows the child’s newest release; see Sub-agents and routing.

The CLI matches project files to workspace resources by name: agents by their name field and packages by their package name. It never stores workspace IDs in your files.

  • A name the workspace does not have yet is created on the next push or publish.
  • A name it has is updated.
  • Nothing is ever deleted. Renaming an agent in its file therefore creates a new agent and leaves the old one in place. After a publish, caplo publish --prune archives agents that an earlier publish of this project created and that the project no longer defines.
  • If the workspace agent with that name is archived, the command stops. Restore the agent in the console, or rename it in the file.

Agent names must be unique in the project, ignoring case.

Without arguments, diff, push, test, eval and publish act on the whole project. Pass selectors to act on part of it:

Terminal window
caplo push agent/orders
caplo test tool/order-desk
caplo publish "agent/Shop Concierge" tool/store-stock
Selector Selects
agent/<KEY_OR_NAME> One agent, by file key or by its name; a key wins over a name. It brings its project sub-agents and the project packages they use.
tool/<PACKAGE> One project package, by package name.

caplo publish also brings the project agents that link a selected agent at release: latest, because publishing the child publishes them again. A selector that matches nothing is a usage error.

Project commands look for the project file in the current directory, then in each parent directory, skipping tool packages’ own caplo.yaml files. So you can run them from inside agents/ or a package folder. To point at a project elsewhere, pass -C (--dir):

Terminal window
caplo validate -C ~/src/shop
Terminal window
caplo validate

caplo validate checks the project without calling the workspace:

  • caplo.yaml and every package’s caplo.yaml
  • every agent file against the agent schema, and unique file keys and agent names
  • references to project agents and packages, and the tools an mcp package declares
  • sub-agent link cycles, and each agent’s depth limit: at most policy.maxDepth (1 to 4, default 3) links below it
  • fast routing: at least one sub-agent and doNotUseWhen on every link, and, when the file has evals, two cases with routedBy per sub-agent
  • every environment in caplo.yaml, with its agent fields applied

Problems are printed with their file and the command exits with code 3. Tools of remote MCP servers are checked against the workspace on diff, push and publish. diff, push, test, eval and publish run the same checks first and stop on any problem.

To bring an agent you built in the console under version control:

Terminal window
caplo pull "agent/Shop Concierge"
caplo pull agent/concierge ./shop

caplo pull writes the agent, every sub-agent it links, and their eval cases as agent files. It also pulls the source of any package they use that the project lacks into the tools directory. Agents the project already defines are written to their existing files; new ones get a file named after the agent.

The target is the project at the directory you give, or the project above -C. If there is none, the CLI creates a new project there, but never inside another project. Links name the exact release the draft pins, because a draft does not record release: latest; change them back to release: latest if you want parents to follow new child releases. Tools of remote MCP servers stay as <server>/<tool>.

Next, see the day-to-day workflow.