Skip to main content
Create, compose, publish, install, and govern agents. An agent bundles MCP servers, skills, hooks, prompts, and sandboxes into one versioned Registry object. Canonical identities use namespace/slug. Commands also accept UUIDs, unambiguous bare names, aliases, and row numbers from the latest Agent list.

Commands

Every leaf command supports --output table|json. JSON success output contains no Rich text, prompt, banner, or spinner. JSON failures leave stdout empty and write one categorized object to stderr.

Create

Use complete flags for automation:
Other modes:
The no-flag form is interactive and cannot run in JSON mode. Flag mode requires --name and either --prompt or --prompt-file. Versions must be semantic versions and every repeated --harness must be registered. --team HANDLE --visibility team creates a private teamspace agent. --visibility team requires --team. JSON returns the direct server Agent object.

Bulk create

Input may be an array or an object containing an agents array:
Input contains 1-50 agents. The CLI rejects malformed fields and duplicate canonical names before HTTP, and the server applies the same duplicate rules. JSON mode requires either --dry-run or --yes. Results include per-agent statuses, summary counts, and partial. Item errors set partial: true and exit with code 11; skips alone remain successful.

List, my, and show

list JSON is paginated:
The most recent list or my result is cached for row-number references. Empty results clear stale Agent rows. --interactive is human-only and cannot be combined with JSON. my returns the standard items, total, page, and page_size envelope, including pending, approved, rejected, and archived agents. Empty results use items: []. show returns the direct Agent object, including component links and success criteria.

Fork an approved agent

SOURCE accepts a UUID, namespace/slug, an alias, or a cached row number. Only a currently approved listing and an approved source version can be forked. The default is the newest stable approved version. A fork begins as your draft in a personal or permitted team namespace; it keeps approved component references, not copies of the components. A private source may be forked only into the same private teamspace. A name collision returns conflict rather than changing an existing agent. A disabled fork setting returns permission denied; per-user rate limiting returns exit code 8. --dir creates a new observal-agent.yaml containing the fork ID and editable fields, including exact component pins, model_config_json, and external_mcps. It refuses to overwrite an existing file before sending the fork request. JSON returns the direct draft object, plus yaml_path when provided. To edit this fork without creating a second listing:
--update uses the scaffold’s agent_id to target the draft exactly, even though drafts do not appear in the public search. The submit command uses the ID returned by fork. A draft requires review before appearing in public fork counts or lists. show displays Source unavailable instead of saved source identity when access to the original has been lost; never infer provenance from a cached reference.

Generate installation config

install asks the server to generate config but does not write it:
JSON returns the complete server installation result. Legacy --raw prints only config_snippet; new automation should use the shared output option. Use observal agent pull to write and track the generated installation.

Archive, delete, and restore

delete is an alias for the same reversible archive operation. JSON mode never prompts and requires --yes. JSON returns the direct updated Agent object.

Local authoring workflow

Initialize

The no-flag form is interactive. JSON mode requires complete flags and refuses to overwrite an existing definition. Writes are atomic.

From a working session

--from-capabilities pre-fills components and supported_harnesses from the resources recorded in the capability lock for the current directory (see observal discover): everything loaded with discover use and every component installed here in the last 24 hours (--since accepts 45m, 2h, 3d, 1w). In JSON mode a default description and prompt are filled in when omitted. Agents cannot nest other agents, so a pulled agent is reported under from_capabilities.skipped_agents rather than added. Exit code 5 when nothing was used in the window. JSON returns:

Add components

Find a component in Registry JSON, then copy its UUID:
Valid types are mcp, skill, hook, prompt, and sandbox. Duplicate type and UUID pairs return conflict exit code 6. Invalid types or IDs return validation exit code 7. Pin an exact component release with --version:
This writes version: 1.4.2 on the component entry. Without a version, the Agent keeps the version its current release pins, or pins the latest approved release when it first gains the component. Versions are matched exactly; latest and ranges are not accepted. A release pins approved versions only; a draft may also pin a component release still in review, but only one you can read (your own component, or as an admin or reviewer). JSON returns the YAML path and added component.

Build

Build verifies every component, checks that any pinned component version exists, and validates whether private components are visible to the target owner. A successful JSON result contains valid, agent, components, and issues. Invalid composition exits with code 7 and leaves JSON stdout empty; the stderr error includes the same repairable data under error.result.

Publish

--draft and --submit are mutually exclusive. Scope changes cannot be combined with --update; use ownership transfer or a separate visibility operation. Non-interactive updates may use --bump patch|minor|major. --update edits the latest version in place, so it only works while that version is a draft, pending, or rejected. An approved version is immutable: installs and locks depend on it. The server answers conflict exit code 6 and points to observal agent release, which publishes a new version for review. JSON returns the direct created, saved, submitted, or updated Agent object.

Release and versions

Release obtains the server’s semantic-version suggestion, submits the complete YAML snapshot, then updates local YAML atomically only after the server accepts the release. A failed server request leaves the local version unchanged. Every release pins each component to an exact version, and those pins are what every pull of the release installs. A release keeps the pins of the Agent’s current release, so components never move unless the author asks:
  • give a component a version in the YAML to pin that release;
  • pass --refresh-components to move every other component to its latest approved release.
Approval freezes the release’s lock. The review gate checks that each pinned component version is approved.

Check component pins

Lists each component the Agent version pins with its pinned version, its latest approved release, and a status: current, outdated, or unlocked (Agent versions released before pinning). Archived components are marked. Defaults to the latest Agent version. JSON returns agent_id, qualified_name, version, components, and a summary with total, outdated, unlocked, and archived counts. Consumers keep installing the pins; this is the author’s cue to release a refreshed version. Versions JSON returns the direct paginated server object. Page size is 1 through 100.

Transfer ownership

The username may optionally begin with @. JSON mode requires --yes and returns the direct server result.

Co-authors

Co-authors can edit and publish the same Agent:
List returns the standard list envelope. Add returns the added user. Remove requires the user UUID returned by list and returns the direct deletion result.

Pull

Pull writes harness files, records the exact Agent and component versions in observal.lock and the local lockfile, and reports every file and setup action. Later pulls keep the locked version until --upgrade or --version. See the Pull reference for pinning, strict mode, path, secret, merge, dry-run, and JSON behavior.

Exit codes

Common Agent failures use: