Skip to main content
A .vio file is a portable definition of a whole agent — prompt, model, skills, connectors and memory — in one YAML file. Everything the agent is made of is inside the file, so you can deploy a .vio someone sent you without any other assets.
Needs vio 1.0.0 or later for the checks on this page. --check-tools, the connector URL check and the warnings need 1.0.6. Check with vio --version.

Validate

From the shell:
Or as a subcommand, which is what scripts, CI and AI agents use:
Validation is local: no sign-in and no network, unless you opt in to --check-tools. A valid file prints a summary of what it contains. An invalid one exits 1 and names each field that’s wrong. Point vio at a folder and it looks for the .vio inside it (one level deep, not subfolders):
One match is used. Several is an error that lists them; none is a distinct “no .vio bundle found” error. For scripts and CI, print one JSON result:

What it checks

A bundle can be valid YAML, match the schema, and still fail the first time the deployed agent runs. vio validate catches those cases here, where they are one edit to fix, and vio deploy runs the same checks before it sends anything.
  • The schema — every field the .vio format requires.
  • Artifact digests — see Editing a bundle below.
  • Memory files the runtime can parse. Each memory artifact needs the frontmatter the runtime reads, including a meta block:
    A missing meta block, an unquoted schemaVersion, or a meta.id that differs from the artifact’s id is refused, with the reason.
  • Template variables the agent never receives. When an agent declares inputs, every {name} in the text it runs with — its first prompt, the skills it references, and the memory it reads or writes — must be one of them. Otherwise validation refuses the bundle and names the placeholder:
    Declare the input, or remove the placeholder. Literal braces such as a JSON example ({"a": 1}) are fine.
  • An optional field with no default. Every {name} must be declared exactly once — either as a persona-prompt variable with source: input, required: false and a default, or as an agent input with no default (which must then be required: true). Declaring the same name both ways is not redundant: an agent-declared input always wins the collision, which silently discards the prompt variable’s default — so a field left optional with no default is a run that omits it and fails with a missing-variable error. vio validate refuses this and names the fix, which differs by where the field lives:
    If the field is an agent input, the fix instead is to declare it only as a prompt variable (source: input, required: false, default: …) and remove it from the agent’s inputs — an agent input can never carry a default.
  • A connector given as an https:// URL. In requires[].connector, a catalogue id such as github is refused. The error prints the MCP URL to use instead.
  • A connector tool no referenced skill allows. Once an agent has one or more skills, the runner binds tools only from each skill’s own allowed-tools frontmatter — a connector tool named in requires[].tools reaches the agent only if some referenced skill’s allowed-tools also lists it. allowed-tools is one line, space-separated, not a YAML list:
    A skill with no allowed-tools line, or one missing a tool it needs, gets none of what’s missing — the deployed agent completes its run having told the model no tools are available. vio validate refuses a bundle with an unreachable connector tool and names it.

Check tool names against the live server

Plain vio validate never touches the network, so it can’t tell you that a tool name is wrong. A name the connector doesn’t offer is skipped at run time with no error. To check:
--check-tools runs the normal checks first. Then it asks each OAuth connector which tools it offers and compares every tool your bundle names, in requires[].tools and in each skill’s allowed-tools. It needs the network, and an authorisation that vio connect staged in the bundle’s Space. It’s opt-in, and in the shell it’s /validate agent.vio --check-tools.
  • A tool the server doesn’t offer fails the bundle with bundle.invalid and exit 1. The error names the closest real tools, for example Did you mean search_docs?.
  • A connector that can’t be asked is only a warning, and never changes the exit code. That covers one that isn’t staged, is unreachable, or refuses the check. If the provider says the authorisation lacks a scope (insufficient_scope), the message names the connector and the vio connect <connector> --scopes … command that fixes it.
  • To see a connector’s tools yourself, run vio connectors tools <connector>.
vio deploy runs the same check on staged connectors before it creates anything, so you only need --check-tools to find out earlier.

Warnings

Some problems don’t stop a deploy but probably aren’t what you meant. vio validate prints them as warnings and the exit code stays 0:
  • A skill-less agent with no input named task. Without skills, an agent only gets its task from an input named task. Rename the input to task, or give the agent a skill.
  • memory in a skill’s frontmatter. The runner ignores it. Memory is bound on the agent, in its memory block. See Memory.
  • A skill’s tools field. The runner never reads it. List the tools in the skill’s allowed-tools frontmatter instead.

Digest

In the shell, /digest agent.vio. As a subcommand:
Prints the deployment digest — the value a deployment records, and the one vio show and the Hub compare against. --content prints the whole-file content digest instead, and --json prints both.

Editing a bundle: fix the digests

Each artifact inside a .vio — every prompt, agent, skill and memory — carries its own digest in the manifest. Edit a body and its recorded digest no longer matches, and the deploy is refused. The file is still valid YAML and still passes the schema, so this is not something you can spot by eye. vio validate checks these, and vio digest --fix repairs them:
It prints each artifact it changed, old digest to new, and rewrites only those lines — your comments, key order and formatting survive. On a file that is already correct it changes nothing and exits 0. If it cannot rewrite the manifest it says so and writes nothing, rather than reporting a fix it did not make. It only runs on a bundle that is otherwise valid, so fix a schema, memory or placeholder problem first. So the loop for editing a bundle by hand, or with an AI coding agent, is:
--json tells the failures apart, which is what an AI agent should branch on:

Deploying a .vio you were given

1

Put it in a folder

2

Validate it

3

Deploy it

Follow Deploy an agent. The file never contains a provider key: either it runs on Viorant credits, or you provide the key.