The pipeline
Four extractors read what you already wrote. One file is the result. Only tools in that file exist. Nothing else reaches your API.Fails closed. A route the extractor cannot classify is written
disabled, with a note saying why. Enable it deliberately after you read it.Declare your schemas: openapi.json
The single highest-leverage file you can add is anopenapi.json at your app root (public/openapi.json and docs/openapi.json — or .yaml — are read too). Without a spec, a plain route scan finds your endpoints but not their shapes: each tool arrives as a method and a path with no parameters and no output schema, and the report says so —
GET /api/orders may support status, customer_id, and limit, and the model has no way to know any of them exist. Add the spec and re-run npx vendo init (or vendo sync) and the same routes come back with every parameter name, type, and output shape declared:
One tool, honestly
Every entry carries the same five fields. Here is one, whole..vendo/tools.json
descriptionis written for the model: what the tool does for the user, not a restatement of the path.riskis what the guard reads before the call.destructiveasks first.bindingis where the call lands. The runtime executes from it without re-reading your spec.
Where the grade comes from
Extraction grades from protocol facts only.DELETE is destructive and a tRPC mutation is at least write; a name decides nothing.
Everything else lands ungraded, which the guard asks about on every call. The grading pass reads the handler behind each tool and writes what it finds to .vendo/judgments.json.
The grading pass runs on your Vendo Cloud key.
Keeping it current
The tool surface is a build artifact, so it moves when your API moves.1
Edit your API
Add the route, the procedure, or the action. Nothing about it is Vendo-shaped.
2
Run npx vendo sync
The extractors re-read your source. No server starts.
3
Read the diff in git
.vendo/tools.json is a tracked file, so a new capability arrives as a reviewable change.vendo init hooks sync into predev and prebuild in your package.json, so step 2 also runs on its own.
Overrides
Corrections live in their own file, which sync never touches..vendo/overrides.json
grant-invalidated decision.
Compound tools
The same file’scompounds array bundles a short sequence of existing tools into one capability the agent calls by name.
.vendo/overrides.json
tools even when it is empty — it is a required key. Each args value is a JSONata expression evaluated against { args, steps, item }, not a literal, which is how steps.create.id hands one step’s output to the next.
Two rules the loader enforces after the file parses: risk must equal the highest risk among the steps, and a step may only name an enabled primitive tool — never another compound. An entry that breaks either is quarantined with a console warning rather than failing the boot, so read the log once after adding one.
Each step still crosses the guard on its own descriptor, so approvals, grants, and audit apply per step. A compound entry inside tools.json is rejected.
Where to go next
Your API is one source of tools. Two more sit beside it.Connected accounts
Each user connects their own Gmail, Slack, or GitHub once.Connected accounts →
Automations
The same tools, fired on a schedule or by an event.Automations →
Guard
Risk grade, approval, and an audit line on every call.How Vendo works →