Skip to main content
The umbrella owns the vendo bin. It has five commands.

vendo init [dir]

Interactive setup. It scans the app, then interviews you about your model import, the product brief, risk labels for critical tools, and the MCP door (theme is extracted automatically). It then proposes the handler and <VendoRoot> wiring. Every code change is permission-gated and shown as a diff. Init writes critical-tool risk answers to .vendo/overrides.json, and future sync runs respect them. Init also scans your host component registrations for statically capturable { name, component } sites and offers to wrap each with remixable: true. Every wrap is a confirmed code change like any other. Router tables with a path field are excluded. After you approve wraps, init re-runs sync so the new remixable slots capture immediately. Init detects the host framework from package.json and scaffolds only what applies. A next dependency gets app/api/vendo/[...vendo]/route.ts (under src/app when that directory exists), a layout that wraps <VendoRoot>, and, when you opt into MCP in the interview, a sibling .well-known/[...vendo]/route.ts. An express dependency gets a vendo/server.ts (vendo/server.mjs without a tsconfig.json) holding the createVendo() composition and a Node HTTP-to-fetch adapter, plus a starter vendo/ai.ts. Mount the adapter with app.use("/api/vendo", mountVendo()) and wrap the client entry in <VendoRoot> to finish. Init detects only next and express, checking next first, so an app with both gets the Next scaffold; any other host is treated as Next. dir is the app to initialize and defaults to the current directory. Init also provisions VENDO_STORE_ENCRYPTION_KEY in your host .env — a 32-byte base64 key the default composition uses to encrypt vendo_secrets at rest. The append is safe: init never regenerates the key, even with --force. Options:
  • --agent emits the setup plan as JSON and writes nothing: the detected framework, every proposed code diff, the four plain-language questions, extraction (deterministic extraction runs first, against a throwaway directory, so the plan carries the extracted tools), and riskRecommendations (per-tool advice: destructive tools should be marked critical, disabled tools reviewed before enabling).
  • --yes skips the interview, shows the proposed diffs, and approves every code change. Combine it with --model-import and --brief for unattended setup.
  • --force regenerates Vendo-owned files under .vendo/. It does not replace existing host source files.
  • --model-import <specifier> sets the module that exports the host’s AI SDK model (default @/lib/ai for Next.js and ./ai for Express).
  • --brief <text> supplies the product brief written to .vendo/brief.md.
Init rejects options it does not recognize and exits 1 before doing anything, so a flag the installed CLI does not support (for example --agent on an older version) can never be silently dropped and turn a read-only request into a writing init. When the host repo has a .claude/ directory and no .claude/skills/vendo-setup/SKILL.md, init also offers (through the same diff consent as every code change) to install the vendo-setup agent skill shipped inside the npm package. An edited copy is never overwritten or re-prompted; deleting the copy makes init offer it again on the next run, like any missing scaffold. Init also proposes idempotent predev and prebuild hooks in package.json so extraction runs alongside your existing dev and build scripts:
If either script already exists, vendo sync is prepended. Existing formatting is preserved. The change is shown as a permission-gated diff like every other init proposal, so you can accept or decline it.

vendo doctor [dir]

Checks wiring and makes one live /status round trip. It recognizes both Next.js (catch-all route plus a layout that mounts <VendoRoot>) and Express (the server composes createVendo from @vendoai/vendo/server; the client mounts <VendoRoot>). It ends with the config line that unlocks each remaining block. Doctor also runs two live HTTP probes against the running dev server so silent credential-forwarding traps surface before you ship:
  • Present-mode forwarding. Doctor calls POST /doctor/present and the composition executes a synthetic same-origin tool. The echo route reports booleans indicating whether the doctor’s authorization and cookie headers reached the host API. The probe fails with actionable text when VENDO_BASE_URL is unset or points at the wrong origin, when the binding is cross-origin, or when the dev server is down. No credential values are printed, logged, or persisted.
  • actAs mint and verify. Doctor calls POST /doctor/act-as so the host-configured createVendo({ actAs }) mints auth material and the host’s own principal resolver accepts it. This works with any actAs implementation, including the actAs presets. When actAs is unconfigured, doctor warns but does not fail; mint or verify errors produce actionable failure text.
