Build
Agents
On this page
What an agent is
An agent is an AI worker that Valet runs for you. It keeps working after your chat with your coding agent ends: it answers questions in Slack, handles email, or posts a report every morning. When no work is in progress it sleeps, and the next message or scheduled run wakes it.
You describe an agent in a folder:
support-bot/
SOUL.md Who the agent is and how it works
skills/
refunds/SKILL.md Instructions for one task
channels/
inbox.md Instructions for one channel
valet.yaml Name, description, connectors and channels- SOUL.md holds the agent's instructions in plain language.
- A skill holds instructions for one task. The agent reads it only when the task comes up.
- A channel is how work reaches the agent, such as a Slack message
or a schedule. A file in
channels/holds instructions for one channel. - valet.yaml names the agent and lists the connectors and channels it needs.
Create an agent
Ask your agent:
Build a Valet agent called support-bot that answers billing questions
in Slack, and deploy it.Your agent writes the folder, creates the agent, then publishes the files:
create_service
{ "kind": "agent", "name": "support-bot" }publish_agent
{
"name": "support-bot",
"files": [
{ "path": "valet.yaml", "content": "name: support-bot\ndescription: Answers billing questions in Slack.\n" },
{ "path": "SOUL.md", "content": "You answer billing questions for Acme's support team.\n…" }
]
}Over MCP, create_service creates an empty agent. publish_agent
deploys it and waits for deployment to finish. An agent that can
run git publishes from a Git push instead of files; see
Publish with Git. Chat with the agent in
the dashboard. With the CLI, valet new writes starter files,
valet agents create creates the agent from the current folder and
deploys it with Git, and valet console opens a chat with it. It needs
Git 2.32 or later unless it creates the agent from the catalog or a Git
URL with --from.
Channels
Every agent has a console channel: the chat in the dashboard and in
valet console. Add others to wake the agent in other ways, such as a
schedule:
create_channel
{
"name": "support-bot",
"channel": "morning-summary",
"channel_kind": "cron",
"schedule": "weekdays at 9:00am",
"timezone": "America/New_York"
}When a channel fires, the agent follows the instructions in
channels/<name>.md, here channels/morning-summary.md.
Webhook
- What wakes the agent
- A request from another service
- Setup
- Signed with a secret by default
Cron
- What wakes the agent
- A schedule, such as weekdays at 9:00
- Setup
- None
Heartbeat
- What wakes the agent
- A fixed interval, from 30 seconds to 24 hours
- Setup
- None
MCP
- What wakes the agent
- Another AI tool calling the agent as a tool
- Setup
- A token for each caller, from
valet channels token mint
Slack
- What wakes the agent
- A message or an @mention
- Setup
- Someone connects Slack to the organization once; each agent then gets its own Slack app
- What wakes the agent
- Mail to an address such as
support@acme.valet.run - Setup
- None
create_channel makes cron, heartbeat, webhook and MCP channels. Slack
needs a browser, so it starts in the dashboard or the CLI.
Agents aren't the only ones with channels. An app takes webhook, cron and heartbeat channels too; see Webhooks and schedules.
What an agent can use
A connector gives the agent a service's tools, such as HubSpot or Google Drive. Valet adds the credential on each call, so the agent never holds it.
attach_connector
{ "name": "support-bot", "connector": "hubspot" }When you deploy, Valet attaches each connector and channel valet.yaml
names that the organization already has. A manually detached connector
returns on the next deploy if valet.yaml still names it. If
valet.yaml names a connector or channel the organization doesn't have,
or a skill that doesn't exist, the deploy fails and lists what to set
up. valet deploy --allow-unsatisfied deploys
anyway, and the agent runs without the missing pieces until you add
them. See Connectors.
An env var is a named setting. Its value is secret by default: the
agent's connectors and channels can use it, but the agent never sees
it. Store a value as plain, with "secret": false in set_env_vars or
--plain in the CLI, when the agent should read it directly, such as a
region.
Skills from your organization's library provide instructions for specific tasks. Attach one a teammate published:
attach_skill
{ "name": "support-bot", "skill": "org:ticket-triage" }A skill in the agent's own skills/ folder ships with the agent. An
attached skill comes from the library and follows its new releases;
there is no pin. See Skills.
The agent has memory: tools to remember, recall and forget facts.
A memory belongs to one conversation, such as a Slack channel, or to
the whole agent. Up to 5 pinned memories reach the agent on every
turn. Each agent holds up to 1,000 memories of up to 4 KB each.
list_memories and set_memory list and set them, as does
valet memories.
Agents run on the claude-sonnet-5 model unless you choose another
with valet ps scale agent=<model>.
Changing its own instructions
An agent can propose changes to its own SOUL.md, its own skills and
its channel files. Valet's code checks each change before it takes
effect:
- It can't change
valet.yaml, so it can't add connectors or channels. - It can't change a skill attached from elsewhere.
- It can make at most 10 changes an hour.
- If its change conflicts with a person's edit, the person's edit wins.
- Each change becomes a new release. A failed build leaves the current release running.
Valet's instructions also tell the agent never to change itself because something it read asked it to.
Who can reach it
Only members of your organization can use the console. On every other channel, anyone the channel reaches can talk to the agent:
- Slack: anyone in the workspace who can message the agent's bot.
- Email: anyone who sends mail to its address.
- Webhook: anyone with the URL and its signing secret.
- MCP: anyone holding a token you minted, and organization members who sign in where MCP sign-in is set up.
Releases
Each publish, with publish_agent or valet deploy, creates a numbered
release, v1, v2 and so on, and makes it live. list_releases or
valet releases support-bot lists them. Changing a connector or an env
var, and each change the agent makes to itself, also creates a release.
There is no rollback command: publish the earlier files again.
A blocking release policy can refuse a release. The agent keeps running its current release. See Release policies to review findings in the dashboard's Releases tab.
Run and watch it
list_sessions
{ "name": "support-bot" }
get_logs
{ "name": "support-bot", "kind": "agent" }
scale_service
{ "name": "support-bot", "count": 0 }
restart_service
{ "name": "support-bot" }These list the agent's conversations, read its logs, pause it, and
restart it. get_session, or valet sessions <id>, shows one
conversation's transcript. Scaling the agent to 1 resumes it. A restart
cuts off conversations in progress.
Next steps
- Connectors: configure the services an agent can use.
- Skill library: manage instructions shared by hosted agents.