Reference
CLI reference
On this page
The valet command line tool publishes and manages your organization's
skills, artifacts, apps and agents. Coding agents run it for you when
they have a terminal, and you can run it yourself. See
Skills for creating, publishing, cloning, deleting and
attaching skills.
Install
On macOS or Linux:
curl -fsSL https://valet.dev/install.sh | shIn Windows PowerShell:
irm https://valet.dev/install.ps1 | iexThen run valet auth login to sign in. On a new machine, run
valet setup instead. It signs you in, creates an organization if you
have none, installs the Valet plugin for Claude Code, and offers to
create and deploy a first agent. valet update installs the latest
version of the CLI.
Git 2.32 or later must be on your PATH for valet deploy,
valet agents create, valet setup, and the valet skills commands
that create, publish or clone skills.
Valet refuses some commands from CLIs older than 0.1.89 with
cli.upgrade_required. Run valet update to fix it.
Commands
The reference below is the CLI's own help text for the current release.
Run valet <command> --help to see the same text for the version you
have installed.
valet agents
List agents
valet agents [flags]List, create, rename, share, and destroy agents, and set who can open them.
Running "valet agents" with no subcommand lists agents in the default organization. Use --org to list agents in a different organization. The default org is set automatically when you create or join an org.
Deploying is a top-level command: run "valet deploy" from the agent directory.
- -o, --org string
- Org to list agents for
$ valet agents
org-agent
$ valet agents --org other-org
my-agentvalet agents access
Show or set who can open an agent's address
valet agents access <name> [public|private|password] [flags]Show or set who can open an agent at its address.
With no mode, prints the agent's access mode and address. With a mode, moves the agent to it:
private Members of the owning org, after a Valet login. Every
agent is private when it is created.
password Org members sign in with Valet, or any visitor enters the
agent password.
public Anyone with the link can open it.Password mode prompts for a hidden password; pass --password in scripts or agent runs where stdin is not a terminal. Switching away from password mode clears the stored password. Any change signs every current visitor out.
An agent can hold connectors that reach the org's systems, so a visitor who opens it can use what those connectors let it do. Public and password access are off until the Valet server enables them. While they are off, the server's refusal is printed and the command exits 1.
- -o, --org string
- Org that owns the agent
- --password string
- Password to set (password mode; prompts with hidden input when omitted)
Example
$ valet agents access support
support access: private
URL: https://support.acme.valet.run
$ valet agents access support private
Setting support access to private in acme org... done
Only members of the owning org can open this agent, after a Valet login.valet agents create
Create an agent and deploy it
valet agents create [name] [flags]Create a new agent and deploy it.
The source must contain a SOUL.md file. By default, the current directory is used. Pass --from to use a local directory, Git URL, or catalog reference as the source.
A local source deploys the way valet deploy does: the CLI creates a push, commits the directory on top of the agent's source, pushes that commit with Git, and publishes it. Git 2.32 or later must be on your PATH; the CLI checks before it creates the agent. The commit holds every regular file under the directory, walked recursively. Only .git and .valet are skipped, and there is no ignore file, so keep build output and dependency trees out of it. Any single file over 25 MiB is refused before anything is pushed. Run valet deploy --help for the details.
Sources for --from: Local path: --from . or --from ./my-agent Git URL: --from github.com/user/repo Catalog ref: --from catalog:code-reviewer
When --from points to a Git URL or catalog reference, the repo is cloned and the project files are scaffolded to a local directory (default ./<name>/, override with --path).
When the source contains a valet.yaml manifest, it is validated before proceeding. If the manifest declares a channel with catalog: slack, the CLI checks the org's Slack connection, prompts for a bot name, and creates the Slack channel inline. The --attach-connector and --attach-channel flags name org-scoped resources to attach to the agent after creation.
If the manifest declares connectors or channels the agent does not have yet, the deploy stops and lists them. The agent exists and the directory is linked by then: attach them and run valet deploy, or run valet deploy --allow-unsatisfied to deploy without them.
The agent name is optional — if omitted, the server generates one. After deploying, waits for the agent runtime to become ready. Use --no-wait to skip the readiness check.
When --org is not specified, the default org is used. The default org is set automatically when you create or join an org.
- --attach-channel stringSlice
- Org channel to attach (repeatable)
- --attach-connector stringSlice
- Org connector to attach (repeatable)
- --from string
- Source: local path, Git URL, or catalog:name
- --no-wait
- Skip waiting for the agent to become ready
- -o, --org string
- Org that owns the agent
- --path string
- Where to scaffold project (default: ./<name>/)
Example
$ valet agents create my-agent
Creating agent... done, my-agent agent
Linking directory... done
Reading files... done, 4 files
Creating push for my-agent agent... done
Fetching source... done
Pushing source... done
Deploying my-agent agent... done, v1
Waiting for agent to start... done
$ valet agents create my-reviewer --from catalog:code-reviewer --org acme
Fetching catalog:code-reviewer... done
Creating agent... done, my-reviewer agent in acme org
Deploying my-reviewer agent in acme org... done, v1
Scaffolding ./my-reviewer... done
Linking directory... done
Waiting for agent to start... done
$ valet agents create my-bot --org acme --attach-connector github --attach-channel gh-webhook
Creating agent... done, my-bot agent in acme org
Linking directory... done
Attaching connector github... done
Attaching channel gh-webhook... done
Reading files... done, 4 files
Creating push for my-bot agent in acme org... done
Fetching source... done
Pushing source... done
Deploying my-bot agent in acme org... done, v1
Waiting for agent to start... done
$ valet agents create support-bot --from ./support-source --org acme
Creating agent... done, support-bot agent in acme org
Linking directory... done
Checking Slack connection... connected (My Workspace)
Bot name [support-bot]: support-bot
Creating Slack channel... done, support-bot-slack
Reading files... done, 5 files
Creating push for support-bot agent in acme org... done
Fetching source... done
Pushing source... done
Deploying support-bot agent in acme org... done, v1
Waiting for agent to start... donevalet agents destroy
Destroy an agent
valet agents destroy <name> [flags]Permanently destroy an agent and all its releases.
This action cannot be undone.
The command asks for confirmation; pass --yes to skip it, which a script must, since the prompt needs a terminal.
- -o, --org string
- Org that owns the agent
- --yes
- Skip the confirmation prompt
Example
$ valet agents destroy my-agent
This destroys my-agent and all its releases. It cannot be undone. Continue? (y/N) y
Destroying my-agent agent in acme org... done
$ valet agents destroy my-agent --yes
Destroying my-agent agent in acme org... donevalet agents info
Show agent details
valet agents info [name] [flags]Show detailed information about an agent.
Displays the agent's org, its role in the org, current release, process state, channels, connectors, and effective environment. Environment rows show each env var's kind and scope; plain values are shown inline, secret values are masked. The agent is determined by the positional argument, the --agent flag, or the linked agent in the current directory.
- -a, --agent string
- Agent to show info for (uses linked agent if omitted)
- -o, --org string
- Org that owns the agent
Example
$ valet agents info my-agent
=== Agent: my-agent (acme org)
org: acme-corp
role: Developer
release: v3
process: up for 3h22m
channels: slack-channel, support-webhook
connectors: github-mcp, linear-mcp
environment:
GITHUB_TOKEN secret ****** agent (overrides org)
REGION plain us-east-1 org (inherited)valet agents link
Link the current directory to an agent
valet agents link <name> [flags]Link the current directory to an existing agent.
Creates a .valet/config.json file that maps this directory to the named agent and its org. Subsequent commands like "valet agents deploy" use the linked agent automatically.
Pass --org when you belong to more than one org. Single-org users can omit --org. Use --force to replace an existing link.
- --force
- Replace an existing link in this directory
- -o, --org string
- Org that owns the agent
Example
$ valet agents link my-agent
Linked my-agent agent in acme org
$ valet agents link other-agent --org widgets --force
Linked other-agent agent in widgets orgvalet agents rename
Rename an agent
valet agents rename <new-name> [flags]Rename an agent.
The new name follows the same validation as 'agents create': it must be a DNS label (lowercase letters, digits, hyphens) and not a reserved word. Renaming is safe at any point in an agent's lifecycle — webhook URLs are keyed by channel UUID, Slack and runtime routing are keyed by agent UUID, and the dashboard URL slug redirects on rename.
An agent rename does not rename or recycle channel routes. Webhook and MCP URLs keep their generated handles and continue to use channel UUIDs.
The agent to rename is determined by --agent or, when omitted, the linked agent in the current directory. If a .valet/config.json above the current directory points at the renamed agent, it is updated in place to the new name.
- -a, --agent string
- Agent to rename (uses linked agent if omitted)
- -o, --org string
- Org that owns the agent
Example
$ valet agents rename better-name --agent my-agent
Renaming my-agent agent to better-name... done
$ cd ./my-agent && valet agents rename better-name
Renaming my-agent agent in acme org to better-name... done
Updating .valet/config.json... donevalet agents role
Give an agent a role in its org
valet agents role [agent] <admin|developer> [flags]Keep an agent's org role at Developer.
Agents have the Developer role. The server refuses requests to assign Admin. The admin argument remains accepted so the server can report that refusal.
The agent is determined by the positional argument, the --agent flag, or the linked agent in the current directory.
Requires the Admin role.
- -a, --agent string
- Agent to give the role (uses linked agent if omitted)
- -o, --org string
- Org that owns the agent
Example
$ valet agents role fixer developer
fixer is now a Developer of acme.valet apps
List apps
valet apps [flags]List, create, rename, and destroy apps.
An app is a Procfile application built with buildpacks and served over HTTPS at a name-derived hostname. Create an app, then run "valet deploy" from the linked directory to build and run it. The URL is live (failing closed) before the first deploy.
Running "valet apps" with no subcommand lists apps in the default organization. Use --org to list apps in a different organization. Share an app by email with "valet apps share", and list or remove shares with "valet apps shares" and "valet apps unshare". Let a script call a private app with a service token from "valet apps token".
- -o, --org string
- Org to list apps for
$ valet apps
NAME URL VERSION ACCESS
my-app https://my-app.acme.valet.run 3 privatevalet apps access
Show or change an app's access mode
valet apps access <name> [public|private|password] [flags]Show or change an app's access mode.
Private admits members of the owning org after Valet login, and is the default for a new app. Password also admits visitors with the password. Public admits anyone.
Omit the mode to show current access. Password mode uses a hidden prompt on a terminal, or --password in scripts. Access changes need no deploy.
- -o, --org string
- Org that owns the app
- --password string
- Password for password mode; no default
Example
$ valet apps access reports
$ valet apps access reports public --org acme
$ valet apps access reports password --password example --org acmevalet apps create
Create an app
valet apps create [name] [flags]Create a new app.
The app's name becomes the first label of its hostname. If the name is omitted, the server generates one. The URL is live immediately and fails closed until the first deploy builds and runs the app. The current directory is linked to the new app so "valet deploy" builds and releases it.
The app name is optional — if omitted, the server generates one. App, site, and agent names share one namespace within an org: an app cannot take the name of an existing agent or site.
When --org is not specified, the default org is used. The default org is set automatically when you create or join an org.
- -o, --org string
- Org that owns the app
Example
$ valet apps create my-app
Creating app... done, my-app
Linking directory... done
URL: https://my-app.acme.valet.run
Access: private
Run "valet deploy" to build and run this directory.valet apps destroy
Destroy an app
valet apps destroy <name> [flags]Permanently destroy an app and all its releases.
The app's hostname stops serving within seconds. A later app or site in the same organization may reuse its name and hostname. This action cannot be undone.
The command asks for confirmation; pass --yes to skip it, which a script must, since the prompt needs a terminal.
- -o, --org string
- Org that owns the app
- --yes
- Skip the confirmation prompt
Example
$ valet apps destroy my-app
This destroys my-app and all its releases. It cannot be undone. Continue? (y/N) y
Destroying my-app app in acme org... done
$ valet apps destroy my-app --yes
Destroying my-app app in acme org... donevalet apps link
Link the current directory to an app
valet apps link <name> [flags]Link the current directory to an existing app.
Creates a .valet/config.json file that maps this directory to the named app and its org. Subsequent "valet deploy" runs publish this directory to the linked app.
Pass --org when you belong to more than one org. Single-org users can omit --org. Use --force to replace an existing link.
- --force
- Replace an existing link in this directory
- -o, --org string
- Org that owns the app
Example
$ valet apps link my-app
Linked my-app app in acme orgvalet apps rename
Rename an app and its hostname
valet apps rename <name> <new-name> [flags]Rename an app and move it to the new name-derived hostname.
The old hostname stops serving and does not redirect. A later app or site in the same organization may reuse the old name and hostname. Generated channel hostnames are unaffected.
- -o, --org string
- Org that owns the app
Example
$ valet apps rename ledger-api accounting-api --org acme
Renaming ledger-api app in acme org to accounting-api... done, https://accounting-api.acme.valet.runvalet apps token
Manage service tokens for an app
valet apps token [command]Mint, list, and revoke service tokens for an app.
A service token lets a script, daemon, or CLI call a private app. Send it as "Authorization: Bearer <token>". The app sees the request as a visitor of kind "service" that names the token. The plaintext value is shown exactly once, at mint time.
When no --app flag is provided, uses the linked app in the current directory.
- --app string
- App that owns the token (uses linked app if omitted)
- -o, --org string
- Org that owns the app
Example
$ valet apps token mint ci --app billing
$ valet apps token list --app billing
$ valet apps token revoke ci --app billingvalet apps token list
List service tokens for an app
valet apps token list [flags]List an app's service tokens.
Shows each token's name, expiry, creation date, and the member who minted it. EXPIRES is "never" for a token with no expiry and "expired" for one whose expiry has passed. Revoked tokens never appear. Plaintext token values are never shown after minting.
When no --app flag is provided, uses the linked app in the current directory.
- --app string
- App that owns the token (uses linked app if omitted)
- -o, --org string
- Org that owns the app
Example
$ valet apps token list --app billing
=== billing app tokens (acme org)
NAME EXPIRES CREATED BY
ci Feb 9, 2027 12:00 PM UTC Nov 11, 2026 jo@acme.com
worker never Nov 11, 2026 jo@acme.comvalet apps token mint
Mint a service token for an app
valet apps token mint <token-name> [flags]Mint a service token for an app.
A service token lets a script, daemon, or CLI call a private app. Send it as "Authorization: Bearer <token>". The app sees the request as a visitor of kind "service" that names this token.
The token is printed exactly once; store it securely. The value goes to stdout and the progress lines to stderr, so a script can capture the value.
When no --app flag is provided, uses the linked app in the current directory.
- --expires string
- Expiry as a Go duration (e.g. 720h) or an RFC 3339 timestamp (default: never)
- --app string
- App that owns the token (uses linked app if omitted)
- -o, --org string
- Org that owns the app
Example
$ valet apps token mint ci --app billing --expires 2160h
Minting token for billing app in acme org... done, ci
expires: Tue Feb 9, 2027 12:00 PM UTC
This token will not be shown again. Store it securely:
vsvc_3q2-7wEAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRovalet apps token revoke
Revoke a service token for an app
valet apps token revoke <token-name> [flags]Revoke a service token for an app.
Revocation is immediate and permanent: the app refuses the token on its next request. Mint a new token to restore access.
When no --app flag is provided, uses the linked app in the current directory.
- --app string
- App that owns the token (uses linked app if omitted)
- -o, --org string
- Org that owns the app
Example
$ valet apps token revoke ci --app billing
Revoking token ci for billing app in acme org... donevalet auth
Manage authentication
Log in, log out, and check authentication status.
Valet uses OAuth device flow for authentication. Credentials are stored locally in the Valet config directory.
valet auth login
Log in to Valet
valet auth login [flags]Authenticate with Valet using the OAuth device flow.
Opens a browser to complete login. If the browser cannot be opened automatically, the URL and confirmation code are printed for manual entry.
Example
$ valet auth login
Open this URL to log in: https://auth.valet.dev/verify?code=ABCD-1234
Confirmation code: ABCD-1234
Waiting for browser login...
Logged in.valet auth logout
Log out of Valet
valet auth logout [flags]Log out of Valet and revoke the stored credentials.
Revokes the access token with the auth provider and deletes locally stored credentials. Safe to run when already logged out.
Example
$ valet auth logout
Logged out.valet auth whoami
Show the current user
valet auth whoami [flags]Display the currently authenticated user.
Shows the email address and name associated with the stored credentials. Also surfaces your default org and any linked project so you can see what "valet <command>" will target. If the access token has expired, whoami transparently refreshes it before reporting. Exits with code 1 if not logged in or if the refresh token is no longer valid.
Example
$ valet auth whoami
Logged in as: alice@example.com (Alice Smith)
Default org: acme (from ~/.config/valet/config.json)
Linked project: /Users/alice/src/reviewer-agent
Agent: reviewer
Org: acmevalet builds
List and show app builds
valet builds [<app>] [flags]List an app's builds, newest first, or show one build.
"valet deploy" starts a build for an app and follows it. "valet deploy --no-wait" prints the build's id and returns; "valet builds show <id>" reads that build later, and --follow follows it as deploy would.
Run without a subcommand, builds lists the app's newest builds to stdout: each build's id, status, the release it made, its commit, and when it was created. A build that started says when, and one that settled says when and how long its attempt took. A build on a later attempt names it, and a failed or superseded build's error follows on its own line. Status is pending, running, succeeded, failed, or superseded, which means a newer deploy replaced the build. The positional argument, --app, or the directory's link names the app.
- -a, --agent string
- App name (overrides project link)
- --app string
- App name (same as --agent)
- -n, --num int32
- Number of builds to list, newest first, up to 100
- -o, --org string
- Org the app belongs to
$ valet builds checkout
=== Builds of checkout
0192f1d4-0b6e-7a31-8c2f-5e4d3c2b1a09 running - 3fa91c2 2026-11-01T12:03:00Z started 2026-11-01T12:03:02Z
0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b succeeded v4 abc1234 2026-11-01T12:00:00Z started 2026-11-01T12:00:01Z finished 2026-11-01T12:00:49Z (48s)
0192f1a0-55c2-7e10-9d3a-1b2c3d4e5f60 superseded - def5678 2026-11-01T11:59:40Z finished 2026-11-01T11:59:58Z
build.superseded: A newer deploy replaced this build, so nothing was deployed from it.
$ valet builds --app checkout -n 1valet builds show
Show an app build's log and status
valet builds show <build-id> [flags]Show an app build: its log so far, then its status, the release it made, the app's processes on that release, and the release evaluation that holds or held it. The log goes to stdout and the rest to stderr. Show reads the build once and exits 0 whatever state it is in. A build still in progress ends with how to follow it.
Pass --follow to follow the build to its end as "valet deploy" does. It streams the log, prints each policy and each process as it changes, and exits 0 once the release is up or idle, or a later release replaced it. It exits 1 if the build fails, a newer deploy replaced the build before its release, a process crashes, policies refuse the release, or --wait-timeout passes.
"valet deploy --no-wait" prints the id of the build it starts. Policy hints name the app the build's release evaluation names, in the org --org or the linked directory gives.
- -f, --follow
- Follow the build until its release is up or fails (default: false)
- -o, --org string
- Org that owns the app, for policy hints with --follow (uses linked or default org if omitted)
- --wait-timeout duration
- With --follow, how long to wait for the app's processes to come up, and for policies to decide (default 15m for policies)
Example
$ valet builds show 0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b
-----> Fetching source
-----> Building
=== Build 0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b
Status: running
Deploy: running
Follow it with "valet builds show 0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b -f".
$ valet builds show 0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b
=== Build 0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b
Status: succeeded
Release: v4
URL: https://checkout.acme.valet.run
Deploy: up
=== Processes
web.1 up v4
$ valet builds show 0192f1c3-7d1e-7c4a-9b1f-3c2d1e0f9a8b -f
-----> Exporting bundle
-----> Uploading bundle
web.1 starting v3 → v4
web.1 up v4
Deployed v4
URL: https://checkout.acme.valet.runvalet channels
List channels
valet channels [flags]List, create, and manage channels.
Channels bring messages and scheduled work into your agents and apps. Each channel has a type, such as webhook or slack, and belongs to an org, an app, or an agent.
A channel on an agent starts a turn with the prompt in its channels/<name>.md. A channel on an app is a webhook, cron, or heartbeat: Valet posts each delivery to the --path you give, so a private app can take webhooks and scheduled work.
Create a webhook or slack channel with --org and attach it to several agents with "valet channels attach". Apps take no org channels.
Running "valet channels" with no subcommand lists all channels.
- -a, --agent string
- Filter channels by agent name
- --app string
- Filter channels by app name (same as --agent)
- -o, --org string
- Org to list channels for
valet channels attach
Attach an org channel to an agent
valet channels attach <channel-name> [flags]Attach an org channel to an agent.
Makes an org-level channel available to the specified agent. Incoming messages on the channel will be routed to the agent. Use --as to give the attachment a custom alias (useful when attaching the same channel to multiple agents with different names). Use --events to filter which event types are routed to the agent.
For Slack channels, attaching provisions a per-agent Slack bot with its own identity in the workspace. The --bot-name flag sets the bot's display name (defaults to the agent name).
An app takes no org channels. Create a webhook, cron, or heartbeat channel on the app with "valet channels create <type> --app <app>".
Use "valet channels detach" to remove the attachment.
- -a, --agent string
- Agent to attach the channel to
- --as string
- Custom alias for the attachment
- --bot-name string
- Slack bot display name (slack channels only, defaults to agent name)
- --events stringSlice
- Event types to filter (comma-separated)
- -o, --org string
- Org that owns the channel
Example
$ valet channels attach github
Attaching github to my-agent agent in acme org... done, github
$ valet channels attach github --as gh-events --events push,pull_request
Attaching github to my-agent agent in acme org... done, gh-events (events: push, pull_request)
$ valet channels attach slack --agent my-agent --bot-name my-bot
Attaching slack to my-agent agent in acme org... done, slack
type: slack
bot: @my-bot
workspace: My Workspace (T12345)valet channels catalog
List channel catalog entries
valet channels catalog [flags]List available channel catalog entries.
The channel catalog contains Valet-curated channel definitions for well-known services. Use "valet channels catalog get <name>" for details on a specific entry. Use "valet channels create <name>" to provision a channel from the catalog.
Example
$ valet channels catalog
github-webhook webhook WEBHOOK_SECRET GitHub webhook (HMAC-SHA256)
slack-events webhook WEBHOOK_SECRET Slack Events APIvalet channels catalog get
Show catalog entry details
valet channels catalog get <name> [flags]Show detailed information about a channel catalog entry.
Displays the entry's type, verification scheme, event header, and required secret slots.
Example
$ valet channels catalog get github-webhook
Name: github-webhook
Type: webhook
Verify: hmac-sha256 (X-Hub-Signature-256)
Event Header: X-GitHub-Event
Slots:
WEBHOOK_SECRET Shared secret for signature validationvalet channels create
Create a channel
valet channels create <entry> [flags]Create a channel from the catalog or by type.
If the argument matches a catalog entry, provisions a channel using that entry's default configuration. Managed secrets are auto-generated for any secret slots the entry defines. Use --as to give the channel a custom name.
For type-specific creation, use a subcommand:
valet channels create webhook [name] valet channels create cron [name] valet channels create heartbeat [name] valet channels create slack [name] valet channels create telegram [name] valet channels create email [name] valet channels create mcp [name]
Name an app with --app on the webhook, cron, or heartbeat subcommand. When no --agent, --app, or --org flag is provided, uses the linked agent or app in the current directory.
Use "valet channels catalog" to browse available catalog entries.
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- --as string
- Custom name for a catalog channel
- -o, --org string
- Org that owns this channel
Example
# Add a channel from the catalog:
$ valet channels create github-webhook
Creating webhook channel on my-agent agent in acme org... done, github-webhook
url: https://gateway.valet.dev/webhook/abc123
secret: whsec_abc123
managed: GITHUB_WEBHOOK_WEBHOOK_SECRET
# Catalog entry with a custom name:
$ valet channels create github-webhook --as my-gh-hook
Creating webhook channel on my-agent agent in acme org... done, my-gh-hook
url: https://gateway.valet.dev/webhook/def456
secret: whsec_def456
managed: MY_GH_HOOK_WEBHOOK_SECRET
# Type-specific subcommands:
$ valet channels create webhook my-channel
$ valet channels create cron daily-report --schedule "every day at 9:00am"
$ valet channels create heartbeat health-check --every 5m
$ valet channels create slack my-bot --bot-name support-bot
$ valet channels create telegram tg-channel
$ valet channels create email inbox --sender-policy org
$ valet channels create mcp my-mcpvalet channels create cron
Create a cron channel
valet channels create cron [name] [flags]Create a cron channel that triggers on a schedule.
Provide either --schedule with a human-readable description (e.g. "every day at 9:00am") or --cron with a raw crontab expression (e.g. "0 9 * * *"). The two flags are mutually exclusive. Use --timezone to specify an IANA timezone (default: UTC).
To deliver to an app, name it with --app (or --agent) and give --path, the path in the app that handles each delivery. Valet posts there with a channel visitor token; the app is not restarted and needs no prompt.
- --app string
- App that owns this channel (same as --agent)
- --cron string
- Raw crontab expression (e.g. "0 9 * * *")
- --path string
- Path in an app that handles each delivery (required for an app, such as /webhooks/stripe)
- --prompt string
- Prompt path (default: channels/<name>.md; not used for an app)
- --schedule string
- Human-readable schedule (e.g. "every day at 9:00am")
- --timezone string
- IANA timezone (default: UTC)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
# Human-readable schedule:
$ valet channels create cron daily-report --schedule "every day at 9:00am"
Creating cron channel on my-agent agent in acme org... done, daily-report
type: cron
schedule: Every Day at 9:00 AM
cron: 0 9 * * *
timezone: UTC
next: Mon Mar 2, 2026 9:00 AM UTC
agent: my-agent
prompt: channels/daily-report.md
# Raw crontab expression:
$ valet channels create cron weekly --cron "0 9 * * 1" --timezone US/Easternvalet channels create email
Create an email channel
valet channels create email [name] [flags]Create an email channel backed by a @valet.run mailbox.
By default a new mailbox is minted with a randomly generated address in the org's namespace. Pass --local-part to choose the address's local part, or --mailbox to bind the exact existing address of an org-owned mailbox instead. The --sender-policy flag controls which senders may reach the agent: open (any sender passing the gates), allowlist, or org (org members only).
The printed status reports the org email identity's readiness: provisioning (records pending), inbound_ready (mail is received and wakes the agent; sending unlocks once the identity verifies), or ready (receiving and sending).
An agent may have several named email channels, each bound to a distinct mailbox and prompt. When no --agent or --org flag is provided, uses the linked agent in the current directory.
- --local-part string
- Chosen local part for the minted address (default: a generated haiku; not with --mailbox)
- --mailbox string
- Existing mailbox address to bind (default: mint a new address)
- --prompt string
- Prompt path (default: channels/<name>.md)
- --sender-policy string
- Sender policy (open, allowlist, org; default: open)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
$ valet channels create email inbox
Creating email channel on my-agent agent in acme org... done, inbox
type: email
address: wandering-brook-7h3k@acme.valet.run
policy: open
agent: my-agent
prompt: channels/inbox.md
$ valet channels create email support --sender-policy org
$ valet channels create email intake --local-part intake
$ valet channels create email executed --mailbox executed@acme.valet.runvalet channels create heartbeat
Create a heartbeat channel
valet channels create heartbeat [name] [flags]Create a heartbeat channel that triggers at a fixed interval.
The --every flag is required and specifies the interval (e.g. 5m, 1h, 30s). Use --timezone to specify an IANA timezone (default: UTC).
To deliver to an app, name it with --app (or --agent) and give --path, the path in the app that handles each delivery. Valet posts there with a channel visitor token; the app is not restarted and needs no prompt.
- --app string
- App that owns this channel (same as --agent)
- --every string
- Heartbeat interval (e.g. 5m, 1h)
- --path string
- Path in an app that handles each delivery (required for an app, such as /webhooks/stripe)
- --prompt string
- Prompt path (default: channels/<name>.md; not used for an app)
- --timezone string
- IANA timezone (default: UTC)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
$ valet channels create heartbeat health-check --every 5m
Creating heartbeat channel on my-agent agent in acme org... done, health-check
type: heartbeat
every: 5m
timezone: UTC
next: Mon Mar 2, 2026 9:05 AM UTC
agent: my-agent
prompt: channels/health-check.mdvalet channels create mcp
Create an MCP channel
valet channels create mcp [name] [flags]Create an MCP channel that exposes the agent as an MCP server.
The channel serves MCP over Streamable HTTP at the endpoint URL shown in the output. It exposes a built-in "ask_<agent>" tool that takes a message and returns the agent's response, so the channel is usable as soon as a credential is minted — no tool files required. Define additional tools by adding mcp/<tool>.md files to the agent.
Clients authenticate with bearer credentials minted via "valet channels token mint".
- --prompt string
- Prompt path (default: channels/<name>.md)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
$ valet channels create mcp my-mcp
Creating mcp channel on my-agent agent in acme org... done, my-mcp
type: mcp
url: https://gateway.valet.dev/mcp/abc123
agent: my-agent
prompt: channels/my-mcp.md
Mint a credential with: valet channels token mint my-mcp <token-name>valet channels create slack
Create a Slack channel
valet channels create slack [name] [flags]Create a Slack channel for bidirectional messaging.
Setup is two-phase. The first phase is per-org: run with --org to connect Slack to the org, which prompts for a Slack app access token and refresh token (generate them at https://api.slack.com/apps under "Your App Configuration Tokens"). The second phase is per-agent: run with --agent (or from a linked project directory) to create a dedicated Slack app for that agent. The per-agent phase requires an existing org-level Slack connection.
Use --bot-name to customize the Slack bot display name. The default is the agent name.
Connecting Slack to the org (--org) requires the Admin role. Creating an agent's app on a connected workspace does not.
- --bot-name string
- Slack bot display name (default: agent name)
- --prompt string
- Prompt path (default: channels/<name>.md)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
$ valet channels create slack --org acme
Checking Slack connection... not connected
Connecting Slack to acme org.
Generate a Slack app access token and refresh token at
https://api.slack.com/apps (under "Your App Configuration Tokens")
and paste them when prompted.
Slack app access token: ********
Slack app refresh token: ********
Connected to Acme (T12345)
$ valet channels create slack my-slack-bot --bot-name support-bot
Checking Slack connection... connected (Acme)
Creating slack channel on my-agent agent in acme org... done, my-slack-bot
type: slack
bot: @support-bot
workspace: Acme (T12345)
agent: my-agent
prompt: channels/my-slack-bot.mdvalet channels create telegram
Create a Telegram channel
valet channels create telegram [name] [flags]Create a Telegram channel for bidirectional messaging.
After creating the channel, connect it by visiting the Telegram deep link shown in the output.
- --prompt string
- Prompt path (default: channels/<name>.md)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
$ valet channels create telegram tg-channel
Creating telegram channel on my-agent agent in acme org... done, tg-channel
type: telegram
telegram: https://t.me/valetdotdevbot?start=tok123
agent: my-agent
prompt: channels/tg-channel.mdvalet channels create webhook
Create a webhook channel
valet channels create webhook [name] [flags]Create a webhook channel with signature verification.
Generates a webhook URL and a managed signing secret used to verify inbound requests. The managed secret is stored as a secret-kind env var ("valet env") and can be rotated with "valet env set". The "managed" field in the output is the secret name.
When --secret-name is provided, the channel references an existing secret by that name instead of auto-generating one. Use this for services like Stripe or Svix where you control the signing key.
Webhook signature verification schemes:
hmac-sha256 HMAC-SHA256 of raw body.
Default header: X-Webhook-Signature.
Supports sha256=<hex>, v1=<hex>, raw hex, raw base64.
Use --signature-header to change the header. stripe HMAC-SHA256 of "{timestamp}.{body}".
Default header: Stripe-Signature.
Parses t=<ts>,v1=<hex> from the header value.
Use --signature-header for providers that use the same
format with a different header (e.g. WorkOS).
Requires --secret-name. svix HMAC-SHA256 of "{msg_id}.{timestamp}.{body}".
Reads svix-id, svix-timestamp, svix-signature headers,
falling back to webhook-id, webhook-timestamp,
webhook-signature (Loops.so and other standard-webhooks
senders). Secret must be base64-encoded (optionally
whsec_ prefixed). Requires --secret-name. slack Slack Events API signature verification.
HMAC-SHA256 of "v0:{timestamp}:{body}".
Reads X-Slack-Request-Timestamp and X-Slack-Signature.
Handles url_verification challenges automatically.
Requires --secret-name. static-token Constant-time comparison of a bearer token.
Default header: X-Webhook-Signature.
Use --signature-header to change the header.none No verification. Use for testing or trusted networks.
To deliver to an app, name it with --app (or --agent) and give --path, the path in the app that handles each delivery. Valet posts there with a channel visitor token; an app channel must verify (not "none").
- --app string
- App that owns this channel (same as --agent)
- --delivery-key-header string
- HTTP header containing a unique delivery ID for dedup (e.g. X-GitHub-Delivery)
- --delivery-key-path string
- Dot-notation path to a unique delivery ID in the JSON body for dedup (e.g. event.id)
- --path string
- Path in an app that handles each delivery (required for an app, such as /webhooks/stripe)
- --prompt string
- Prompt path (default: channels/<name>.md; not used for an app)
- --secret-name string
- Name of an existing secret-kind env var to use for webhook verification (from valet env)
- --signature-header string
- Header for signature (hmac-sha256: X-Webhook-Signature, stripe: Stripe-Signature, mercury: Mercury-Signature, static-token: X-Webhook-Signature)
- --verify string
- Verification scheme (none, hmac-sha256, slack, svix, stripe, mercury, static-token; default: hmac-sha256)
- -a, --agent string
- Agent that owns this channel (an app for webhook, cron, and heartbeat)
- -o, --org string
- Org that owns this channel
Example
# Default hmac-sha256 verification (auto-generates managed secret):
$ valet channels create webhook my-channel
Creating webhook channel on my-agent agent in acme org... done, my-channel
type: webhook
url: https://gateway.valet.dev/webhook/abc123
secret: whsec_abc123
managed: MY_CHANNEL_WEBHOOK_SECRET
verify: hmac-sha256 (X-Webhook-Signature)
agent: my-agent
prompt: channels/my-channel.md
# Stripe webhooks with a managed secret reference:
$ valet channels create webhook stripe-events \
--verify stripe \
--secret-name STRIPE_WEBHOOK_SECRETvalet channels destroy
Destroy a channel
valet channels destroy <name> [flags]Permanently destroy a channel.
This action cannot be undone. When no --agent, --app, or --org flag is provided, uses the linked agent or app in the current directory.
Destroying an org-level Slack channel cascades: all per-agent Slack bots are destroyed first, then the org Slack connection is removed.
- -a, --agent string
- Agent that owns this channel
- --app string
- App that owns this channel (same as --agent)
- -o, --org string
- Org that owns this channel
Example
$ valet channels destroy my-channel
Destroying my-channel on my-agent agent in acme org... done
$ valet channels destroy stripe --app my-app
Destroying stripe on my-app app in acme org... done
$ valet channels destroy slack --org my-org
Destroying slack in my-org org... donevalet channels detach
Detach a channel from an agent
valet channels detach <alias> [flags]Detach a channel from an agent.
Removes an org channel attachment from the specified agent. Messages on the channel will no longer be routed to the agent. The org channel itself is not deleted.
For Slack channels, detaching destroys the per-agent Slack bot. Use --force to skip the confirmation prompt.
Use "valet channels attach" to re-attach the channel.
- -a, --agent string
- Agent to detach the channel from
- --force
- Skip confirmation for Slack channel detach
- -o, --org string
- Org that owns the channel
Example
$ valet channels detach github
Detaching github from my-agent agent in acme org... done
$ valet channels detach slack --force
Detaching slack from my-agent agent in acme org... donevalet channels info
Show channel details
valet channels info <name> [flags]Show detailed information about a channel.
Displays the channel's type, webhook URL, signing secret, managed secret name, verification scheme, status, owning org, app, or agent, and prompt path.
A channel on an app also shows its delivery path and its last five deliveries: each one's outcome (delivered, retrying, pending, or failed), attempts, the status the app answered, and the error. A channel whose deliveries keep failing shows why under health.
When no --agent, --app, or --org flag is provided, uses the linked agent or app in the current directory.
- -a, --agent string
- Agent that owns this channel
- --app string
- App that owns this channel (same as --agent)
- -o, --org string
- Org that owns this channel
Example
$ valet channels info my-channel
=== Channel: my-channel on my-agent agent in acme org
type: webhook
url: https://gateway.valet.dev/webhook/abc123
status: active
secret: whsec_abc123
verify: hmac-sha256 (X-Webhook-Signature)
agent: my-agent
prompt: channels/my-channel.md
$ valet channels info stripe --app my-app
=== Channel: stripe on my-app app in acme org
type: webhook
url: https://gateway.valet.dev/webhook/def456
status: active
verify: stripe (Stripe-Signature)
app: my-app
path: /webhooks/stripevalet channels slack
Manage Slack activity levels
valet channels slack [flags]List and manage how actively the agent participates in each Slack conversation.
An activity level controls what wakes the agent in a conversation: "mentions" (only @-mentions), "emails" (@-mentions and forwarded emails), or "all" (every message). The channel default is a template stamped onto each conversation when the bot joins it; changing the default never re-points conversations the bot is already in.
Running "valet channels slack" with no subcommand lists the bot's conversations with each conversation's effective level.
- -a, --agent string
- Agent that owns the Slack channel
- -o, --org string
- Org that owns the Slack channel
Example
$ valet channels slack --agent my-agent
=== Slack conversations on my-agent agent
#general C0123456789 public mentions
#ops G0234567890 private allvalet channels slack add
Add the agent's bot to a Slack conversation
valet channels slack add <#conversation> [flags]Add the agent's Slack bot to a conversation.
For a public channel the bot self-joins. A private channel or DM cannot be self-joined: the command prints the /invite hint to run from inside the conversation instead. The conversation may be given as "#name" (resolved against joinable channels) or as a raw Slack ID.
Use --activity to stamp a starting level; without it the conversation inherits the channel default.
- --activity string
- Starting activity level (mentions, emails; default: channel default)
- -a, --agent string
- Agent that owns the Slack channel
- -o, --org string
- Org that owns the Slack channel
Example
$ valet channels slack add '#support' --agent my-agent
Added the bot to #support (activity: mentions)
$ valet channels slack add '#leadership' --activity all --agent my-agent
#leadership is private -- the bot can't self-join.
Invite it from the conversation with: /invite @<your-bot>valet channels slack set
Set one conversation's activity level
valet channels slack set <#conversation> <level> [flags]Set the agent's activity level for a single Slack conversation, overriding the channel default for it alone.
The conversation may be given as "#name" or as a raw Slack ID; a name is resolved against the bot's current conversations. Valid levels are "mentions" (only @-mentions), "emails" (@-mentions and forwarded emails), and "all" (every message).
- -a, --agent string
- Agent that owns the Slack channel
- -o, --org string
- Org that owns the Slack channel
Example
$ valet channels slack set '#support' all --agent my-agent
Set #support activity to allvalet channels slack set-default
Set the channel default activity level
valet channels slack set-default <level> [flags]Set the default activity level for the agent's Slack channel.
The default is a template stamped onto each conversation when the bot joins it. Changing the default does not re-point conversations the bot is already in -- use "valet channels slack set" for those.
Valid levels are "mentions" (only @-mentions wake the agent), "emails" (@-mentions and forwarded emails), and "all" (every message).
- -a, --agent string
- Agent that owns the Slack channel
- -o, --org string
- Org that owns the Slack channel
Example
$ valet channels slack set-default emails --agent my-agent
Set default activity to emails for team-botvalet channels token
Manage MCP channel tokens
valet channels token [command]Mint, list, and revoke bearer tokens for MCP channels.
MCP channels authenticate clients with bearer credentials. Each token carries an optional tool grant, expiry, and rate limit. The plaintext value is shown exactly once, at mint time.
- -a, --agent string
- Agent that owns the channel
- -o, --org string
- Org that owns the channel
Example
$ valet channels token mint my-mcp ci
$ valet channels token list my-mcp
$ valet channels token revoke my-mcp civalet channels token list
List tokens on an MCP channel
valet channels token list <channel> [flags]List the bearer credentials minted for an MCP channel.
Shows each token's name, tool grant, rate limit, expiry, status (active, expired, or revoked), and creation time. Plaintext token values are never shown after minting.
When no --org or --agent flag is provided, uses the linked agent in the current directory.
- -a, --agent string
- Agent that owns the channel
- -o, --org string
- Org that owns the channel
Example
$ valet channels token list my-mcp
Tokens for my-mcp on my-agent agent in acme org:
NAME TOOLS RATE LIMIT EXPIRES STATUS CREATED
ci all - - active Fri May 1, 2026 9:00 AM UTC
zapier search,fetch 30 Fri Jul 10, 2026 12:00 AM UTC active Fri May 1, 2026 9:00 AM UTCvalet channels token mint
Mint a bearer token for an MCP channel
valet channels token mint <channel> <token-name> [flags]Mint a bearer credential for an MCP channel.
The plaintext token is printed exactly once; store it securely. Use --tools to narrow the credential to specific tools, --expires to set an expiry, and --rate-limit to cap tool calls per minute. Tool names include the built-in "ask_<agent>" tool and any tools the agent defines in mcp/<tool>.md.
When no --org or --agent flag is provided, uses the linked agent in the current directory.
- --expires string
- Expiry as a Go duration (e.g. 720h) or an RFC 3339 timestamp (default: never)
- --rate-limit int32
- Tool calls per minute (default: 0, unlimited)
- --tools stringSlice
- Tools the token may call, comma-separated or repeated (default: all tools)
- -a, --agent string
- Agent that owns the channel
- -o, --org string
- Org that owns the channel
Example
$ valet channels token mint my-mcp ci --tools search,fetch --expires 720h
Minting token for my-mcp on my-agent agent in acme org... done, ci
expires: Fri Jul 10, 2026 12:00 PM UTC
This token will not be shown again. Store it securely:
vlt_abc123...valet channels token revoke
Revoke a token on an MCP channel
valet channels token revoke <channel> <token-name> [flags]Revoke a bearer credential on an MCP channel.
Revocation is immediate and permanent: clients holding the token lose access on their next request. Mint a new token to restore access.
When no --org or --agent flag is provided, uses the linked agent in the current directory.
- -a, --agent string
- Agent that owns the channel
- -o, --org string
- Org that owns the channel
Example
$ valet channels token revoke my-mcp ci
Revoking token ci for my-mcp on my-agent agent in acme org... donevalet channels update
Change a channel's cadence or an app channel's path
valet channels update <name> [flags]Change a heartbeat or cron channel's cadence, or move a channel on an app to another path.
--path moves the channel's deliveries to another path in the app. The app is not restarted. --every, --schedule, --cron, and --timezone replace a heartbeat's or cron channel's cadence, for an agent or an app.
When no --agent or --app flag is provided, uses the linked agent or app in the current directory.
- -a, --agent string
- Agent that owns this channel
- --app string
- App that owns this channel (same as --agent)
- --cron string
- New raw crontab expression
- --every string
- New heartbeat interval, such as 15m
- -o, --org string
- Org that owns this channel
- --path string
- New path in the app that handles each delivery
- --schedule string
- New human-readable cron schedule
- --timezone string
- New IANA timezone
Example
$ valet channels update stripe --app my-app --path /webhooks/stripe-v2
Updating stripe on my-app app in acme org... done
path: /webhooks/stripe-v2
$ valet channels update tick --every 2hvalet connectors
List connectors
valet connectors [flags]List, create, and manage connectors.
Connectors extend agents with external capabilities. There are two types:
mcp-server Provides tool access via MCP. Defines a transport
(stdio, sse, or streamable-http) and optionally a
command or URL.
command Wraps a CLI tool as a callable command. Defines a
command, optional args, and secret names. Secrets
are injected into the command's environment at
runtime -- the agent never sees the values.Each connector is scoped to an org or agent. Running "valet connectors" with no subcommand lists connectors for the linked agent.
- -a, --agent string
- Agent to list connectors for
- -o, --org string
- Org to list connectors for
- --sites
- List only connectors a site can hold (HTTP MCP servers)
valet connectors attach
Attach an org connector to an agent or site
valet connectors attach <connector-name> [flags]Attach an org connector to an agent or site.
Makes an org-level connector available to the target. An agent can use the connector's tools during sessions; a site serves the connector's tools to anyone who can open the page, so attaching hands the connector's full reach to everyone the page reaches. Use --agent or --site to name the target -- they are mutually exclusive. Use --as to give the attachment a custom alias (useful when attaching the same connector to multiple targets with different names).
A site holds only HTTP MCP servers -- an mcp-server connector on the sse or streamable-http transport. Attaching anything else to a site is refused; "valet connectors list --sites" shows the connectors a site can hold.
Use "valet connectors detach" to remove the attachment.
- -a, --agent string
- Agent to attach the connector to
- --as string
- Custom alias for the attachment
- -o, --org string
- Org that owns the connector
- --site string
- Site to attach the connector to
Example
$ valet connectors attach slack
Attaching slack to my-agent agent in acme org... done, slack
$ valet connectors attach slack --site reports
Attaching slack to reports site in acme org... done, slack
$ valet connectors attach slack --as slack-readonly
Attaching slack to my-agent agent in acme org... done, slack-readonlyvalet connectors call
Run one of a connector's tools and print the answer
valet connectors call <connector-name> <tool> [flags]Run one of a connector's tools and print the answer.
Sample a connector before you build against it. A tool's schema says what it accepts; only a real call says what it answers, and the answer is usually the part that decides how a page or an agent has to parse it -- a markdown table, a single meta-tool taking a "command" string, or a 401 from a credential whose scope covers only some of the tools.
The loop is: "valet connectors list --sites" to see what the org has, "valet connectors attach" to give the target one, "valet sites info --schemas" (or the list_connector_tools MCP tool, for an MCP caller) to read the attached tools and their argument schemas, then this command to see one tool's real answer. "valet sites info" without --schemas prints each attachment's status and its tool names, but not the schemas. Use --agent or --site to name the target -- they are mutually exclusive, and the target must already hold the connector.
Only an HTTP MCP server can be called: a command connector and a stdio MCP server run inside an agent's container, where Valet cannot reach them. The connector's answer is printed to stdout verbatim. A tool that answers with an error prints that error and exits 1.
- -a, --agent string
- Agent holding the connector
- --args string
- JSON object of arguments for the tool (default: {})
- -o, --org string
- Org that owns the connector
- --site string
- Site holding the connector
Example
$ valet connectors call posthog exec --args '{"command":"docs"}' --site reports
| path | views |
| ----------- | ----- |
| /pricing | 1204 |
| /docs | 871 |
$ valet connectors call linear search --agent triage
No issues match.valet connectors catalog
List connector catalog entries
valet connectors catalog [flags]List available connector catalog entries.
The connector catalog contains Valet-curated connector definitions for well-known services. Use "valet connectors catalog get <name>" for details on a specific entry. Use "valet connectors create <name>" to provision a connector from the catalog.
Example
$ valet connectors catalog
github mcp-server GITHUB_TOKEN GitHub MCP server (stdio)
slack mcp-server SLACK_TOKEN Slack MCP server (stdio)valet connectors catalog get
Show catalog entry details
valet connectors catalog get <name> [flags]Show detailed information about a connector catalog entry.
Displays the entry's transport, command, arguments, and required secret slots.
Example
$ valet connectors catalog get github
Name: github
Type: mcp-server
Transport: stdio
Command: npx
Args: -y @modelcontextprotocol/server-github
Slots:
GITHUB_TOKEN GitHub personal access tokenvalet connectors create
Create a connector
valet connectors create <entry> [flags]Create a connector from the catalog or by type.
If the first argument matches a catalog entry, provisions a connector using that entry's default configuration. Use --as to give the connector a custom name.
If the first argument is not a catalog entry, use one of the type-specific subcommands to create a connector:
valet connectors create mcp-server <name> valet connectors create command <name>
When no --agent or --org flag is provided, uses the linked agent in the current directory.
An entry's secret slots resolve to env vars in the connector's scope. An agent-scoped connector reads each slot under the slot's own name. An org-scoped connector binds each slot to an env var named for the connector, so a second connector from the same entry can hold its own credentials. Before creating anything, this command asks the server which of those env vars it requires and refuses when one is unset, naming the "valet env set" command that fills it. An OAuth or Composio entry needs none, because its credential comes from the provider.
Use "valet connectors catalog" to browse available catalog entries.
- -a, --agent string
- Agent to create the connector for
- --as string
- Custom name for a catalog connector
- -o, --org string
- Org to create the connector for
- --secret-name string
- Name of an existing secret-kind env var (from valet env) whose value an API-key connector forwards to the provider at connect time
Example
# Add a connector from the catalog:
$ valet connectors create github --agent my-agent
Creating mcp-server connector on my-agent agent in acme org... done, github
# Catalog entry with a custom name:
$ valet connectors create github --as github-readonly --org acme
Creating mcp-server connector in acme org... done, github-readonly
# A second connector from an entry with a secret slot, in an org:
# the create refuses until the bound secret exists.
$ valet connectors create luma-mcp --as luma-mcp-2 --org acme
Error: luma-mcp-2 needs a secret before it can be created.
valet env set LUMA_MCP_2_LUMA_API_KEY=... --org acme
$ valet env set LUMA_MCP_2_LUMA_API_KEY=sk_live_... --org acme
$ valet connectors create luma-mcp --as luma-mcp-2 --org acme
Creating mcp-server connector in acme org... done, luma-mcp-2
# API-key catalog connector: reference a secret env var set beforehand
# (its value is forwarded to the provider, not stored on the connector):
$ valet env set EXA_API_KEY=exa_live_... --agent my-agent
$ valet connectors create exa-composio --agent my-agent --secret-name EXA_API_KEY
Creating mcp-server connector on my-agent agent in acme org... done, exa-composio
# MCP server connector with stdio transport:
$ valet connectors create mcp-server slack --transport stdio \
--command npx --args=-y,server-slack \
--env SLACK_BOT_TOKEN={{SLACK_BOT_TOKEN}} \
--env SLACK_TEAM_ID={{SLACK_TEAM_ID}}
Creating mcp-server connector on my-agent agent in acme org... done, slack
# Command connector:
$ valet connectors create command gh \
--command gh --secrets GITHUB_TOKEN
Creating command connector on my-agent agent in acme org... done, ghvalet connectors create command
Create a command connector
valet connectors create command <name> [flags]Create a command connector that wraps a CLI tool.
Command connectors require --command and accept --args and --secrets. The --secrets flag takes a comma-separated list of secret names that are injected when the command runs. The agent never sees secret values directly.
When no --agent or --org flag is provided, uses the linked agent in the current directory.
- --args stringSlice
- Command arguments
- --command string
- Command to run
- --secrets stringSlice
- Secret names for command connectors (comma-separated)
- -a, --agent string
- Agent to create the connector for
- -o, --org string
- Org to create the connector for
Example
# Command connector:
$ valet connectors create command gh \
--command gh --secrets GITHUB_TOKEN
Creating command connector on my-agent agent in acme org... done, gh
# Command connector with args and multiple secrets:
$ valet connectors create command aws \
--command aws --args s3,ls \
--secrets AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY
Creating command connector on my-agent agent in acme org... done, awsvalet connectors create mcp-server
Create an MCP server connector
valet connectors create mcp-server <name> [flags]Create an MCP server connector with the specified transport and connection details.
Use --transport=stdio with --command for local processes, or --transport=sse/streamable-http with --url for remote servers.
Environment variables and headers can reference env vars using the {{NAME}} template syntax instead of embedding literal values. The connector stores the reference, and the control plane resolves it to the actual value at deploy time. Templates can appear anywhere in a value (e.g. https://{{HOST}}/api). Use "valet env set" to create env vars before referencing them.
An OAuth-protected remote server needs no credential flags. The control plane discovers the server's authorization endpoints, creates the connector in pending status, and this command opens your browser to complete the grant, then waits for the connector to go active.
When no --agent or --org flag is provided, uses the linked agent in the current directory.
- --args stringSlice
- Command arguments
- --command string
- Command to run
- --env stringSlice
- Environment variables as KEY=VAL pairs (use {{NAME}} to reference a secret)
- --header stringSlice
- HTTP headers as KEY=VAL pairs (use {{NAME}} to reference a secret)
- --transport string
- Transport type (stdio, sse, streamable-http)
- --url string
- Server URL (sse or streamable-http transport)
- -a, --agent string
- Agent to create the connector for
- -o, --org string
- Org to create the connector for
Example
# MCP server connector with stdio transport:
$ valet connectors create mcp-server slack --transport stdio \
--command npx --args=-y,server-slack \
--env SLACK_BOT_TOKEN={{SLACK_BOT_TOKEN}} \
--env SLACK_TEAM_ID={{SLACK_TEAM_ID}}
Creating mcp-server connector on my-agent agent in acme org... done, slack
# MCP server connector with SSE transport:
$ valet connectors create mcp-server api \
--transport sse --url https://example.com/sse \
--header Authorization={{API_KEY}}
Creating mcp-server connector on my-agent agent in acme org... done, api
# OAuth-protected MCP server: authorize in the browser:
$ valet connectors create mcp-server research --org acme \
--transport streamable-http --url https://mcp.example.com/mcp
Creating mcp-server connector in acme org... done, research (pending authorization)
Authorize the connector:
https://mcp.example.com/oauth/authorize?...
Waiting for authorization... donevalet connectors destroy
Destroy a connector
valet connectors destroy <name> [flags]Permanently destroy a connector.
Removes the connector from the agent. This action cannot be undone.
- -a, --agent string
- Agent that owns the connector
- -o, --org string
- Org that owns the connector
Example
$ valet connectors destroy slack
Destroying slack on my-agent agent in acme org... donevalet connectors detach
Detach a connector from an agent or site
valet connectors detach <alias> [flags]Detach a connector from an agent or site.
Removes an org connector attachment from the target. The target will no longer be able to use the connector's tools -- for a site, that means every page it serves loses access. The org connector itself is not deleted. Use --agent or --site to name the target -- they are mutually exclusive.
Use "valet connectors attach" to re-attach the connector.
- -a, --agent string
- Agent to detach the connector from
- -o, --org string
- Org that owns the connector
- --site string
- Site to detach the connector from
Example
$ valet connectors detach slack
Detaching slack from my-agent agent in acme org... done
$ valet connectors detach slack --site reports
Detaching slack from reports site in acme org... donevalet connectors info
Show connector details
valet connectors info <name> [flags]Show detailed information about a connector.
Displays the connector's type, transport, status, command or URL, arguments, environment variables (with {{NAME}} secret references), HTTP headers, secrets and whether each is set, and catalog origin.
Status is "active" or "pending"; a pending connector is still waiting for its first OAuth authorization and every tool call fails until the grant lands. Auth status reports credential health for a connector that holds credentials: pending, active, needs_reauth, or revoked. A connector with nothing to authorize omits the line. Auth reason carries the provider's diagnostic when the grant broke. Run "valet connectors reauthorize <name>" to restore a grant that was revoked or never finished.
A "Secrets" section lists each env var the connector reads, marked "set" or "not set" in the connector's scope. An agent-scoped connector counts a variable set on the agent or on its org. The section is absent for a connector that reads no secrets.
- -a, --agent string
- Agent that owns the connector
- -o, --org string
- Org that owns the connector
Example
$ valet connectors info slack
=== Connector: slack on my-agent agent in acme org
Name: slack
Type: mcp-server
Transport: stdio
Status: active
Command: npx
Args: -y server-slack
# A connector whose OAuth authorization never completed:
$ valet connectors info research --org acme
=== Connector: research in acme org
Name: research
Type: mcp-server
Transport: streamable-http
Status: pending
Auth status: pending
URL: https://mcp.example.com/mcp
# A second Luma connector in the same org, with its own bound secret:
$ valet connectors info luma-mcp-2 --org acme
=== Connector: luma-mcp-2 in acme org
Name: luma-mcp-2
Type: mcp-server
Transport: streamable-http
Status: active
URL: https://mcp.lumalabs.ai/mcp
Secrets:
LUMA_MCP_2_LUMA_API_KEY setvalet console
Start an interactive console session
valet console [flags]Start an interactive console session with an agent.
Opens a REPL-style session connected to the agent via the gateway's console channel. The agent is determined by the --agent flag or the linked agent in the current directory. If the agent is still starting, waits for it to become ready before opening the session.
Use --resume <session-id> to continue an existing session; the CLI verifies the session exists before opening the REPL.
- -a, --agent string
- Agent to connect to (uses linked agent if omitted)
- -o, --org string
- Org that owns the agent
- -r, --resume string
- Resume an existing session by ID
$ valet console --agent my-agent
$ valet console --agent my-agent --resume sess-abcvalet deploy
Deploy an agent
valet deploy [flags]Deploy the current directory as a new release for an agent, app, site, or skill.
Creates a push on the service, commits the directory on top of the service's source, pushes that commit with Git, and publishes it. The service is determined by the --agent flag or the linked service in the current directory. Git 2.32 or later must be on your PATH.
The bundle is every regular file under the current directory, walked recursively. Only .git and .valet are skipped at any depth, symbolic links and other special files are skipped, and there is no ignore file. Build output, node_modules, vendored dependencies, datasets, and media all ship to the service's repo if they sit in the directory. Move them out first. Deploy refuses a file over the service's per-file limit, naming it, before it pushes anything.
Deploy never touches a repository in the directory and ignores your Git configuration, hooks, attributes, and filters. It keeps a cache of the service's source in your user cache directory, so a deploy pushes only what changed. Deleting the cache is always safe.
After deploying an app, waits for its processes: it prints a line each time one changes state, then exits 0 once every process is up on the new release, and exits 1 if one crashes or --wait-timeout passes. An app whose processes are all idle exits 0 and starts on its next request. If a later release replaces this one, deploy says so and exits 0: the later release builds on this commit. If a newer deploy replaces the build before it makes a release, deploy says nothing was deployed and exits 1. --no-wait returns after the build starts and prints its id; "valet builds show <id> -f" follows it later.
For a skill, deploy publishes the directory as the skill's next release, as "valet skills publish" does, and prints the release number. It needs the directory's SKILL.md and waits for nothing else.
After deploying an agent, waits for the agent runtime to become ready. Use --no-wait to skip the readiness check and return immediately after the release is activated.
If your org has a policy that blocks, the release is not live until the policy passes. Deploy prints each policy's status and each blocking finding, then continues once the policies pass. It exits 1 and prints why when a policy blocks or errors, or when --wait-timeout passes. The previous release stays live. --no-wait says where to follow the policies and returns. Run "valet policies show" to follow them later.
If the local source is identical to the service's current source and a release has already deployed it, deploy exits 0 without re-releasing — there's nothing to ship. If nothing has deployed yet (for example an earlier build failed), deploy rebuilds the unchanged source so a retry isn't stuck; pass --force to rebuild unchanged source even when it has already deployed.
If the service changes while deploy runs, deploy builds the same directory on the new source and tries once more.
If the directory is linked to an anonymous site (a link naming the "try" org), deploy publishes through the anonymous-site path instead, authorized by the claim token in that directory's own .valet/config.json rather than by a login. It needs no Git. Claiming is not a precondition: an unclaimed anonymous site updates in place, and deploy prints the earliest moment the site may be removed and how to keep it. If it has since been claimed, the link is rewritten to the site's real org and name, the spent token is dropped in the same write, and the ordinary deploy proceeds.
If the manifest declares connectors or channels that aren't attached yet, deploy stops and lists what's missing. The dependencies are suggestions, not hard requirements — pass --allow-unsatisfied to deploy anyway (the agent runs without them until they're attached). A manifest that fails to parse is always a hard error that --allow-unsatisfied does not bypass. Server validation, required-skill gates, billing requirements, and build failures can still block deployment.
- -a, --agent string
- Agent, app, site, or skill to deploy (uses linked service if omitted)
- --allow-unsatisfied
- Deploy even if declared connectors/channels aren't attached yet (default: false)
- --app string
- App to deploy (same as --agent)
- --force
- Rebuild even when the source is unchanged (default: false)
- --no-wait
- Skip waiting for the agent to become ready or a policy to decide
- -o, --org string
- Org that owns the service
- --wait-timeout duration
- How long to wait for an app's processes to come up, and for policies to decide (default 15m for policies)
$ valet deploy --agent my-agent
Creating push for my-agent agent in acme org... done
Fetching source... done
Reading files... done, 12 files
Pushing source... done
Deploying my-agent agent in acme org... done, v3
Waiting for agent to start... done
$ valet deploy --agent my-agent --allow-unsatisfied
Creating push for my-agent agent in acme org... done
Fetching source... done
Reading files... done, 12 files
Pushing source... done
Deploying my-agent agent in acme org... done, v4
$ valet deploy --agent checkout
Creating push for checkout app in acme org... done
Fetching source... done
Reading files... done, 38 files
Pushing source... done
Starting build for checkout app in acme org... done
-----> Fetching source
-----> Detecting buildpacks
-----> Building
-----> Exporting bundle
-----> Uploading bundle
web.1 starting v1 → v2
web.1 up v2
Deployed v2
URL: https://checkout.acme.valet.run
$ valet deploy --agent support-bot
Deploying support-bot agent in acme org... done, v4
Waiting for policies (secrets)…
secrets running (block at high)
secrets blocked (block at high)
high config.yaml:3 AWS access key found (aws-key)
Fix: Remove the key and rotate it.
Error: acme's policies blocked support-bot's changes: secrets found 1 finding at high or above. Nothing was deployed; the current release is still live. Fix it and deploy again.valet drafts
List agent drafts
valet drafts [flags]List open drafts in scope, or operate on a single draft.
Drafts pair an agent with an editing session. The Architect opens a Blueprint draft when a user starts an edit, edits files via plain git over the URL the server mints, and publishes when done.
Run `valet drafts` with no subcommand to list open drafts in the current org. Pass --agent to filter to a single agent.
- --agent string
- Filter to drafts for a single agent (by name)
- -o, --org string
- Org to list drafts in
$ valet drafts
=== Drafts
drf_01J9... triage 2026-04-26T10:00:00Z
drf_01J9... digester 2026-04-26T11:30:00Zvalet drafts checkout
Clone the draft branch and print the working directory path
valet drafts checkout <draft_id> [flags]Clone the draft branch to a local working directory and print the absolute path of that directory on stdout.
The working directory is placed under the system temp directory, one directory per draft id:
$TMPDIR/valet-drafts/<draft-id>/
Keying by draft id gives each draft its own tree, so two concurrent editing sessions for different agents' drafts never collide. The runtime is ephemeral, so /tmp gets reaped along with the container — no cleanup is needed.
Running checkout again lays down a fresh tree at the current branch tip, discarding any uncommitted local drift. Push before re-running checkout if you have work to keep.
Inside the agent runtime the working tree is owned by the valet user (the agent's own identity) so the agent can edit it in place; the git work is performed by the setuid-root valet-draft-git helper, which keeps the org token isolated in the sandboxed valet-worker user. On a developer machine the checkout is owned by the caller.
The branch cloned is draft/<draft-id> on the ephemeral namespace. The server's ephemeral namespace has no main, so a normal clone would fail — this command uses --single-branch --branch to clone only the draft ref.
Designed for shell composition with cd:
cd "$(valet drafts checkout drf_X)"
Diagnostics (draft id and agent name) go to stderr so stdout contains only the path.
Example
$ valet drafts checkout drf_01J9...
/tmp/valet-drafts/drf_01J9...
draft drf_01J9... on my-agent
$ cd "$(valet drafts checkout drf_01J9...)"valet drafts create
Open a new draft for an agent
valet drafts create [flags]Open a fresh editing draft in an agent's source repository and print the new draft id on stdout.
A draft is an ephemeral branch forked from the agent's main HEAD. Use this to start an out-of-band edit that you review before publishing, rather than `valet deploy` (which opens a draft, pushes the current directory, publishes, and deploys in one shot). The draft id this prints feeds the per-draft subcommands:
drf=$(valet drafts create --agent my-agent) cd "$(valet drafts checkout "$drf")" $EDITOR skills/some-skill/SKILL.md valet drafts push "$drf" valet drafts publish "$drf" valet deploy --agent my-agent
The agent is determined by the --agent flag or the linked agent in the current directory. An agent may have at most one open draft; if one already exists this errors with the existing draft's id unless you pass --force, which discards it first.
The draft id is the only thing on stdout (so it composes with checkout); status and diagnostics go to stderr.
- -a, --agent string
- Agent to open a draft for (uses linked agent if omitted)
- --force
- Discard any existing open draft and proceed (default: false)
- -o, --org string
- Org that owns the agent
Example
$ valet drafts create --agent my-agent
Opening draft for my-agent agent... done
drf_01J9...
draft drf_01J9... on my-agent (base abc1234)valet drafts discard
Delete a draft without publishing
valet drafts discard <draft_id> [flags]Delete the draft and its ephemeral branch. Idempotent at the row level — a missing draft yields NotFound from the server.
Example
$ valet drafts discard drf_01J9...
Discarded.valet drafts info
Show draft detail
valet drafts info <draft_id> [flags]Show metadata for a single draft: agent, session, base commit, timestamps. Run `valet drafts checkout` to get a clone URL for editing.
Example
$ valet drafts info drf_01J9...
=== Draft: drf_01J9...
Agent: triage (019d...)
Session: 019d...
Base commit: abc123
Created: 2026-04-26T10:00:00Z
Updated: 2026-04-26T10:00:00Zvalet drafts publish
Promote a draft to main
valet drafts publish <draft_id> [flags]Promote the draft's ephemeral branch to main and report any catalog dependencies that need installing or attaching before the agent can deploy.
When the manifest declares connectors or channels that aren't yet installed in the org, the response status is "needs_configuration" and the pending lists tell the configure flow what to set up next.
Example
$ valet drafts publish drf_01J9...
Status: deployablevalet drafts push
Ship local files to a draft branch
valet drafts push <draft_id> [flags]Walk a directory of agent source and ship its contents to the draft branch via the server's PushDraftFiles RPC. The server commits the changed files; nothing is published. Use this to iterate on a draft without promoting it to main — for example, the Architect pushes after each user-visible edit so the dashboard's draft view refreshes.
The directory is walked recursively and every regular file is sent. Only .git and .valet are skipped, and there is no ignore file. Keep build output and dependency trees out of the directory. Push refuses any single file over 25 MiB, naming it, before it uploads anything.
Plain `git push` against a draft clone URL does not work for draft branches: the ephemeral endpoint advertises only ephemeral refs, so a local pack builder cannot enumerate ancestors across the ephemeral / non-ephemeral namespaces. `drafts push` sidesteps the namespace question by sending file contents directly and letting the server build the commit.
When the working directory matches the draft tip exactly, the server returns no_changes and this command exits 0 without publishing a commit.
- --dir string
- Directory to ship (defaults to the draft's checkout dir in the agent runtime, else the current directory)
- -m, --message string
- Commit message (defaults to server's "Update draft")
Example
$ valet drafts push drf_01J9... --dir ./my-agent
Pushed, commit abc1234
$ valet drafts push drf_01J9...
No changes.valet drafts validate
Verify the draft's valet.yaml parses against the manifest schema
valet drafts validate [draft-id] [flags]Verify the draft's valet.yaml parses against the manifest schema. Run this after editing files and before `valet drafts push`.
When a draft-id is provided the command also checks that the current Git branch matches the draft's branch — "draft/<draft-id>", the branch `valet drafts checkout` lays the working tree down on. A mismatch is reported as an additional error. Validating a copied working tree (one not on the draft branch) should omit the draft-id and pass --dir instead, which runs schema validation only.
Exits 0 when the manifest is valid (and the branch matches, if a draft-id was supplied). Exits 1 and prints each error prefixed with "error:" when validation fails.
- --dir string
- Directory containing valet.yaml (defaults to current directory)
Example
$ valet drafts validate drf_01J9...
valet.yaml is valid
$ valet drafts validate --dir ./my-agent
error: channels[0]: every is required for heartbeat channelsvalet drains
List drains
valet drains [flags]List, create, and manage drains for an org or a service.
A drain forwards telemetry to an OpenTelemetry endpoint. A drain carries logs and traces. An org drain receives every site, app, agent, and skill in the org. Each drain has a name and can include custom headers for authentication.
Running "valet drains" with no subcommand lists the drains for the linked service, including its org's drains, or for the org with --org alone. Each row shows the endpoint, the signals, the status, and the name. Only an Admin sees an org drain's endpoint and headers; anyone else sees "(hidden)".
- -a, --agent string
- Agent or app name (uses linked service if omitted)
- --app string
- App name (same as --agent)
- -o, --org string
- Org; alone, names the org's drains
valet drains create
Create a drain
valet drains create <url> [flags]Create a drain for an org or a service.
Give a base URL to store its /v1/logs and /v1/traces endpoints, or a URL ending in /v1/logs to store a logs endpoint alone. The drain carries logs and traces. The endpoints must be https URLs. Use --header to include authentication headers.
Use --name to tell drains apart, such as "Honeycomb". Without it, the drain is named after its endpoint's host. Names are unique in the service or org.
With --org alone, the drain is an org drain: every service in the org sends to it, and only an Admin can create one. Otherwise the drain is the service's.
With --org alone, requires the Admin role.
- -a, --agent string
- Agent or app name (uses linked service if omitted)
- --app string
- App name (same as --agent)
- --header stringSlice
- HTTP headers as Key=Value pairs
- --logs-endpoint string
- Logs URL, overriding the derived one
- --name string
- Drain name; defaults to the endpoint's host
- -o, --org string
- Org; alone, creates an org drain
- --signals stringSlice
- Signals to send: logs, traces, metrics
- --traces-endpoint string
- Traces URL, overriding the derived one
Example
$ valet drains create https://otlp.example.com --header Authorization=Bearer\ tok123
Creating drain on my-agent agent in acme org... done
name: otlp.example.com
logs: https://otlp.example.com/v1/logs
traces: https://otlp.example.com/v1/traces
status: active
headers: Authorization
$ valet drains create https://otlp.example.com --org acme --signals logs --name Honeycomb
Creating drain on acme org... done
name: Honeycomb
logs: https://otlp.example.com/v1/logs
status: activevalet drains destroy
Destroy a drain
valet drains destroy <url-or-name> [flags]Permanently destroy a drain.
Removes the drain the argument names: one of its endpoints, the base URL they derive from, or, when no endpoint matches, the drain's name. With --org alone, destroys an org drain, which only an Admin can do. An org drain cannot be destroyed from a service.
With --org alone, requires the Admin role.
- -a, --agent string
- Agent or app name (uses linked service if omitted)
- --app string
- App name (same as --agent)
- -o, --org string
- Org; alone, destroys an org drain
Example
$ valet drains destroy https://otlp.example.com
Destroying drain on my-agent agent in acme org... donevalet drains info
Show drain details
valet drains info <url-or-name> [flags]Show detailed information about a drain.
Displays the drain's name, scope, endpoints, status, header names, and creation timestamp. The argument names one of the drain's endpoints, the base URL they derive from, or, when no endpoint matches, the drain's name. A service's drains include its org's.
Only an Admin sees an org drain's endpoints and header names. Anyone else sees its name, scope, signals, status, and creation time.
With --org alone, shows an org drain.
- -a, --agent string
- Agent or app name (uses linked service if omitted)
- --app string
- App name (same as --agent)
- -o, --org string
- Org; alone, names the org's drains
Example
$ valet drains info https://ingest.example.net
=== Drain (acme org)
name: ingest.example.net
scope: org
logs: https://ingest.example.net/v1/logs
traces: https://ingest.example.net/v1/traces
status: active
headers: Authorization
created at: 2026-11-10T15:57:49Zvalet emails
List email mailboxes
valet emails [flags]List, create, inspect, and destroy email mailboxes.
An email mailbox is an org-owned primitive that stores email threads and messages. Creating one mints an address on valet.run; mail sent to that address lands in the mailbox, and binding an email channel wakes an agent on inbound mail. Mailboxes are named by their address everywhere — internal UUIDs never surface. Threads and quarantined messages are named by their RFC 5322 Message-ID, accepted with or without the surrounding angle brackets.
Running "valet emails" with no subcommand lists mailboxes for the org.
- -o, --org string
- Org to list mailboxes for
$ valet emails --org acme
Mailboxes in acme org:
ADDRESS DISPLAY NAME CREATED
quiet-meadow-x7k2@valet.run Docs inbox 2026-07-21T00:00:00Zvalet emails create
Create an email mailbox and mint its address
valet emails create [flags]Create an org-owned email mailbox and mint its address.
The address mints inside the org's namespace. Without --local-part a random haiku local-part is generated; with it, you choose the address's local part (subject to the reserved list). The printed status reports the org email identity's readiness: provisioning (records pending), inbound_ready (receiving; sending pending identity verification), or ready (receiving and sending).
Without --name the display name defaults to the local-part. When no --org flag is provided, uses the default org.
Requires the Admin role.
- --local-part string
- Chosen local part for the address (default: a generated haiku)
- --name string
- Display name for the mailbox (default: the minted local-part)
- -o, --org string
- Org that owns the mailbox
Example
$ valet emails create --name "Docs inbox" --org acme
Creating mailbox in acme org... done, quiet-meadow-x7k2@valet.runvalet emails destroy
Destroy an email mailbox
valet emails destroy <address> [flags]Permanently destroy an email mailbox by its address.
This action cannot be undone. The address is tombstoned forever (never re-minted), inbound mail stops, and a bound email channel is soft-deleted with the mailbox — the two share a lifecycle. When no --org flag is provided, uses the default org.
Requires the Admin role.
- -o, --org string
- Org that owns the mailbox
Example
$ valet emails destroy quiet-meadow-x7k2@valet.run --org acme
Destroying quiet-meadow-x7k2@valet.run in acme org... donevalet emails info
Show mailbox details
valet emails info <address> [flags]Show detailed information about an email mailbox by its address.
Displays the mailbox's display name, creation time, and its thread, message, and quarantine counts. When no --org flag is provided, uses the default org.
- -o, --org string
- Org that owns the mailbox
Example
$ valet emails info quiet-meadow-x7k2@valet.run --org acme
=== Mailbox: quiet-meadow-x7k2@valet.run in acme org
display name: Docs inbox
created: 2026-07-21T00:00:00Z
threads: 3
messages: 7
quarantine: 2valet emails quarantine
List quarantined messages
valet emails quarantine [<address>] [flags]List the org's quarantined inbound messages — the spam folder.
Pass a mailbox address to narrow the list to one mailbox. Quarantined messages are stored but not delivered to the agent; release one with "valet emails quarantine release" to re-run ingest (the "not spam" button). When no --org flag is provided, uses the default org.
- -o, --org string
- Org that owns the mailboxes
Example
$ valet emails quarantine --org acme
Quarantined messages in acme org:
MESSAGE-ID MAILBOX FROM SUBJECT CREATED
spam@host quiet-meadow-x7k2@valet.run spammer@example.com You won 2026-07-21T00:00:00Zvalet emails quarantine release
Release a quarantined message
valet emails quarantine release <message-id> [flags]Release a quarantined message by its RFC 5322 Message-ID, re-running ingest (the "not spam" button).
Releasing re-runs the inbound pipeline for the message: it is threaded, stored, and — if the mailbox has a bound channel — wakes the agent. The Message-ID is accepted with or without the surrounding angle brackets, so shell quoting is never a trap. When no --org flag is provided, uses the default org.
Requires the Admin role.
- -o, --org string
- Org that owns the mailbox
Example
$ valet emails quarantine release '<spam@host>' --org acme
Releasing message... donevalet emails threads
List a mailbox's threads
valet emails threads <address> [flags]List the threads in an email mailbox by the mailbox address.
Each row shows the thread's root RFC 5322 Message-ID, subject, message count, and last-message time. Pass a Message-ID to "valet emails threads info" to read a single thread. When no --org flag is provided, uses the default org.
- -o, --org string
- Org that owns the mailbox
Example
$ valet emails threads quiet-meadow-x7k2@valet.run --org acme
Threads in quiet-meadow-x7k2@valet.run:
MESSAGE-ID SUBJECT MESSAGES LAST
abc@host Invoice 4 2026-07-21T00:00:00Zvalet emails threads info
Show a thread by its root Message-ID
valet emails threads info <message-id> [flags]Show a single email thread and its messages by the thread's root RFC 5322 Message-ID.
The Message-ID is accepted with or without the surrounding angle brackets, so shell quoting is never a trap. Messages are listed in delivery order. When no --org flag is provided, uses the default org.
- -o, --org string
- Org that owns the mailbox
Example
$ valet emails threads info '<abc@host>' --org acme
=== Thread: abc@host
subject: Invoice
mailbox: quiet-meadow-x7k2@valet.run
last: 2026-07-21T00:00:00Z
MESSAGE-ID FROM DIRECTION STATUS CREATED
abc@host sender@example.com inbound ingested 2026-07-21T00:00:00Zvalet env
List env vars
valet env [flags]Manage environment variables for orgs, agents, and apps.
Env vars come in two kinds. Secret vars (the default) hold credentials used by connectors and channels at runtime -- the agent can invoke tools that depend on them but never sees the values. Plain vars are delivered to the agent's environment as ordinary unix environment variables, readable from bash ($NAME) and from code the agent writes, and their values are displayed in list output.
Reference an env var of either kind in a connector with {{NAME}} syntax:
valet env set GITHUB_TOKEN=ghp_xxx
valet connectors create gh --transport command \
--command gh --env GITHUB_TOKEN={{GITHUB_TOKEN}}Each env var is scoped to either an org or a service (an agent, app, or site), and a name is unique within its scope across both kinds. Use --org to manage org-scoped env vars. Use --agent or --app (or run from a linked directory) to manage a service's env vars; --app is the same flag under the name an app owner expects.
Running "valet env" with no subcommand lists env vars.
Listing a service shows the effective environment it sees: its own vars plus the org vars it inherits, each tagged with its kind and scope. The scope names the service's kind, so an app's own vars read "app". When a service's var has the same name as an org var, the service value wins and the row is marked "overrides org". Plain values are shown inline; secret values are masked.
- -a, --agent string
- Agent to list env vars for
- --app string
- App to list env vars for (same as --agent)
- -o, --org string
- Org to list env vars for
$ valet env --agent abb-luma-bot
Environment for abb-luma-bot agent in valetdotdev org:
GITHUB_TOKEN secret ••• agent (overrides org)
REGION plain us-east-1 org (inherited)
STRIPE_API_KEY secret ••• org (inherited)
$ valet env --app checkout
Environment for checkout app in acme org:
DATABASE_HOST secret ••• app
DATABASE_URL secret ••• app
STRIPE_API_KEY secret ••• org (inherited)valet env set
Set env vars
valet env set <NAME=VALUE>... [flags]Create or update one or more env vars for an org, agent, or app.
Env vars are secret by default: the agent can invoke tools that depend on them but never sees the values. Pass --plain for values the agent should read directly from its environment (a region, a base URL, a customer identifier). Plain values are displayed in list output; secret values never are.
Sets the named env vars in a single atomic operation -- either all are persisted or none are. All vars in one invocation share a kind. Values are encrypted before storage. Setting an env var that already exists overwrites its value, and changes its kind in place when you pass the other kind.
Env vars of either kind can be referenced by connectors and channels via {{NAME}}. Plain vars are additionally delivered to the agent's environment, readable from bash ($NAME) and from code the agent writes.
Use --org to set org-scoped env vars. Use --agent or --app (or run from a linked directory) to set a service's env vars. When you belong to multiple orgs with services of the same name, pass --org as well to disambiguate.
Waits for the agent or app to become ready after setting its env vars. Use --no-wait to skip the readiness check.
With --org, requires the Admin role.
- -a, --agent string
- Agent to set the env var for
- --app string
- App to set the env var for (same as --agent)
- --no-wait
- Skip waiting for the agent or app to become ready
- -o, --org string
- Org to set the env var for
- --plain
- Set kind plain: deliver values to the agent environment and display them (default: secret)
Example
$ valet env set GITHUB_TOKEN=ghp_abc123
Setting GITHUB_TOKEN on my-agent agent in acme org... done
Set GITHUB_TOKEN (secret)
Waiting for agent to start... done
$ valet env set REGION=us-east-1 --plain --agent my-agent
Setting REGION on my-agent agent... done
Set REGION (plain)
Waiting for agent to start... done
$ valet env set LOG_LEVEL=debug --plain --app checkout
Setting LOG_LEVEL on checkout app... done
Set LOG_LEVEL (plain)
Waiting for app to start... done
$ valet env set A=1 B=2 C=3 --plain --org my-org
Setting A, B, C in my-org org... done
Set 3 env vars (plain)valet env unset
Unset an env var
valet env unset <NAME> [flags]Remove an env var for an org, agent, or app.
Deletes the named env var of either kind and reports the kind that was removed. If the var is referenced by a connector or channel (via {{NAME}}), or an org var by a checker's header, the command fails unless --force is passed.
Use --org to remove an org-scoped env var. Use --agent or --app (or run from a linked directory) to remove a service's env var. When you belong to multiple orgs with services of the same name, pass --org as well to disambiguate.
Waits for the agent or app to become ready after removing its env var. Use --no-wait to skip the readiness check.
With --org, requires the Admin role.
- -a, --agent string
- Agent to unset the env var for
- --app string
- App to unset the env var for (same as --agent)
- --force
- Force unset even if referenced by connectors, channels, or checkers
- --no-wait
- Skip waiting for the agent or app to become ready
- -o, --org string
- Org to unset the env var for
Example
$ valet env unset REGION
Unsetting REGION on my-agent agent in acme org... done
Unset REGION (plain)
Waiting for agent to start... done
$ valet env unset SLACK_TOKEN --agent my-agent
Unsetting SLACK_TOKEN on my-agent agent... done
Unset SLACK_TOKEN (secret)
Waiting for agent to start... done
$ valet env unset LOG_LEVEL --app checkout
Unsetting LOG_LEVEL on checkout app... done
Unset LOG_LEVEL (plain)
Waiting for app to start... done
$ valet env unset API_KEY --org my-org
Unsetting API_KEY in my-org org... done
Unset API_KEY (secret)valet logs
Show recent logs for an agent or app
valet logs [flags]Show recent log records from an agent or app.
By default, prints the last 100 historical log lines and exits. Use -n to change the number of lines or -n 0 to skip history entirely. Pass -f/--follow to keep the stream open and tail live log records until interrupted with Ctrl+C.
The service is determined by the --agent or --app flag or the linked service in the current directory. --app is the same as --agent.
- -a, --agent string
- Agent or app to show logs for (uses linked service if omitted)
- --app string
- App to show logs for (same as --agent)
- -f, --follow
- Stream log records as they arrive (default: dump and exit)
- -n, --num int32
- Number of historical log lines to show (0 to skip history; default: 100)
- -o, --org string
- Org that owns the agent or app
$ valet logs --agent my-agent
2026-02-23T10:15:32Z agent web.1 INFO Starting request handler
2026-02-23T10:15:33Z valet web.1 INFO Request processed
$ valet logs -a my-agent -n 10
$ valet logs -a my-agent -n 1000 -f
Streaming logs for my-agent agent in acme org...
$ valet logs -a my-agent -n 0 -f
$ valet logs --app checkout -n 0 -f
Streaming logs for checkout app in acme org...valet manifests
Create and inspect agent manifest files
Create, validate, and inspect valet.yaml manifest files.
Run subcommands to generate a manifest for an existing agent or to check that a manifest conforms to the schema (including story and per-service UI copy constraints).
valet manifests create
Generate a valet.yaml for an existing agent
valet manifests create [name] [flags]Generate a minimal valet.yaml for an existing agent by reading the agent's current configuration from the API.
Writes valet.yaml to the current directory (or --dir). Refuses to overwrite an existing manifest. The agent is determined by the positional argument, the --agent flag, or the linked agent in the current directory.
The generated manifest populates name, connectors, and channels from the API and leaves placeholder values for display_name, description, and category — these are not stored on the agent record and need to be filled in by hand before the manifest can be validated.
Only catalog-backed connectors and channels are emitted. Agent-owned (non-catalog) entries and inline cron/heartbeat channels are skipped and need to be added by hand.
- -a, --agent string
- Agent to generate a manifest for (uses linked agent if omitted)
- --dir string
- Directory to write valet.yaml into (default: cwd)
- -o, --org string
- Org that owns the agent
Example
$ valet manifests create my-agent
Wrote /path/to/valet.yaml
Fill in display_name, description, and category before publishing.
$ valet manifests create my-agent --dir /tmp/agent-checkoutvalet manifests validate
Validate a manifest file
valet manifests validate [path] [flags]Validate a valet.yaml manifest in two passes.
The schema pass checks syntax, required fields, unknown fields, and the story and per-service UI constraints. The online pass then resolves every connector and channel 'catalog:' reference by name against the control-plane catalog — the same name lookup the attach/deploy path runs. This closes the gap where a manifest passes local validation but fails at deploy because it references a catalog entry that is not there. References are resolved by name, so unlisted entries (kept out of catalog discovery but still referenceable, like the runtime 'valet' connector) are accepted.
When path is omitted, reads valet.yaml from the current directory. Exits 1 and prints errors to stderr when either pass fails.
The online pass requires authentication and network access. Pass --offline to run the schema pass only (useful in CI or offline environments). Manifests that declare no catalog references skip the online pass automatically.
- --offline
- Validate schema only; skip checking catalog references against the control plane (default: false)
Example
$ valet manifests validate
/path/to/valet.yaml is valid
$ valet manifests validate --offline
/path/to/valet.yaml is valid
$ valet manifests validate ../other-agent/valet.yaml
Error: manifest references unknown catalog entries
connector "githubb" not found in catalogvalet memories
List memories
valet memories [flags]Manage durable memories for an agent.
Memories are key/value facts the agent can recall across sessions. The runtime may also write unkeyed memories; those appear in list output for audit, but set and unset operate by key.
Running "valet memories" with no subcommand lists memories.
Use --agent (or run from a linked directory) to choose the agent. Pass --org as well when multiple orgs have an agent with the same name.
- -a, --agent string
- Agent to list memories for
- -o, --org string
- Org containing the agent
$ valet memories --agent abb-luma-bot
=== Memories: abb-luma-bot agent
=== schema/users
ID: 019a...
Key: schema/users
Content: users(id, email)
Pinned: yes
Created: 2026-06-01T12:00:00Z
Updated: 2026-06-01T12:00:00Z
Expires: never
Origin: nonevalet memories set
Set a memory
valet memories set <KEY=VALUE> [flags]Create or update one keyed memory for an agent.
If the key already exists, content is replaced in place. Passing --pin marks the memory for pinned-context injection. Omitting --pin writes the memory as unpinned.
Pass --ttl to set an expiry in seconds from now. Omitting --ttl creates or replaces the memory without an expiry.
- -a, --agent string
- Agent to set the memory for
- -o, --org string
- Org containing the agent
- --pin
- Pin the memory
- --ttl int64
- Expire the memory after this many seconds
Example
$ valet memories set schema/users='users(id, email)' --pin --agent my-agent
Setting schema/users on my-agent agent... done
Set schema/usersvalet memories unset
Unset a memory
valet memories unset <KEY> [flags]Remove one keyed memory from an agent.
This removes the memory without restarting the agent. Runtime turns after removal no longer recall or pin that key.
- -a, --agent string
- Agent to unset the memory for
- -o, --org string
- Org containing the agent
Example
$ valet memories unset schema/users --agent my-agent
Unsetting schema/users on my-agent agent... done
Unset schema/usersvalet new
Scaffold an agent project
valet new <name> [flags]Create a new agent project directory with starter files.
Scaffolds a directory with SOUL.md, AGENTS.md, CLAUDE.md, a placeholder valet.yaml, and empty skills/ and channels/ subdirectories. The project is ready for customization — edit SOUL.md to define your agent, fill in the manifest's display_name/description/category, then run "valet agents create" to deploy it.
By default, creates the directory under the current working directory. Use --dir to specify a different location.
- --dir string
- Directory to create the project in (default: ./<name>)
$ valet new my-agent
Created agent project my-agent
my-agent/
SOUL.md Agent personality and behavior
AGENTS.md Conventions for coding agents
CLAUDE.md Points Claude Code at AGENTS.md
valet.yaml Manifest describing connectors and channels
skills/ Custom skills (add .md files)
channels/ Channel prompts (add .md files)
$ valet new my-agent --dir ~/projects/my-agentvalet orgs
List organizations
valet orgs [flags]List, create, and manage organizations.
Organizations let teams share agents and connectors. Running "valet orgs" with no subcommand lists all organizations you belong to.
valet orgs create
Create an organization
valet orgs create <name> [flags]Create a new organization.
Creates an organization with the given name and adds you as the first member. Organization names must be unique. The new org is automatically set as the default org.
Example
$ valet orgs create my-org
Creating org... done, my-org
Default org set to my-org.valet orgs destroy
Destroy an organization
valet orgs destroy <name> [flags]Permanently destroy an organization.
Removes the organization and all of its members and invitations. This action cannot be undone. If the org you destroy is the current default org, the default is cleared.
Destroy asks for confirmation; pass --yes to skip it, which a script must, since the prompt needs a terminal.
Requires the Admin role.
- --yes
- Skip the confirmation prompt
Example
$ valet orgs destroy my-org
This destroys my-org and everything in it. It cannot be undone. Continue? (y/N) y
Destroying my-org... done
Default org cleared.
$ valet orgs destroy my-org --yes
Destroying my-org... donevalet orgs info
Show organization details
valet orgs info <name> [flags]Show detailed information about an organization.
Displays the organization's name and creation date.
Example
$ valet orgs info my-org
Name: my-org
Created: 2025-01-15T10:30:00Zvalet orgs invite
Invite a member to an organization
valet orgs invite <name> <email> [flags]Invite a user to join an organization by email.
Sends an invitation that the user can accept with "valet orgs join". Where the installation adds people directly, as Valet Dedicated does, the person must already have signed in. Valet adds them at once, sends no invitation, and prints "Added <email> to <org>." Without --role, the invitee joins with the installation's default role: Admin in Valet Cloud, Developer in Valet Dedicated. Inviting an Admin requires the Admin role.
- --role string
- Role the invitee joins with: admin or developer (default: the installation's default role)
Example
$ valet orgs invite my-org alice@example.com
Inviting alice@example.com to my-org... donevalet orgs join
Join an organization using an invitation code
valet orgs join <code> [flags]Join an organization using an invitation code.
Accepts a pending invitation and adds you as a member of the organization. The code is provided by an existing member who invited you. The joined org is automatically set as the default org.
Example
$ valet orgs join K3MZQ7XR2VNAW4PJ6TLHB5DYCE
Joined my-org.
Default org set to my-org.valet orgs leave
Leave an organization
valet orgs leave <name> [flags]Leave an organization you belong to.
Removes you from the organization. You will lose access to the organization's agents and connectors. If the org you leave is the current default org, the default is cleared.
Example
$ valet orgs leave my-org
Left my-org.
Default org cleared.valet orgs members
List members and invitations for an organization
valet orgs members <name> [flags]List members and pending invitations for an organization.
Shows all current members and any outstanding invitations that have not yet been accepted.
Example
$ valet orgs members my-org
=== Members
alice@example.com
bob@example.com
=== Pending Invitations
carol@example.comvalet orgs remove
Remove a member from an organization
valet orgs remove <name> <email> [flags]Remove a member from an organization by email.
Removal prevents new member-authorized access. Existing scoped tokens and grants keep their own expiration and revocation rules.
Requires the Admin role.
Example
$ valet orgs remove my-org alice@example.com
Removing alice@example.com from my-org... donevalet orgs revoke
Revoke a pending organization invitation
valet orgs revoke <name> <email> [flags]Revoke a pending invitation to an organization.
Cancels an invitation that has not yet been accepted. The invitation code will no longer be valid.
Requires the Admin role.
Example
$ valet orgs revoke my-org alice@example.com
Revoking invitation for alice@example.com... donevalet orgs role
Give a member of an org a role
valet orgs role <email> <admin|developer> [flags]Give a member of an org a role.
A Developer builds and runs sites, apps, agents, and skills. An Admin can also manage members, roles, billing, org settings, and secret reveal. An org always keeps at least one Admin.
Requires the Admin role.
- -o, --org string
- The org (default: the linked or default org)
Example
$ valet orgs role bo@acme.com admin
bo@acme.com is now an Admin of acme.valet orgs set-default
Set the default organization
valet orgs set-default <name> [flags]Set the default organization used by subsequent commands.
The named org must be one you already belong to. Use "valet orgs" to see the orgs you are a member of; use "valet orgs join" to accept an invitation. Exits with code 1 if the named org is not in your membership list.
Example
$ valet orgs set-default my-org
Default org set to my-org.valet policies
List release policies
valet policies [flags]Manage the release policies of an org.
A policy is a checker, such as a secret scanner or a dependency audit, configured for the org. It evaluates every release before the release goes live. A policy either monitors or blocks. A monitor policy records its findings. A blocking policy holds the release until it passes. If it reports a finding at or above its severity, or fails to run, the release is refused and the previous release stays live. "valet deploy" waits for blocking policies.
Running "valet policies" with no subcommand lists the org's policies. Use "valet policies checkers" to see the checkers you can configure, "valet policies add" and "valet policies remove" to change the list, and "valet policies show" to read the evaluation of one release.
The LAST 30 DAYS column counts the policy's evaluations over the last 30 days. A blocking policy lists its evaluations, then the ones it blocked and the ones that errored, leaving out a zero count. A monitor policy lists its evaluations, then how many a policy blocking at that severity would have held, for critical, high, and medium, leaving out a severity with none, and the evaluations that errored. It reads "-" when the policy has not been evaluated, or the server does not report evaluations.
Below the table, "Last errors in the last 30 days" gives each policy's latest error, the reason the policy could not evaluate a release.
Use --org to pick the org (or run from a linked directory).
- -o, --org string
- Org to list policies for
$ valet policies
=== Policies in acme org
NAME CHECKER ENFORCEMENT LAST 30 DAYS SETTINGS
secrets catalog:secrets block at high 41 evaluations, 3 blocked, 1 errored -
dependencies catalog:osv monitor 41 evaluations, would block 3 at high, 7 at medium -valet policies add
Add or replace a policy
valet policies add <name> --checker <checker> [flags]Add a policy to an org, or replace the one with the same name.
A policy is a checker, configured with settings, that evaluates every release. It either monitors or blocks. A monitor policy records its findings and never holds a release. A blocking policy holds the release until it passes: a finding at or above its severity, or a checker that fails to run, refuses the release.
A policy monitors unless you pass --block-at. Pass --monitor to say so explicitly. Give --block-at a severity (info, low, medium, high, or critical) to block. The two flags are mutually exclusive.
Add checks the name, the checker, and the setting names before it asks for anything. Pass the checker's settings with --set key=value, repeated. Use --set key=@file to read a value from a file. Run "valet policies checkers" to see each checker's settings. When a new policy is missing a required secret setting, add prompts for it on a terminal and does not echo it. Without a terminal, pass it with --set key=@file.
Adding a policy with an existing name replaces it. Pass every non-secret setting again. A secret setting you omit keeps its stored value when the checker is unchanged, so you can change a policy's enforcement without entering its token again.
A change to a policy applies to releases not yet decided. Changing a policy's enforcement or settings never changes a decided evaluation, and a running policy evaluation keeps the checker and enforcement it started with. A running policy evaluation whose checker hasn't started yet uses the current settings. Removing a policy, or changing its checker, cancels its running policy evaluations, so releases that waited only on it go ahead.
Requires the Admin role.
- --block-at string
- Hold releases with a finding at or above this severity (info, low, medium, high, critical)
- --checker string
- Checker to run (see "valet policies checkers")
- --monitor
- Record findings without holding releases (default)
- -o, --org string
- Org that owns the policy
- --set stringArray
- Checker setting as key=value or key=@file, repeatable
Example
$ valet policies add secrets --checker catalog:secrets --block-at high
Added policy secrets in acme org (block at high)
$ valet policies add dependencies --checker catalog:osv --monitor
Added policy dependencies in acme org (monitor)
$ valet policies add app-secrets --checker catalog:secrets --set exclude=testdata/*,*.pem
Added policy app-secrets in acme org (monitor)valet policies checkers
List the checkers you can configure
valet policies checkers [flags]List the checkers an org can configure as policies, and add, remove, or verify an org's own.
A checker is a kind of policy; "valet policies add --checker" configures one. Each checker shows its id, then its display name, then what it does. Each checker lists the settings it takes in a table with the columns FIELD, REQUIRED, SECRET, and DESCRIPTION. Pass a setting to "valet policies add" with --set key=value, or --set key=@file to read the value from a file. Secret settings are write-only: Valet never shows them again.
An org checker also lists its origin, why it is unavailable, its URL, its approved files, its headers as written (a credential is a {{NAME}} reference, never its value), when Valet last tried to describe it, whether or not that worked, and the last error from a describe or validate. Use "valet policies checkers add", "remove", and "verify" to manage org checkers.
- -o, --org string
- Org to list checkers for
Example
$ valet policies checkers
=== Checkers
catalog:osv Dependencies (OSV)
Finds known-vulnerable dependencies in a release through OSV.dev
FIELD REQUIRED SECRET DESCRIPTION
ignore no no Comma-separated advisory ids to skip
catalog:secrets Secrets (gitleaks)
Finds credentials in a release's source with gitleaks' default rules
FIELD REQUIRED SECRET DESCRIPTION
exclude no no Comma-separated path globs of source files to skip
org:snyk Snyk Open Source
Finds vulnerable dependencies with Snyk
Origin: organization
URL: https://snyk-checker.acme.valet.run
Approved files: build
Header: Authorization: Bearer {{SNYK_CHECKER_TOKEN}}
Last describe attempt: 2026-10-20T14:03:11Z
Last error: its endpoint answered HTTP 401 to describevalet policies checkers add
Add or replace an org checker
valet policies checkers add <name> --url <url> [flags]Add an org checker, or replace the one with the same name.
An org checker is an HTTPS endpoint that implements the Checker API. Valet calls it for every release a policy that names it evaluates, and sends it links to the release's source or build, as the endpoint asks. Adding a checker agrees to send those files to its URL.
Pass headers with --header, repeated. Write a credential as a reference to a secret org env var, such as --header 'Authorization: Bearer {{SNYK_TOKEN}}'; set it first with valet env set --org. Valet resolves it at each call, so rotating the variable needs no change here. A header named Authorization, Proxy-Authorization, Cookie, X-Api-Key, or Api-Key, or ending in -Token, -Secret, or -Key, must hold a reference. Every member sees any other header's value as written.
Any member can add a checker, and its headers can name any secret org env var, which sends that secret to the checker's URL.
Replacing a checker takes effect on the next call of every policy that names it. A new URL or new headers also restart its running evaluations at the new endpoint. Pass every header again.
Requires the Admin role.
- --header stringArray
- Header as "Name: value", repeatable
- -o, --org string
- Org that owns the checker
- --url string
- The endpoint's base URL (https)
Example
$ valet policies checkers add snyk --url https://snyk-checker.acme.valet.run --header 'Authorization: Bearer {{SNYK_CHECKER_TOKEN}}'
Added checker org:snyk in acme org (Snyk Open Source; approved files: build)
Valet sends build of every release a policy that names org:snyk evaluates to https://snyk-checker.acme.valet.run.valet policies checkers remove
Remove an org checker
valet policies checkers remove <name> [flags]Remove an org checker.
Valet refuses while a policy names the checker. Remove the policy first with "valet policies remove", or point it at another checker.
Requires the Admin role.
- -o, --org string
- Org that owns the checker
Example
$ valet policies checkers remove snyk
Removed checker org:snyk from acme orgvalet policies checkers verify
Check that an org checker's endpoint works
valet policies checkers verify <name> [flags]Check that an org checker's endpoint answers.
Valet calls the endpoint's describe, with the saved headers, and reports whether it answered and how long it took. Pass --set key=value, repeated, or key=@file, to also check settings a policy would give the checker. Verify sends no release files. Within 10 seconds of the last describe, Valet reuses that result and reports no latency; it still checks any settings. It exits 1 when the endpoint fails or refuses the settings.
Requires the Admin role.
- -o, --org string
- Org that owns the checker
- --set stringArray
- Checker setting as key=value or key=@file, repeatable
Example
$ valet policies checkers verify snyk --set snyk_org=acme-prod
Verified org:snyk in acme org: OK in 412 ms
$ valet policies checkers verify snyk
Error: org:snyk failed verification: its endpoint answered HTTP 401 to describevalet policies remove
Remove a policy
valet policies remove <name> [flags]Remove a policy from an org.
New releases no longer evaluate the policy. A change to a policy applies to releases not yet decided. Changing a policy's enforcement or settings never changes a decided evaluation, and a running policy evaluation keeps the checker and enforcement it started with. A running policy evaluation whose checker hasn't started yet uses the current settings. Removing a policy, or changing its checker, cancels its running policy evaluations, so releases that waited only on it go ahead.
Requires the Admin role.
- -o, --org string
- Org that owns the policy
Example
$ valet policies remove app-secrets
Removing policy app-secrets from acme org... donevalet policies show
Show a release's evaluation and its findings
valet policies show [<id>] [flags]Show the release evaluation of one release: its status, each policy's evaluation, and each finding with its file or package and how to fix it.
Without an id, show reads the service's latest release evaluation. Pass an evaluation id to read an older one. A finding that blocks is marked [blocks]. The deploy line says whether the release is waiting, live, or why it was refused. Decided is when the evaluation reached its status. Each policy ends with how long its evaluation took.
Use --agent (or run from a linked directory) to pick the service.
- -a, --agent string
- Service to show the release evaluation for (uses linked service if omitted)
- -o, --org string
- Org that owns the service
Example
$ valet policies show -a support-bot
=== Release evaluation 0192f1c3
Service: support-bot
Commit: 9f2c1ab
Status: blocked
Deploy: deploy.policy_blocked
Message: acme's policies blocked support-bot's changes: secrets found 1 finding at high or above. Nothing was deployed; the current release is still live. Fix it and deploy again.
Started: 2026-10-18T10:30:00Z
Decided: 2026-10-18T10:30:04Z
=== Policies
secrets catalog:secrets blocked (block at high) 4s
high config.yaml:3 Possible AWS access key in the source (gitleaks/aws-access-token) [blocks]
Fix: Remove it from the source, rotate it, and set it with valet env set
secrets-audit catalog:secrets passed (monitor) 100msvalet ps
List processes for an agent or app
valet ps [flags]List all processes for a deployed agent or app.
Shows each process with its size, current state, uptime, release version, and container ID. economy-1x stops after 30 minutes without traffic and starts on the next request; standard-1x never stops. While a rollout is in progress, the release column reads "v6 → v7": the container runs v6 and the process targets v7. A crashed process adds a line with the first line of its crash reason. An app has one process per Procfile process type and count, named like web.1 and worker.1.
The service is determined by the --agent or --app flag or the linked service in the current directory. --app is the same as --agent.
- -a, --agent string
- Agent or app to list processes for (uses linked service if omitted)
- --app string
- App to list processes for (same as --agent)
- -o, --org string
- Org that owns the agent or app
$ valet ps --agent my-agent
Processes for my-agent agent in acme org: 2 processes
my-agent.0 economy-1x up 2h3m v5 6e82d4187b0958
my-agent.1 economy-1x up 2h3m v5 6e82d418b62d78
$ valet ps --app checkout
Processes for checkout app in acme org: 2 processes
web.1 standard-1x up 41m v7 3d8e5617c42908
worker.1 economy-1x up 41m v7 3d8e5617c51a78
$ valet ps --app checkout
Processes for checkout app in acme org: 2 processes
web.1 economy-1x up 2m v6 → v7 3d8e5617c42908
worker.1 economy-1x crashed 8s v7 3d8e5617c51a78
reason: exit status 1: Error: Cannot find module 'express'valet ps restart
Restart all processes for an agent or app
valet ps restart [flags]Restart all processes for a deployed agent or app by replacing their containers using the current release. This is useful for picking up changed environment variables or recovering from a stuck state without deploying a new release.
A restart cuts any in-flight conversations immediately — unlike a deploy, which lets a busy container finish its work before replacing it. That forcefulness is the point: it is the escape hatch for a wedged agent.
The service is determined by the --agent or --app flag or the linked service in the current directory. --app is the same as --agent.
For an app, restart then waits for each process to come up on a new container, printing a line as each changes. It exits 0 when every process is up (or idle), and 1 if one crashes or --wait-timeout passes. --no-wait returns once the restart is requested.
- -a, --agent string
- Agent or app to restart (uses linked service if omitted)
- --app string
- App to restart (same as --agent)
- --no-wait
- Return once the restart is requested, without waiting for an app's processes
- -o, --org string
- Org that owns the agent or app
- --wait-timeout duration
- How long to wait for an app's processes to come up
Example
$ valet ps restart --agent my-agent
Restarting my-agent agent in acme org... done
$ valet ps restart --app checkout
Restarting checkout app in acme org... done
web.1 up v3
Restarted: 1 process upvalet ps scale
Scale processes for an agent or app
valet ps scale <process>=<value>... [flags]Scale an agent or an app.
For an agent, pass a single "agent=<value>" pair. The right side of "=" is a model ID, a process count, a size, "model:count", or "count:size". Each value you leave out keeps its current setting. Today an agent's count must be 0 or 1.
For an app, pass one or more "<type>=<value>" pairs naming process types from its Procfile. The value is a count ("web=2"), a size ("web=standard-1x", which keeps the count), or both ("web=2:standard-1x"). A type's first scale without a size runs on economy-1x. Counts run from 0 up to the platform's per-type maximum.
Sizes:
economy-1x stops after 30 minutes without traffic and starts again
on the next request
standard-1x the same machine, and never stopsChanging size restarts the type's processes.
Sites have no processes and cannot be scaled.
Changing an agent's model or count restarts its process. App scale changes never redeploy surviving processes.
The service is determined by the --agent or --app flag or the linked service in the current directory. --app is the same as --agent.
Available agent models: claude-sonnet-5 claude-sonnet-5-5 gpt-5.6-sol gpt-5.6-terra gpt-5.6-luna gpt-6-luna gpt-6.1-sol glm-5.3 glm-5.3-flash
- -a, --agent string
- Agent or app to scale (uses linked service if omitted)
- --app string
- App to scale (same as --agent)
- -o, --org string
- Org that owns the agent or app
Example
$ valet ps scale agent=gpt-5.6-terra
Scaling my-agent agent in acme org... done, model=gpt-5.6-terra
$ valet ps scale agent=0
Scaling my-agent agent in acme org... done, count=0
$ valet ps scale web=2 worker=1 --app checkout
Scaling checkout app in acme org... done, web=2 worker=1
$ valet ps scale web=standard-1x --app checkout
Scaling checkout app in acme org... done, web=standard-1x
$ valet ps scale web=3:standard-1x --app checkout
Scaling checkout app in acme org... done, web=3:standard-1xvalet releases
List releases for an agent, app, site, or skill
valet releases [<name>] [flags]List the release history for an agent, app, site, or skill, newest first.
A release is a versioned bundle of the service's files. The "(current)" marker flags the release the service is serving now. Only deployed releases appear: a release that was built but never deployed is left out, so the list reconciles with what has shipped. The positional argument, the --agent flag, or the directory's link names the service.
- -a, --agent string
- Agent, app, site, or skill name (overrides project link)
- --app string
- App name (same as --agent)
- -o, --org string
- Org the service belongs to
$ valet releases my-agent
=== Releases on my-agent
v3 active abc1234 2026-06-01T12:00:00Z (current)
v2 active def5678 2026-05-20T09:30:00Z
v1 active 9abcdef 2026-05-01T08:00:00Zvalet releases files
List files in the deployed release
valet releases files [<name>] [flags]List the files in the agent's currently-deployed release. Reads at the release's commit, not at main HEAD — files published to main but not yet deployed are excluded so the listing reflects what the agent is actually running. Prints "No files." when the agent has no active release. Read-only — to edit, open a draft with `valet drafts create`.
- -a, --agent string
- Agent, app, site, or skill name (overrides project link)
- --app string
- App name (same as --agent)
- -o, --org string
- Org the service belongs to
Example
$ valet releases files my-agent
=== Files on my-agent
valet.yaml
SOUL.md
skills/triage.mdvalet releases read
Print a file from the deployed release
valet releases read [<name>] <path> [flags]Read one file from the agent's currently-deployed release. Reads at the release's commit, not at main HEAD — the file you see is what the agent is actually running. Contents go to stdout verbatim with no header so the output is pipeable. Returns an error when the agent has no active release.
- -a, --agent string
- Agent, app, site, or skill name (overrides project link)
- --app string
- App name (same as --agent)
- -o, --org string
- Org the service belongs to
Example
$ valet releases read my-agent SOUL.md
# triage
...
$ valet releases read my-agent SOUL.md > soul.mdvalet resources
List resources
valet resources [flags]List, create, attach, and destroy resources.
A resource is a named set of env vars your org owns, such as a PostgreSQL database Valet provisions for you. Attaching a resource to an app puts its env vars in the app's environment, so the app reads DATABASE_URL it never set. An app that needs two of the same kind attaches the second with a prefix, so it reads SECONDARY_DATABASE_URL beside the first.
A resource can be attached to any number of apps. Detaching removes the env vars from an app and keeps the resource. Destroying a provisioned resource deletes its data.
Running "valet resources" with no subcommand lists resources attached to the linked app, or every resource in the org with --org.
- --app string
- App to list resources for
- -o, --org string
- Org to list resources for
$ valet resources --app checkout
NAME PLAN PREFIX STATE
checkout-db valet-postgresql:dev provisioned
shared-events-db valet-postgresql:dev EVENTS provisioned
$ valet resources --org acme
NAME PLAN STATE ATTACHMENTS
checkout-db valet-postgresql:dev provisioned 1
shared-events-db valet-postgresql:dev provisioned 2
scratch-db valet-postgresql:dev pending 0valet resources attach
Attach a resource to an app
valet resources attach <resource-name> [flags]Attach a resource to an app.
Puts the resource's env vars in the app's environment under their own names, so valet-postgresql sets DATABASE_URL, DATABASE_HOST, and the rest. Use --prefix when the app already has those names: --prefix SECONDARY sets SECONDARY_DATABASE_URL beside the first. The app is redeployed so the new env vars take effect.
The resource must be provisioned. Attaching fails when an env var it would set already exists on the app or its org; unset the env var, or attach with a prefix.
- --app string
- App to attach the resource to
- -o, --org string
- Org that owns the resource
- --prefix string
- Prefix for the attachment's env var names
Example
$ valet resources attach shared-events-db --app checkout --prefix EVENTS
Attaching shared-events-db to checkout app with prefix EVENTS... done
Sets EVENTS_DATABASE_URL, EVENTS_DATABASE_POOLED_URL, EVENTS_DATABASE_HOST,
EVENTS_DATABASE_PORT, EVENTS_DATABASE_NAME, EVENTS_DATABASE_USER,
EVENTS_DATABASE_PASSWORD.
$ valet resources attach shared-events-db --app analytics
Attaching shared-events-db to analytics app... done
Sets DATABASE_URL, DATABASE_POOLED_URL, DATABASE_HOST, DATABASE_PORT,
DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD.valet resources catalog
List the resources you can create and their plans
valet resources catalog [flags]List the resources you can create and their plans.
Shows each provider with its plans and the env var names an attachment sets. Create one with "valet resources create <provider>:<plan> <name>". Attach with --prefix to put a word in front of every name.
- -o, --org string
- Org to list the catalog for
Example
$ valet resources catalog
PROVIDER NAME PLANS ENV VARS
valet-postgresql Valet PostgreSQL small, dev DATABASE_URL, DATABASE_POOLED_URL, DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORDvalet resources create
Create a resource
valet resources create <provider>:<plan> <name> [flags]Create a resource.
Provisions a new resource from a provider and plan, written "<provider>:<plan>" as in "valet-postgresql:dev", under a name that is unique in your org. Run "valet resources catalog" to see the providers and plans.
Provisioning takes a few seconds. With --app (or from a linked app directory) the command waits for the resource to be provisioned and then attaches it, so the app's environment gains the resource's env vars and the app is redeployed; --prefix puts a word in front of every name. Without an app the command returns as soon as the resource is recorded; run "valet resources info" to watch it, and "valet resources attach" to use it.
- --app string
- App to attach the resource to once it is provisioned
- -o, --org string
- Org to create the resource in
- --prefix string
- Prefix for the attachment's env var names
Example
$ valet resources create valet-postgresql:dev checkout-db --app checkout
Creating valet-postgresql:dev checkout-db... done
Provisioning... provisioned
Attaching checkout-db to checkout app in acme org... done
Sets DATABASE_URL, DATABASE_POOLED_URL, DATABASE_HOST, DATABASE_PORT,
DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD.
$ valet resources create valet-postgresql:dev events-db --app checkout --prefix EVENTS
Creating valet-postgresql:dev events-db... done
Provisioning... provisioned
Attaching events-db to checkout app with prefix EVENTS in acme org... done
Sets EVENTS_DATABASE_URL, EVENTS_DATABASE_POOLED_URL, EVENTS_DATABASE_HOST,
EVENTS_DATABASE_PORT, EVENTS_DATABASE_NAME, EVENTS_DATABASE_USER,
EVENTS_DATABASE_PASSWORD.
$ valet resources create valet-postgresql:dev shared-events-db --org acme
Creating valet-postgresql:dev shared-events-db in acme org... done
Attach it once provisioned with
"valet resources attach shared-events-db --app <app>".valet resources destroy
Destroy a resource and its data
valet resources destroy <name> [flags]Destroy a resource and its data.
Deletes the resource. For a provisioned database this deletes every table and row, and it cannot be undone. The command asks for confirmation; pass --yes to skip it, which a script must, since the prompt needs a terminal.
A resource attached to any app is refused unless --force is given, which detaches every app first. "valet resources detach" keeps the resource; only destroy deletes it.
- --force
- Detach from every app and destroy anyway
- -o, --org string
- Org that owns the resource
- --yes
- Skip the confirmation prompt
Example
$ valet resources destroy scratch-db
This deletes scratch-db and all of its data. Continue? (y/N) y
Destroying scratch-db in acme org... donevalet resources detach
Detach a resource from an app
valet resources detach <resource-name> [flags]Detach a resource from an app.
Removes the attachment's env vars from the app's environment and redeploys the app. The resource is untouched; attach it again to restore the env vars.
- --app string
- App to detach the resource from
- -o, --org string
- Org that owns the resource
Example
$ valet resources detach shared-events-db --app checkout
Detaching shared-events-db from checkout app... donevalet resources info
Show resource details
valet resources info <name> [flags]Show detailed information about a resource.
Displays the resource's provider and plan, state, and every attachment with its app, prefix, and the env var names it sets.
State is one of pending, provisioning, provisioned, deprovisioning, deprovisioned, or failed. Only a provisioned resource can be attached. Reason carries the provider's diagnostic when the state is not the one you expected.
- -o, --org string
- Org that owns the resource
Example
$ valet resources info shared-events-db
=== Resource: shared-events-db in acme org
Name: shared-events-db
Plan: valet-postgresql:dev (Valet PostgreSQL)
State: provisioned
Created: 2026-09-25 14:02 UTC
Attachments:
app: analytics DATABASE_URL, DATABASE_POOLED_URL, DATABASE_HOST, ...
app: checkout EVENTS EVENTS_DATABASE_URL, EVENTS_DATABASE_POOLED_URL, ...
$ valet resources info scratch-db
=== Resource: scratch-db in acme org
Name: scratch-db
Plan: valet-postgresql:dev (Valet PostgreSQL)
State: failed
Reason: neon: create project: 429 too many requests
Created: 2026-09-25 14:02 UTC
Attachments: nonevalet run
Send a prompt to an agent and stream the response
valet run <prompt> [flags]Send a single prompt to a deployed agent and stream back the execution trace.
Creates an ephemeral session, runs the agent loop, and displays text output, tool calls, and timing. The agent is determined by the --agent flag or the linked agent in the current directory. Useful for testing agents, scripting, and programmatic access.
Use --json for machine-readable NDJSON output. Use --timeout to set the maximum execution time (default 10m).
- -a, --agent string
- Agent to run (uses linked agent if omitted)
- --json
- Output newline-delimited JSON events
- -o, --org string
- Org that owns the agent
- --timeout duration
- Maximum execution time (default: 10m)
$ valet run --agent my-agent "what is 2+2"
> what is 2+2
[tool] Calculator({"expression":"2+2"})
[tool] → 4
The answer is 4.
elapsed: 5s
$ valet run --agent my-agent "hello" --jsonvalet sessions
List or show sessions
valet sessions [id] [flags]List, show, and follow inference sessions for an agent.
Running "valet sessions" with no argument lists the sessions belonging to an agent. Passing a session ID shows that session's transcript. The -f/--follow flag streams events as they arrive. The agent is determined by the --agent flag or the linked agent in the current directory.
- -a, --agent string
- Agent to list sessions for (uses linked agent if omitted)
- -f, --follow
- Stream events as they arrive (default: dump and exit)
- -o, --org string
- Org that owns the agent
$ valet sessions --agent my-agent
=== Sessions
01HXYZ000000000000000001 2026-04-16 10:00 UTC How do I deploy?
01HXYZ000000000000000002 2026-04-15 16:30 UTC (untitled)
$ valet sessions 01HXYZ000000000000000001 --agent my-agent
[10:00:00] user: How do I deploy?
[10:00:02] assistant: Run "valet deploy".
[10:00:02] tokens: in=1234 out=567
$ valet sessions 01HXYZ000000000000000001 -a my-agent -f
# streams events until Ctrl-Cvalet sessions delete
Delete a session
valet sessions delete <id> [flags]Delete a session by ID.
The session and its transcript are removed from the server and no longer appear in "valet sessions". This action cannot be undone.
Requires the Admin role.
- -a, --agent string
- Agent that owns this session
- -o, --org string
- Org that owns the agent
Example
$ valet sessions delete 01HXYZ000000000000000001 --agent my-agent
Deleting session 01HXYZ000000000000000001 on my-agent agent in acme org... donevalet sessions info
Show session details
valet sessions info <id> [flags]Show detailed information about a session.
Displays the session's status, channel, timestamps, and conversation key. The agent is determined by the --agent flag or the linked agent in the current directory.
- -a, --agent string
- Agent that owns this session
- -o, --org string
- Org that owns the agent
Example
$ valet sessions info 01HXYZ000000000000000001 --agent my-agent
=== Session: 01HXYZ000000000000000001 on my-agent agent in acme org
title: How do I deploy?
status: active
channel: ch-webhook
created: Thu Apr 16, 2026 10:00 AM UTC
updated: Thu Apr 16, 2026 10:05 AM UTC
conv-key: 019d3c9f-2a10-7c80-9b8a-1e2f3d4a5b6cvalet setup
Set up Valet with guided onboarding
valet setup [flags]Walk through a guided setup to get started with Valet.
Runs a five-step onboarding flow: authenticate, create an organization, install the Valet plugin for Claude Code, scaffold an agent project, and deploy it. Each step can be skipped if already completed. Press Ctrl+C at any prompt to cancel.
The deploy step works the way valet deploy does: it pushes the project with Git and publishes it. Creating an agent needs Git 2.32 or later on your PATH; setup checks before it scaffolds anything.
$ valet setup
Welcome to Valet!
Let's get you set up.
Step 1 of 5: Log in
✓ Already logged in as alice@example.com
Step 2 of 5: Create an organization
Creating org... done, my-org
Step 3 of 5: Install the Valet plugin for Claude Code
✓ Installed the Valet plugin
Step 4 of 5: Create your first agent
...
Step 5 of 5: Deploy
Creating agent... done, my-agent
Linking directory... done
Reading files... done, 5 files
Creating push for my-agent agent in my-org org... done
Fetching source... done
Pushing source... done
Deploying my-agent agent in my-org org... done, v1
Waiting for agent to start... done
✓ Setup complete!valet sites
List sites
valet sites [flags]List, create, rename, and destroy static sites.
A site is a directory of static files served over HTTPS at a name-derived address. Create a site, then run "valet deploy" from the linked directory to publish its content. The URL is live (serving 404s) as soon as the site is created.
Running "valet sites" with no subcommand lists sites in the default organization. Use --org to list sites in a different organization.
- -o, --org string
- Org to list sites for
$ valet sites
NAME URL VERSION
my-site https://acme.valet.run/my-site 3valet sites access
Show or set a site's visibility
valet sites access <name> [public|private|password] [flags]Show or set who can view a site.
With no mode, prints the site's current access mode. With a mode, moves the site to it:
private Members of the owning org, after a Valet login. New sites
are private by default.
password Org members sign in with Valet, or any visitor enters the
site password. The password is for external users.
public Anyone on the internet.Password mode prompts for a hidden password; pass --password in scripts or agent runs where stdin is not a terminal. Switching away from password mode clears the stored password. Any change signs every current visitor out.
- -o, --org string
- Org that owns the site
- --password string
- Password to set (password mode; prompts with hidden input when omitted)
Example
$ valet sites access my-site
my-site access: private
$ valet sites access my-site public
Setting my-site access to public in acme org... done
Anyone can now view this site.
$ valet sites access my-site password
Password:
Setting my-site access to password in acme org... done
Org members sign in with Valet; others enter the password. Sessions last 24 hours.valet sites claim
Claim an anonymous site into an org
valet sites claim [name] [flags]Claim an anonymous site published without an account, moving it into an organization permanently.
An anonymous site lives in the shared incubator org, serves at a `try.valet.run` address, and expires. Claiming transfers it into an org you belong to, gives it a permanent URL, and leaves the anonymous site URL redirecting there. The claim consumes the anonymous site's claim token: afterwards the site is managed through org membership like any other.
A claimed site stays public, which a site made with "valet sites create" is not — those are private by default. The anonymous URL redirects to the permanent one, so making the site private at claim time would lock out everyone holding the link the publisher shared. Run "valet sites access <name> private" to change it.
Name the anonymous site on the command line, defaulting to the site this directory is linked to. Its claim token is read from that directory's .valet/config.json, so an anonymous site can only be claimed from the directory it was published from — from anywhere else, use the claim URL printed when the site was created.
--org is required and must name an org you already belong to: this command never guesses where a site should live, and it never creates an org, because an org's name is reserved permanently. For a brand-new org, run "valet orgs create <org>" first, or claim from the browser claim URL printed when the site was created, which does both at once.
Use --name to rename the site on the way in; a name that is already taken is reported rather than silently suffixed. On success the directory's .valet/config.json is rewritten to the new org and name, so "valet deploy" keeps working.
- --name string
- Rename the site on the way in (default: keep the anonymous site's name)
- -o, --org string
- Org to claim the site into (required; must already exist)
Example
$ valet sites claim --org acme
Claiming bubbling-brook-1934... done, bubbling-brook-1934 in acme
Updating link... done
URL: https://acme.valet.run/bubbling-brook-1934
The anonymous site URL now redirects here permanently.
This site stays public — anyone with the link can view it.
Make it private with "valet sites access bubbling-brook-1934 private".
Run "valet deploy" to publish changes.
$ valet sites claim bubbling-brook-1934 --org side-projects --name docs
Claiming bubbling-brook-1934... done, docs in side-projects
URL: https://side-projects.valet.run/docs
The anonymous site URL now redirects here permanently.
This site stays public — anyone with the link can view it.
Make it private with "valet sites access docs private".
Run "valet deploy" to publish changes.valet sites create
Create a site
valet sites create [name] [flags]Create a new static site.
The site's name becomes the last segment of its address. If the name is omitted, the server generates one. The URL is live immediately and serves 404s until the first deploy. The current directory is linked to the new site so "valet deploy" publishes it.
The site name is optional — if omitted, the server generates one. App, site, and agent names share one namespace within an org: a site cannot take the name of an existing app or agent.
When --org is not specified, the default org is used. The default org is set automatically when you create or join an org.
Use --anonymous to create a site with no Valet account at all. It lands in a shared incubator org, it is public to anyone with the link, it takes a generated name, and it may be removed 36 hours after it is created, unless it is claimed. Its claim token — the only credential that can update, delete, or claim it — is written into .valet/config.json in the current directory, which should not be committed. --anonymous takes no site name and cannot be combined with --org, and it is refused when you are signed in: "valet sites create <name>" followed by "valet sites access <name> public" makes a permanent public site in your own org instead. It also refuses to replace an existing link; pass --relink to mean it.
- --anonymous
- Create a public site with no account; it may be removed 36 hours after it is created, unless it is claimed (default: false)
- -o, --org string
- Org that owns the site
- --relink
- With --anonymous, replace this directory's existing .valet/config.json (default: false)
Example
$ valet sites create my-site
Creating site... done, my-site
Linking directory... done
URL: https://acme.valet.run/my-site
Run "valet deploy" to publish this directory.
$ valet sites create --anonymous
Creating anonymous site... done, bubbling-brook-1934
URL: https://try.valet.run/bubbling-brook-1934
Expires in 3h 54m (2026-07-31 03:14 UTC)
Claim URL: https://valet.dev/claim/RZ2m7q...
Linking directory... done
The claim token is now in .valet/config.json. It is the only credential for this site — do not commit it.
Run "valet deploy" to publish this directory.valet sites destroy
Destroy a site
valet sites destroy [name] [flags]Permanently destroy a site and all its releases.
The site's hostname stops serving within seconds. A later app or site in the same organization may reuse its name and hostname. This action cannot be undone. Generated anonymous hostnames remain retired.
Run with no name in a directory linked to an anonymous site to take that site down with the claim token in its .valet/config.json — no account needed. The server is asked first; the link file is removed only after the site is confirmed gone, because the token in it is the only credential the site has. An anonymous site that has already been claimed is refused: it belongs to an org now, and org membership is what governs it.
The command asks for confirmation; pass --yes to skip it, which a script must, since the prompt needs a terminal.
- -o, --org string
- Org that owns the site
- --yes
- Skip the confirmation prompt
Example
$ valet sites destroy my-site
This destroys my-site and all its releases. It cannot be undone. Continue? (y/N) y
Destroying my-site site in acme org... done
$ valet sites destroy my-site --yes
Destroying my-site site in acme org... done
$ valet sites destroy --yes
Destroying anonymous site bubbling-brook-1934... done
Removed /home/me/site/.valet/config.json.valet sites download
Download a deployed site's files
valet sites download <name> [dir] [flags]Download a site's currently-deployed files into a local directory and link that directory to the site.
This is how one agent or person updates a site another created. A static site has no build step, so its deployed release is the source of truth: the downloaded copy is exactly what the site serves and is ready to edit and redeploy. Any org member with access to the site can download it — the original source is not needed.
Files are written into [dir], defaulting to a new directory named after the site. The directory must be empty unless --force is given; the .git and .valet directories are never written. A .valet/config.json link is written so "valet deploy" from the directory republishes to the same site. Returns an error when the site has no active release.
- --force
- Write into a non-empty directory
- -o, --org string
- Org that owns the site
Example
$ valet sites download docs-site
Downloading docs-site... done, 12 files to docs-site/
Linking directory... done
Run "valet deploy" from docs-site to publish changes.valet sites info
Show site details
valet sites info [name] [flags]Show detailed information about a site.
Displays the site's org, URL, current release with its deploy age, any attached drains, and any attached connectors under "integrations:" — each one's transport and whether a page served from the site can call it. A conforming connector also lists its live tool names on a nested "tools:" line. Use "valet releases" for the full release history. The site is determined by the positional argument or the linked site in the current directory.
Pass --schemas to print each tool's description and its input schema (the JSON Schema a page's call has to satisfy) instead of just its name — this is the CLI's route to the schemas that back "valet connectors call".
In a directory linked to an anonymous site, this reports that site's standing under the claim token in its .valet/config.json — no account needed. It answers in every state: while the site is live it prints the earliest moment the site may be removed, and once the site has been claimed it prints where it went, which is how a directory left behind by a browser claim finds its site again.
- -o, --org string
- Org that owns the site
- --schemas
- Print each attached connector's tool descriptions and input schemas
Example
$ valet sites info docs-site
=== Site: docs-site (acme org)
org: acme-corp
url: https://apt-lens-2877.valet.run
release: v3 (deployed 2h12m ago)
access: private (org members only, via Valet login)
drains: https://in.logs.example.com/v1/logs (logs; active), https://ingest.example.net/v1/logs (org; logs,traces; active)
integrations:
github-mcp streamable-http ok
tools: search_issues, create_issue
betterstack-mcp streamable-http ok (session)
stripe-mcp sse not usable: requires an interactive OAuth flow
$ valet sites info docs-site --schemas
...
integrations:
github-mcp streamable-http ok
tools:
search_issues — Search issues by query
{"type":"object","properties":{"query":{"type":"string"}}}
create_issue
{"type":"object","properties":{"title":{"type":"string"}}}
$ valet sites info
=== Anonymous site: bubbling-brook-1934
url: https://bubbling-brook-1934.try.valet.run
state: unclaimed
Expires in 13h 25m (2026-07-29 04:00 UTC)
Claim it to keep it.valet sites link
Link the current directory to a site
valet sites link <name> [flags]Link the current directory to an existing site.
Creates a .valet/config.json file that maps this directory to the named site and its org. Subsequent "valet deploy" runs publish this directory to the linked site.
Pass --org when you belong to more than one org. Single-org users can omit --org. Use --force to replace an existing link.
- --force
- Replace an existing link in this directory
- -o, --org string
- Org that owns the site
Example
$ valet sites link my-site
Linked my-site site in acme orgvalet sites rename
Rename a site and its address
valet sites rename <name> <new-name> [flags]Rename a site and move it to the address the new name derives.
In host mode, the old hostname stops serving and does not redirect. In path mode, the old path stops serving. The same organization may reuse ordinary handles. Compatibility paths and anonymous claim URLs keep redirecting to the site. Handles with redirect or anonymous history remain retired.
Renaming an existing path site in host mode preserves its old path as a redirect. Wait for its org's DNS and HTTPS readiness before renaming. A refused rename keeps the old name and address available.
- -o, --org string
- Org that owns the site
Example
$ valet sites rename launch-notes release-notes --org acme
Renaming launch-notes site in acme org to release-notes... done, https://release-notes.acme.valet.runvalet skills
List configured agent and org skills, and manage org skills
valet skills [flags]List configured agent and org skills, and manage org skills.
A skill is a versioned folder of instructions — a SKILL.md plus any supporting files — kept in its own Git repository. Each version is a commit. Agents get org skills by attachment, and Valet copies them into each release at deploy time. Attach refs take two forms:
org:<name>[@vN|@latest] an org skill
catalog:<name> installs the catalog skill into the
org, or reuses the org's copy, and
attaches itAn unpinned or @latest ref resolves to the newest version at deploy time; @vN pins a specific version.
Running "valet skills --agent <agent>" lists the agent's attached skills. Running "valet skills --org <org>" lists the org's skills, each with its version, access mode, address, origin, and description. "valet skills access" shows or sets who can open a skill's address. Use "valet skills catalog" to browse curated skills and "valet skills attach" to attach a catalog or org skill source to an agent.
Create, publish, clone, rename, and destroy org skills with "valet skills create", "publish", "clone", "rename", and "destroy". Share a skill by email with "valet skills share", and list or remove shares with "valet skills shares" and "valet skills unshare".
- -a, --agent string
- Agent to list effective skills for
- -o, --org string
- Org to list skills for
valet skills access
Show or set who can open a skill's address
valet skills access <name> [public|private|password] [flags]Show or set who can open a skill at its address.
With no mode, prints the skill's access mode and address. A skill has no address until Valet gives it one. With a mode, moves the skill to it:
private Members of the owning org, after a Valet login. Every
skill is private when it is created.
password Org members sign in with Valet, or any visitor enters the
skill password.
public Anyone with the link can open and download it.Password mode prompts for a hidden password; pass --password in scripts or agent runs where stdin is not a terminal. Switching away from password mode clears the stored password. Any change signs every current visitor out.
- -o, --org string
- Org that owns the skill
- --password string
- Password to set (password mode; prompts with hidden input when omitted)
Example
$ valet skills access research
research access: private
URL: https://research.acme.valet.run
$ valet skills access research private
Setting research access to private in acme org... done
Only members of the owning org can open this skill, after a Valet login.valet skills attach
Attach a skill to an agent
valet skills attach <source> [flags]Attach a skill source to an agent.
Sources must be curated catalog refs or org skill refs:
catalog:<name> org:<name>[@vN|@latest]
A catalog:<name> source installs the catalog skill into the org, or reuses the org's copy if it is already installed, then attaches it. A catalog source takes no version: an install copies the current template. Pin the org's copy with org:<name>@vN.
An org:<name> source that names a built-in, such as org:governance, attaches Valet's default when the org has published no skill of that name. The agent follows Valet's default until the org publishes its own, then follows that.
Use "valet skills catalog" to browse curated skills and "valet skills --org <org>" to list org skill snapshots.
- -a, --agent string
- Agent to attach the skill to
- -o, --org string
- Org that owns the agent
Example
$ valet skills attach catalog:research --agent assistant --org acme
Attaching catalog:research to assistant agent in acme org... done, catalog:research
$ valet skills attach org:brand-voice@v2 --agent assistant
Attaching org:brand-voice@v2 to assistant agent... done, org:brand-voice@v2valet skills catalog
List curated skill catalog entries
valet skills catalog [flags]List curated skill catalog entries.
Each entry is a Valet-curated template. Install one as the org's own skill with "valet skills create --from catalog:<name>". The command is org-scoped because catalog visibility is controlled by the skills feature gate.
- -o, --org string
- Org to list catalog skills for
Example
$ valet skills catalog --org acme
research Research Research a person or company
posthog Analytics Summarize PostHog user activityvalet skills clone
Clone an org skill with Git
valet skills clone <name> [dir] [flags]Clone an org skill with Git.
Clones the skill's latest version into a directory named after the skill, or into dir, and links that directory to the skill. The clone's main branch holds that version's commit. Edit the files there, then publish them with "valet deploy" in the directory, or with "valet skills publish". The clone keeps no Git remote, so it holds no credential.
- -o, --org string
- Org that owns the skill
Example
$ valet skills clone research
Cloned research v4 from acme org into ./research
Run valet deploy in ./research to publish your changes.valet skills create
Create an org skill
valet skills create [dir] [flags]Create an org skill.
Creates the skill a directory's SKILL.md names, links the directory to it, and publishes the directory as its first version. The directory defaults to the current one. Every file in it is published, except the .git and .valet directories. Run "valet deploy" in the directory to publish its next version.
With --from catalog:<name>, installs a copy of that catalog skill instead and reads no directory. The copy is the org's own skill: edit it and publish new versions like any other. It does not change when Valet updates the catalog.
- --from string
- Install a catalog skill, written catalog:<name>
- -o, --org string
- Org to create the skill in
Example
$ valet skills create ./research
Created research in acme org: v1
$ valet skills create --from catalog:premortem
Installed premortem from the catalog in acme org: v1valet skills destroy
Destroy an org skill
valet skills destroy <name> [flags]Destroy an org skill.
Destroys the skill, its releases, and its repository, and frees its name. A skill attached to an agent can't be destroyed: detach it first. For a built-in skill, Valet's default answers again.
The command asks for confirmation; pass --yes to skip it, which a script must, since the prompt needs a terminal.
- -o, --org string
- Org that owns the skill
- --yes
- Skip the confirmation prompt
Example
$ valet skills destroy research
This destroys research and all its releases. It cannot be undone. Continue? (y/N) y
Destroying research in acme org... done
$ valet skills destroy research --yes
Destroying research in acme org... donevalet skills detach
Detach a skill from an agent
valet skills detach <source-or-name> [flags]Detach a skill from an agent.
Pass the original source ref, such as catalog:research, or the materialized skill name, such as research. The org skill snapshot or catalog entry is not deleted.
- -a, --agent string
- Agent to detach the skill from
- -o, --org string
- Org that owns the agent
Example
$ valet skills detach catalog:research --agent assistant --org acme
Detaching catalog:research from assistant agent in acme org... done
$ valet skills detach research --agent assistant
Detaching research from assistant agent... donevalet skills info
Show org skill details
valet skills info <name> [flags]Show detailed information about an org skill.
Displays the skill's description, its author, its address and access mode, its origin (catalog:<name> for a copy installed from the catalog, custom:manual for one the org created), its active release, whether it is starred, the release history, and the agents that hold it. The Ref line is the form to declare in a manifest's skills: list. An agent that holds the skill follows its active release.
- -o, --org string
- Org that owns the skill
Example
$ valet skills info premortem
=== Skill: premortem in acme org
Name: premortem
Description: Run a premortem on any plan
Author: Alice Example
URL: https://premortem.acme.valet.run
Access: private
Origin: catalog:premortem
Active release: v2
Content SHA-256: 4bf5c2…
Starred: since 2026-07-03T00:00:00Z
Created: 2026-07-01T00:00:00Z
Updated: 2026-07-02T00:00:00Z
Ref: org:premortem
=== Versions (2)
v2 4bf5c2… 2048 bytes 2026-07-02T00:00:00Z
v1 9d01ae… 1024 bytes 2026-07-01T00:00:00Z
=== Held by (1)
support-botvalet skills publish
Publish a new version of an org skill
valet skills publish [dir] [flags]Publish a new version of an org skill.
Publishes the directory as the next version of the skill its SKILL.md names. The directory defaults to the current one. Every file in it is published, except a .git directory, and a file the latest version has that the directory lacks is removed. Files identical to the latest version publish nothing.
The CLI sends the files with Git. A skill can hold up to 500 files and 50 MB, with at most 25 MB per file, and binary files.
- -o, --org string
- Org that owns the skill
Example
$ valet skills publish ./research
Published research in acme org: v4
$ valet skills publish
research in acme org: no changes since v4valet skills rename
Rename an org skill
valet skills rename <name> <new-name> [flags]Rename an org skill.
The skill keeps its history and its attachments. Valet publishes a release whose SKILL.md carries the new name, and every agent that attaches the skill uses the new name from its next start.
If the current directory is linked to the skill, rename updates the link. Edit the name in your own copy of SKILL.md before the next publish.
- -o, --org string
- Org that owns the skill
Example
$ valet skills rename research deep-research
Renamed research to deep-research (v7).
Attached to support-bot and triage-bot. Update any instructions that name the old skill.valet skills show
Print an org skill's SKILL.md
valet skills show <name> [flags]Print an org skill's SKILL.md.
Prints the org's own skill, or, for a built-in skill the org has not changed, Valet's current default. The SKILL.md goes to stdout and the source line to stderr, so the output can be redirected to a file.
With --path, prints that supporting file, such as reference/guide.md, instead of SKILL.md. With --release, prints that release instead of the active one. "valet releases <skill>" lists the releases.
- -o, --org string
- Org that owns the skill
- --path string
- Print this supporting file instead of SKILL.md
- --release int32
- Print this release instead of the active one
Example
$ valet skills show governance --org acme > SKILL.md
governance in acme org: Valet's default
$ valet skills show premortem
premortem in acme org: v2
$ valet skills show premortem --release 1
premortem in acme org: v1
$ valet skills show premortem --path reference/guide.mdvalet topics
Read help guides
Read help guides on common Valet workflows and concepts.
Available topics cover getting started, the agent lifecycle, channels and sessions, and MCP connectors. Run "valet topics <name>" to read a specific guide.
valet topics agent-lifecycle
Agent creation, linking, and deployment
valet topics agent-lifecycle [flags]Agent lifecycle: creation, linking, and deployment.
An agent project is a directory containing a SOUL.md file that defines the agent's personality, skills, and behavior.
Creating an agent:
$ valet agents create my-agent
This creates the agent on the server, links the current directory to it, and deploys the first release. The directory must contain SOUL.md. When --org is not specified, the default org is used.
Creating from a source:
$ valet agents create my-agent --from catalog:code-reviewer --org acme $ valet agents create my-agent --from github.com/user/repo $ valet agents create my-agent --from ./path/to/agent
The --from flag accepts a catalog reference, a Git URL, or a local path. Catalog references scaffold a Valet-curated agent template.
Attaching resources at creation:
$ valet agents create my-bot --org acme \
--attach-connector github \
--attach-channel gh-webhookUse --attach-connector and --attach-channel to wire org-scoped resources to the agent at creation time.
Linking a directory:
$ valet agents link my-agent
Links the current directory to an existing agent. Creates a .valet/config.json file so subsequent commands use this agent automatically.
Deploying:
$ valet deploy
Packages the current directory into a release tarball, uploads it, and activates it. Uses the linked agent name unless one is provided explicitly. Waits for the agent to become ready. Use --no-wait to skip the readiness check.
Agent info:
$ valet agents info my-agent
Shows detailed information about an agent including its current release, state, attached connectors, channels, and effective environment (env vars with secret values masked and plain values shown inline; manage them with "valet env").
Destroying:
$ valet agents destroy my-agent
Permanently removes the agent and all its releases. The command asks for confirmation. Pass --yes to skip it; a script must.
valet topics channels
Channels and sessions
valet topics channels [flags]Channels and sessions.
Channels are message entry points for agents. Each channel has a type and belongs to an org or to one agent. An org channel (webhook or slack) reaches an agent through an attachment, so one org channel can serve several agents.
Channel types: - webhook: Receives HTTP webhooks from third-party services - telegram: Connects a Telegram bot to an agent - heartbeat: Fires a prompt on a fixed interval - cron: Fires a prompt on a cron schedule
Browsing the catalog:
$ valet channels catalog $ valet channels catalog get github-webhook
The catalog contains Valet-curated channel definitions for well-known services. Catalog entries encode signing schemes, event taxonomies, and service-specific behaviors.
Adding from the catalog:
$ valet channels create github-webhook --org acme $ valet channels create github-webhook --org acme --as github-docs
Use --as to give the channel a custom name when adding multiple instances of the same catalog entry.
Creating a channel directly:
$ valet channels create webhook slack --agent my-agent $ valet channels create heartbeat health --agent my-agent --every 5m $ valet channels create cron daily --agent my-agent --schedule "every day at 9:00am" $ valet channels create telegram bot --agent my-agent
Each channel has a prompt path (defaults to channels/<name>.md).
Attaching an org channel to an agent:
$ valet channels attach github-webhook --agent my-bot $ valet channels attach github-webhook --agent my-bot --events push,pull_request
Use --events to filter which event types are delivered to the agent. Use --as to give the attachment a custom alias.
Detaching:
$ valet channels detach github-webhook --agent my-bot
Webhook signature verification:
Each webhook channel has a verification scheme that validates incoming requests. Signing secrets are stored as env vars (kind secret, so the agent never sees them) and referenced by the channel via {{NAME}}; channels added from the catalog create them automatically. Manage them with "valet env". Use --verify to select a scheme:
hmac-sha256 HMAC-SHA256 of the raw body. Default header:
X-Webhook-Signature. Auto-detects sha256=<hex>,
v1=<hex>, raw hex, and raw base64 formats. Use
--signature-header to change the header name. stripe HMAC-SHA256 of "{timestamp}.{body}". Default
header: Stripe-Signature. Parses t=<ts>,v1=<hex>
from the header value. Works with any provider
that uses this format (Stripe, WorkOS, etc). Use
--signature-header for providers with a different
header name (e.g. WorkOS-Signature). svix HMAC-SHA256 of "{msg_id}.{timestamp}.{body}".
Reads svix-id, svix-timestamp, svix-signature
headers, falling back to webhook-id,
webhook-timestamp, webhook-signature (Loops.so
and other standard-webhooks senders). Secret
must be base64-encoded, optionally prefixed
with whsec_. static-token Constant-time comparison of a bearer token.
Default header: X-Webhook-Signature. Use
--signature-header to change the header name. none No verification. Use for testing or trusted
networks.valet topics connectors-overview
Connectors (MCP and command)
valet topics connectors-overview [flags]Connectors: tool and CLI access for agents.
Connectors give agents access to external tools and CLI commands. Two types are supported: MCP server connectors (structured tool access via the Model Context Protocol) and command connectors (CLI tools with automatic secret injection).
MCP Server Connectors:
MCP server connectors expose structured tools to agents. Each defines a transport and can be scoped to an agent or an org.
Transports: - stdio: runs a local command (e.g., npx -y @modelcontextprotocol/server-slack) - sse: connects to a remote server via Server-Sent Events - streamable-http: connects via HTTP streaming
Creating MCP server connectors:
$ valet connectors create slack --transport stdio \
--command npx --args=-y,server-slack \
--env SLACK_BOT_TOKEN={{SLACK_BOT_TOKEN}} \
--env SLACK_TEAM_ID={{SLACK_TEAM_ID}} $ valet connectors create linear --transport streamable-http \
--url https://mcp.linear.app/mcpEnvironment variables and headers can reference env vars using the {{NAME}} template syntax. The connector stores the reference and the control plane resolves it at deploy time. Templates can appear anywhere in a value (e.g. https://{{HOST}}/api). Use "valet env set NAME=VALUE" to create env vars before referencing them. Env vars are secret by default -- hidden from the agent -- which is right for credentials; pass --plain for values the agent should also read directly from its environment. Both kinds resolve in templates.
Command Connectors:
Command connectors wrap CLI tools and make them available on the agent's PATH. They inject secrets automatically — the agent calls the connector name as a regular command and secrets are resolved transparently.
Naming convention:
Name the connector after the CLI command the agent will type. The connector name becomes the executable on the agent's PATH, so it must match the command the agent is expected to run. For example, if the CLI command is "gh", name the connector "gh". If the CLI is installed via npx (e.g., npx -y agentmail-cli installs the "agentmail" command), name the connector "agentmail" — not the npm package name.
$ valet connectors create gh --type command \
--command gh --secrets GITHUB_TOKEN $ valet connectors create agentmail --type command \
--command npx --args=-y,agentmail-cli \
--secrets AGENTMAIL_API_KEYThe second example names the connector "agentmail" (the CLI command) even though the npm package is "agentmail-cli". The agent runs "agentmail inboxes list" and the wrapper transparently handles npx, args, and secret injection.
How command connectors work at runtime:
The supervisor generates a wrapper script in ~/bin/ named after the connector. When the agent calls this command, the wrapper injects the configured secrets and runs the underlying command.
The agent runs "gh pr list" and the runtime connector helper injects the connector's secrets. The agent never sees the secret values directly.
Important: the agent runs the connector name, not the underlying command or npx invocation. Only the connector name is on PATH:
agentmail inboxes list # correct — connector name npx agentmail-cli inboxes list # wrong — bypasses the wrapper agentmail-cli inboxes list # wrong — not on PATH
SOUL.md workflow steps should reference the connector name as the command the agent should run.
Browsing the catalog:
$ valet connectors catalog $ valet connectors catalog get github
The catalog contains Valet-curated connector definitions for well-known services. Each entry defines transport, command, and required secret slots.
Adding from the catalog:
$ valet connectors add github --org acme $ valet connectors add github --org acme --as github-readonly
Use --as to give the connector a custom name when adding multiple instances of the same catalog entry with different credentials.
Attaching an org connector to an agent:
$ valet connectors attach github --agent my-bot $ valet connectors attach github --agent my-bot --as gh-tools
Use --as to give the attachment a custom alias on the agent.
Detaching:
$ valet connectors detach github --agent my-bot
Scoping:
Connectors can be scoped to an org (--org) or directly to an agent (--agent). Org-scoped connectors are configured once and shared across agents in the organization. Agent-scoped connectors belong to a single agent.
$ valet connectors --org acme # list org connectors $ valet connectors --agent my-bot # list agent connectors
valet topics getting-started
Getting started with Valet
valet topics getting-started [flags]Getting started with Valet.
1. Log in:
$ valet auth login
2. Create an agent from a directory containing a SOUL.md:
$ cd my-agent-project $ valet agents create my-agent Creating agent... done, my-agent Linking directory... done Deploying... done, my-agent v1 Waiting for agent to start... done
3. Deploy new releases after making changes:
$ valet deploy Deploying... done, my-agent v2 Waiting for agent to start... done
4. Start an interactive console session:
$ valet console my-agent
5. Add a connector from the catalog:
$ valet connectors catalog $ valet connectors add github --org acme $ valet env set GITHUB_TOKEN=ghp_abc123 --org acme
Env vars are secret by default: the agent can use them through connectors but never sees the values. Pass --plain for values the agent should read directly from its environment (a region, a base URL).
6. Attach the connector to your agent:
$ valet connectors attach github --agent my-agent
7. Add a webhook channel:
$ valet channels create webhook slack --agent my-agent
8. Check your agents:
$ valet agents
valet topics resolution
How Valet resolves agents and orgs
valet topics resolution [flags]How Valet resolves agents and orgs.
Most valet commands target an agent, an org, or both. The CLI resolves your target from three sources, in precedence order:
1. Flags — --agent and --org on the command line 2. Project link — .valet/config.json in your project 3. Default org — set at login or with "valet orgs set-default"
# The Rules
Flags override everything. If you pass any flag, the CLI uses only your flags — project link and default org are ignored. One exception: a command that needs an agent, app, or site, given only --org, uses the linked one when the link names that same org.
In a linked project, the project's agent and org are used together as a pair. "valet agents create", "valet apps create", and "valet sites create" link the directory they run in; "valet agents link", "valet apps link", and "valet sites link" pin an existing directory.
Otherwise, the default org is used. Agent is unspecified, so commands that require an agent will error.
Sources are never mixed. If you pass --agent without --org and you belong to multiple orgs where that agent name exists, the server returns an error listing the orgs — pass --org to disambiguate.
# Command Kinds
AgentRequired --agent, or a linked project
(org is optional — the server resolves it)OrgRequired --org, or the default org
DualScoped --agent or --org (or a linked project)
Scope follows whichever is populated.# Examples
Single-org user, unlinked directory:
$ valet agents # uses your one org $ valet deploy --agent foo # --agent wins
Multi-org user, unlinked directory:
$ valet orgs set-default acme # pick your default $ valet agents # lists agents in acme $ valet agents --org widgets # lists agents in widgets
Linked project:
$ cd ~/src/my-reviewer $ valet deploy # uses the project's link
Override a link:
$ cd ~/src/my-reviewer
$ valet deploy --agent other --org acme
# flags win; link ignored# Errors
"--agent is required (or run from a linked directory)."
Command needs an agent. Pass --agent or cd into a linked
project. Commands that take --app say "--app is required"."--org is required (or set a default with 'valet orgs set-default')."
Command needs an org. Pass --org or set a default."specify --agent, --org, or run from a linked directory."
A dual-scoped command saw nothing. Pick a scope."agent 'foo' exists in multiple orgs (acme, widgets)..."
Multi-org user passed --agent alone where that name is
ambiguous. Pass --org to pick one.# Commands That Help
valet auth whoami shows your default org and any
linked project
valet agents link <name> link the current directory to an
agent
valet orgs set-default change your default org
valet orgs list your membershipsvalet update
Update the Valet CLI to the latest version
valet update [flags]Update the Valet CLI using the method that installed it.
Official direct installations download and verify the latest stable release. Homebrew installations continue to update through Homebrew. Unknown or manually-copied binaries are never modified.
$ valet update
Valet 1.2.3 is already up to date.valet version
Print the CLI version
valet version [flags]Print the Valet CLI version, platform, and Go runtime version.
$ valet version
valet/1.0.0 darwin-arm64 go1.24.0Next steps
- Get started: connect your agent and publish.
- MCP server: use Valet from an MCP client.