The synthetic /doctor/* routes are development-only and return 404 in production. When the MCP door is open, doctor also validates the registry discovery surface:
  • both OAuth metadata documents (/.well-known/oauth-protected-resource/... and /.well-known/oauth-authorization-server/...) resolve
  • the server card at /.well-known/mcp/server-card.json parses
  • a server.json in the project root, if present, matches the MCP registry schema and its remote URL agrees with the live door
  • a local public/.well-known/mcp-registry-auth challenge file starts with v=MCPv1, and the same challenge served over HTTP parses when present
Exit codes:
  • 0: green
  • 1: broken wiring

vendo sync [dir]

Runs the build-step extraction manually. It updates tool extraction, remix baselines, and the host component catalog for dir, which defaults to the current directory. The default is fail-soft and warns on breaking changes. When tools changed or broke, sync asks the running dev server which saved apps, automations, and grants they impact and prints one impact: line per tool (or impact unknown when no server is reachable). Drifted pins get an advisory drifted: line — drift never auto-rebases; each fork’s owner decides. Unresolved remixable slots are listed and fail the run with exit 2 regardless of --strict (silent remix skips are eliminated). Sync scans exported JSX components referenced by your <VendoRoot> components map and writes .vendo/catalog.json (see Host components). Rescans are deterministic and byte-stable, so the file is safe to commit. Both sync and init print one status line summarizing what was found:
A malformed existing .vendo/catalog.json fails sync loudly instead of being silently overwritten. Options:
  • --strict — CI gate: exit 2 on breaking tool changes, exit 3 when a breaking tool impacts saved references.
  • --json — print exactly one machine-readable object on stdout: { ok, exitCode, report, impact, notes }, where report carries tools/breaking/pins/unresolvedPins/catalog/warnings, impact is the per-tool blast radius ([] when nothing changed, null when unknown), and notes collects CLI-level events. An error field appears when extraction itself failed soft.
  • --url <url> — override VENDO_URL for the blast-radius impact query against a running dev server (POST /sync/impact).
  • --report — push the report to Vendo Cloud (requires VENDO_API_KEY or --key; --api-url overrides VENDO_CLOUD_URL).
The report names any remixable slots whose captured baseline changed and points to rebase — user forks of those pins are now drifted and keep rendering their previous content until an explicit rebase replays the recorded edit trail onto the new baseline. See Host components. Exit codes:
  • 0: success, including fail-soft warnings
  • 2: unresolved remixable slots (any mode), or breaking changes when --strict is set
  • 3: breaking changes that impact saved apps, automations, or grants when --strict is set

vendo refine [dir]

Proposes agent-layer improvements as reviewable diffs — nothing is ever applied silently, and deterministic tools.json is never touched. One model pass over the extracted tools, your app’s source, the capability-miss feed (.vendo/data/misses.jsonl), and a short interview proposes:
  • compound capabilities and briefs into .vendo/capabilities.json
  • risk corrections, enable/disable curation, and clearer descriptions into .vendo/overrides.json
  • product-brief improvements to .vendo/brief.md
With --url pointing at your running dev server, each proposed compound is probed before it is offered: the composition’s /status is checked and read-risk steps are verified against the live app. Write-risk steps are never executed by the probe. Compounds that fail their probe are dropped with the reason printed.
The model rides your own key: --model-import loads the module that exports your AI SDK model, and without it the init starter default is used (@ai-sdk/anthropic installed in your app plus ANTHROPIC_API_KEY). Options:
  • --url <url> — mounted wire base of the running dev app; enables the probe.
  • --model-import <specifier> — module exporting your AI SDK model.
  • --ask <text> — interview answer for non-interactive runs (repeatable).
  • --yes — approve every displayed diff without prompting.
Each run writes a transcript under .vendo/data/refine/. vendo init offers to run refine once at the end of a successful interactive setup.

vendo mcp

Tooling for publishing your door to the official MCP registry. Both subcommands operate on the current directory unless you pass a target dir.

vendo mcp server-json

Generate and validate the server.json artifact the registry expects. The command reads your package.json for the name, version, description, and homepage, then combines that identity with the domain namespace and public door URL you pass in.
Options:
  • --domain <domain> — registry namespace to publish under. Prompted if omitted.
  • --url <public-mcp-url> — public URL of the live door. Prompted if omitted.
  • --force — overwrite an existing server.json.
On success, doctor’s registry checks compare the file against the running door on every run.

vendo mcp verify-domain

Generate the Ed25519 keypair and challenge string you need to prove ownership of a registry namespace. The private seed is written only to the path you choose so you can keep it outside the repository.
Options:
  • --domain <domain> — required. Registry domain you are proving.
  • --key-out <path> — required. Path for the private key seed. Written with mode 0600 and refuses to overwrite an existing file.
  • --write-well-known <dir> — optional. Also writes the challenge to <dir>/.well-known/mcp-registry-auth so your host can serve the HTTP proof.
The command prints both the DNS TXT record and the HTTP challenge value (v=MCPv1; k=ed25519; p=<base64>). Publish either to satisfy registry verification, then pass the private key’s hex value to mcp-publisher when authenticating.

vendo cloud

Client for the Vendo Cloud API. vendo cloud login <email> sends a 6-10 digit email OTP, prompts for it, and stores the session at ~/.vendo/cloud-session.json; --token <jwt> stores an access token instead. Other subcommands: logout, whoami, orgs, keys (list, create, revoke), members, invite, deployments, usage, billing, validate, deploy, share, publish, and pin-ship. Read results print as JSON, with two exceptions. validate renders a human-readable report by default (org, plan, capabilities, quota bars) and takes --json for a machine-readable envelope that stays stable across live, stale-cache, and offline-degraded paths. deploy prints a concise summary table by default and switches to raw JSON with --json. vendo cloud deploy pushes local enabled automations from .vendo/data to a hosted instance. Use --app <id> (repeatable) to restrict the set, --subject <id> when the local store holds more than one subject, and --secret NAME=VALUE (repeatable) to send referenced secret values. See Vendo Cloud for the full walkthrough. Global options:
  • --api-url <url> overrides VENDO_CLOUD_URL (default https://console.vendo.run).
  • --key <vnd_...> overrides VENDO_API_KEY for the machine commands (validate, deploy, share, publish, pin-ship). Keys must match vnd_ followed by 40 hex characters or the command exits before any network call.
Org-scoped commands take --org <id>; omit it only when your account has one organization. Run vendo cloud help for the full list. See Vendo Cloud for setup, keys, and sharing.

Telemetry opt-out

Set VENDO_TELEMETRY_DISABLED=1 or set "optedOut": true in ~/.vendo/telemetry.json. DO_NOT_TRACK, CI, and production runtime also disable build and development telemetry.