agent.yaml

Every field of an automation's YAML file, with types, defaults, and allowed values. The schema is strict, so an unknown key fails validation.

An automation is one YAML file under agents/, .agents/, ellipsis/, or .ellipsis/ (any depth, .yml or .yaml); the top-level ellipsis: block is what marks a file as one, and a YAML file in those directories without it is ignored. The schema is strict: an unknown or misplaced key (a top-level name: that belongs under ellipsis:, say) fails validation instead of being dropped. What an automation is and how a file deploys: Automations.

# yaml-language-server: $schema=https://www.ellipsis.dev/schemas/latest/agent-config.json
ellipsis:
  version: v1
  name: recent-work-summary

trigger:
  type: cron
  schedule: "0 9 * * 1"

claude:
  model: claude-haiku-4-5-20251001
  system: |
    Summarize the pull requests merged in the last week across the
    cloned repositories. Open a GitHub issue in web-repo titled
    "Weekly work summary" with the digest, grouped by repository.

environment: cloud_agent_environment

budget:
  session: 1.00

Every Monday at 09:00 UTC this opens one issue in web-repo and spends at most $1. The schema comment on line one gives you inline validation in any editor with a YAML language server.

Top-level fields

FieldTypeDefaultDescription
ellipsisobjectrequiredSchema version, name, description, metadata, and the enabled flag. Its presence marks the file as an automation.
claudeobject{}Claude Code runtime: instructions, model, effort, fallback model, turn cap, settings file.
codexobject | nullnullRun on OpenAI's Codex CLI instead of Claude Code. Declaring the block is what selects it.
triggerobject | nullnullWhen the automation runs on its own: one trigger of type cron, react, or mention. Omit for an API and CLI only automation.
permissionsobject{}What the agent may do with the credentials minted into its sandbox: the Ellipsis API token and the GitHub token.
environmentstring | object{}Where the agent runs: the name of a saved environment, or an inline environment block.
skillslist of skill objects[]Claude Code skills installed for the session beyond what the cloned repositories provide.
inputobject | nullnullTyped input: a JSON Schema for the payload an API-started session takes, and an initial-message template.
outputobject | nullnullJSON Schema the session's result must satisfy. Read it back with GET /v1/sessions/{id}/output.
budgetobjectall nullPer-session and trailing spend caps, in US dollars.

ellipsis

FieldTypeDefaultDescription
versionstringv1Schema version. v1 is the only supported value.
namestringrequired to deployThe automation's address, used by the API and CLI. Lowercase letters, digits, hyphens, and underscores, starting with a letter or digit, at most 64 characters, never starting with agent_.
descriptionstring | nullnullProse shown in the dashboard.
enabledbooleantrueWhen false, cron, react, and mention starts are skipped. API and CLI starts still work.
metadataobject{}labels (list of strings) and annotations (map of string to string). Organizational only; no effect on a session.

An automation declares no kind. ellipsis.kind: environment, slack, or code_review routes the file to a different schema; kind: agent fails validation, so omit the key. Whether a session accepts messages while it runs is a per-session request flag, not a field in this file.

claude

FieldTypeDefaultDescription
systemstring | {file} | list of both""The agent's instructions, appended to Claude Code's default prompt. A {file: path} entry reads a UTF-8 file (64 KiB max) from a repository at session start; a list joins its parts in order. Empty runs Claude Code's own default prompt.
system[].filestringrequiredPath relative to the repository root: no leading /, no .., not an automation file.
system[].repositoryobject | nullthe automation's ownname, optional owner, optional ref. Any repository of your installation or a public one; a private repository outside your installation is rejected.
modelstring | nullnullOmitted, the session uses your account default model, then the platform default claude-opus-5. An unknown id, a model Claude Code cannot run, or a retired model fails validation.
effortenum | nullnullReasoning effort: low, medium, high, xhigh, or max. Omit for the model default.
fallback_modelstring | nullnullModel Claude Code switches to when the primary is overloaded. Same rules as model.
max_turnsinteger | nullnullHard cap on agent turns; must be greater than 0. The budget bounds the session independently.
settingsobject | nullnullA Claude Code settings.json in a repository: path (same rules as system[].file) plus optional repository. Applied below Ellipsis-managed settings, so it cannot weaken them.

codex

Declaring codex: runs the automation on OpenAI's Codex CLI. It has no effort, fallback_model, max_turns, or settings, and skills and MCP servers are not wired through; setting one fails validation rather than being ignored.

FieldTypeDefaultDescription
systemstring | {file} | list of both""Same shapes and rules as claude.system.
modelstringgpt-5.6-terraA model that speaks the OpenAI Responses API. Any claude-* id or a retired model fails validation.

trigger

At most one trigger, discriminated by type.

typeFields
cronschedule (required): five-field cron ("0 9 * * 1") or an EventBridge cron(...), rate(...), or at(...) expression, in UTC. A five-field expression may restrict day-of-month or day-of-week, not both.
reactExactly one surface block from the table below.
mentionplatforms (default []): which @ellipsis mentions this automation answers, from github and linear. Empty means both. Slack routing is slack.yaml, not a mention trigger. When several enabled automations claim a platform, the oldest answers.

React surfaces, each a block under trigger: carrying its own on list and filters:

SurfaceonFilters
pull_requestrequired: opened (opened, reopened, or marked ready), pushed (every head advance, including the open), merged, closed, review_submitted, commentedrepositories, base, head, draft, labels, paths, for
pushnone; every push to a matching branch firesrepositories, branch, paths, for
issuerequired: opened, closed, commentedrepositories, labels, for
linear_issuedefault [opened]; opened is the only valuefor
sentryrequired: issue_alert (an issue alert rule fired), metric_alert (a metric alert entered critical)projects
slack_channelnone; fires when a channel is created in the connected workspacenone
FilterTypeDefaultDescription
repositorieslist of strings | {include, exclude}allRepositories to watch, by name. A bare list is include; empty include matches every repository of the installation, including ones added later. Independent of environment.
base, head, branchlist of strings[]Branch filters: exact names, prefixes ending in * (release/*), or default for the repository's default branch. Empty matches any branch.
draftboolean | nullnulltrue matches only draft pull requests, false only non-draft, null both.
labelslist of strings[]Matches when any listed label is present.
pathslist of strings[]Changed-file globs. Include-only; a ! pattern fails validation.
projectslist of strings[]Sentry project slugs. Empty matches every project.
for{users, bots}users true, bots falseWho may trigger, classified on the author (the pusher for push). Each of users and bots is true, false, a list of logins, or {include, exclude}.
trigger:
  type: react
  pull_request:
    on: [opened, pushed]
    repositories: [web-repo, api-repo]
    base: [default]
    draft: false
    for:
      users: true
      bots: ["dependabot[bot]"]

permissions

FieldTypeDefaultDescription
ellipsistrue | "all" | resource maptrueThe sandbox's Ellipsis API token. true and "all" grant everything a sandbox token can do; a map narrows it per resource and can only reduce access. false fails validation.
githubobject{}The GitHub token minted for the sandbox (GH_TOKEN). By default it carries the installation's full permissions on all of its repositories. Either field can only reduce that; GitHub enforces the result.
github.permissionsread_only | map | nullnullread_only grants read on contents, issues, metadata, and pull_requests. A map names scopes one by one: checks (write only), administration and repository_projects (read, write, or admin), and actions, contents, discussions, issues, members, metadata, pull_requests, secret_scanning_alerts, security_events, vulnerability_alerts (read or write). An empty map or unknown scope fails validation.
github.repositorieslist of strings | nullnullRepository names the token may touch. Omitted means all repositories of the installation; an empty list or a duplicate fails validation.

The ellipsis map keys are resources: account, alerts, sessions, files, memories, reviews, configs, defaults, environments, secrets, templates, integrations, tokens. Each value is a level (read < write < delete, higher includes lower), a {level, match} grant, or a list of either; an unlisted resource is denied. match is a list of globs over the instance key and is only allowed on sessions, files, memories, secrets, and configs.

permissions:
  ellipsis:
    sessions: write
    files:
      - read
      - level: write
        match: ["reports/*"]
  github:
    permissions: read_only
    repositories: [web-repo]

environment

A string names a saved environment (its name, or its env_ id), substituted in at session start. An object defines the environment inline with the same six fields an environment file has: repositories, variables, compute, image, hooks, and mcp_servers. Field detail: Environments.

environment.mcp_servers

An entry is a built-in by bare name or {name}, or a custom server you define. Built-ins are linear and slack; a bare string with any other name fails validation, and a custom server may not reuse a built-in name or appear twice. A built-in entry only matters when that integration is set to opt-in inclusion; an integration left on all sessions is available regardless. GitHub is the gh CLI, always present, and takes no entry.

ShapeFields
stdioname, command (required, run inside the sandbox), args (default []), env (default {}). Install the command's runtime through image if the base image lacks it.
remotename, url (required, http:// or https://), headers (default {}).

env and headers values may embed ${NAME} references, whole-value or inline (Bearer ${TOKEN}), resolved from your stored secrets at session start; a reference to a secret that does not exist fails the session.

skills

Skills under a cloned repository's .claude/skills/ load on their own; an entry here brings in a skill the clones do not provide. At most 10 per automation, each at most 50 files and 512 KiB, 64 KiB per file, UTF-8 only.

FieldTypeDefaultDescription
pathstringrequiredDirectory containing SKILL.md, relative to the repository root; not . and not an automation file. Its last segment is the installed name, so it must be unique across the list.
repositoryobject | nullthe automation's ownname, optional owner, optional ref. Same repository rules as claude.system[].repository.

input

At least one of the two fields. json_schema is not allowed on a react automation, whose payload is the surface's own fields.

FieldTypeDefaultDescription
json_schemaobject | nullnullJSON Schema (type: object at the root) for the input an API or CLI start passes. Validated when the session starts.
messagestring | nullnullInitial-message template with {{path}} substitution and nothing else (no conditionals). Every path must exist in json_schema, or on a react automation in the surface's published fields; otherwise deployment fails. Example: Implement {{issue_url}}.

output

FieldTypeDefaultDescription
json_schemaobjectrequiredJSON Schema the agent's final output must satisfy. Read it with GET /v1/sessions/{id}/output.

budget

All values in US dollars. session caps one session; day, week, and month cap this automation's own trailing spend over 1, 7, and 28 days. Account-wide limits: Organization.

FieldTypeDefaultDescription
sessionnumber | nullaccount defaultThe account default is $250, which is also the maximum.
daynumber | nullnullTrailing one-day cap. Platform ceiling $1,000.
weeknumber | nullnullTrailing seven-day cap. Platform ceiling $10,000.
monthnumber | nullnullTrailing 28-day cap. Platform ceiling $40,000.

Validation

Every path runs the same validator. When a commit to the default branch makes a file invalid, the automation keeps running its last good version and the error is recorded; the automation's page in the dashboard shows the message and the commit it came from. agent automation create -f agents/recent-work-summary.yaml sends the file to POST /v1/automations, which rejects an invalid definition with 400 and the same message. Referenced files (system[].file, settings.path, skills[].path) are checked again at session start at the session's own commit, and a missing one fails the session before the agent runs.

On this page

Schedule a demo