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:
--agentemits 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), andriskRecommendations(per-tool advice: destructive tools should be marked critical, disabled tools reviewed before enabling).--yesskips the interview, shows the proposed diffs, and approves every code change. Combine it with--model-importand--brieffor unattended setup.--forceregenerates 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 SDKmodel(default@/lib/aifor Next.js and./aifor Express).--brief <text>supplies the product brief written to.vendo/brief.md.
--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:
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/presentand the composition executes a synthetic same-origin tool. The echo route reports booleans indicating whether the doctor’sauthorizationandcookieheaders reached the host API. The probe fails with actionable text whenVENDO_BASE_URLis 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-asso the host-configuredcreateVendo({ actAs })mints auth material and the host’s own principal resolver accepts it. This works with anyactAsimplementation, including the actAs presets. WhenactAsis unconfigured, doctor warns but does not fail; mint or verify errors produce actionable failure text.
/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.jsonparses - a
server.jsonin 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-authchallenge file starts withv=MCPv1, and the same challenge served over HTTP parses when present
0: green1: 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:
.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 }, wherereportcarriestools/breaking/pins/unresolvedPins/catalog/warnings,impactis the per-tool blast radius ([]when nothing changed,nullwhen unknown), andnotescollects CLI-level events. Anerrorfield appears when extraction itself failed soft.--url <url>— overrideVENDO_URLfor the blast-radius impact query against a running dev server (POST /sync/impact).--report— push the report to Vendo Cloud (requiresVENDO_API_KEYor--key;--api-urloverridesVENDO_CLOUD_URL).
0: success, including fail-soft warnings2: unresolved remixable slots (any mode), or breaking changes when--strictis set3: breaking changes that impact saved apps, automations, or grants when--strictis 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
--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.
--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 SDKmodel.--ask <text>— interview answer for non-interactive runs (repeatable).--yes— approve every displayed diff without prompting.
.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.
--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 existingserver.json.
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.
--domain <domain>— required. Registry domain you are proving.--key-out <path>— required. Path for the private key seed. Written with mode0600and refuses to overwrite an existing file.--write-well-known <dir>— optional. Also writes the challenge to<dir>/.well-known/mcp-registry-authso your host can serve the HTTP proof.
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>overridesVENDO_CLOUD_URL(defaulthttps://console.vendo.run).--key <vnd_...>overridesVENDO_API_KEYfor the machine commands (validate,deploy,share,publish,pin-ship). Keys must matchvnd_followed by 40 hex characters or the command exits before any network call.
--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
SetVENDO_TELEMETRY_DISABLED=1 or set "optedOut": true in
~/.vendo/telemetry.json. DO_NOT_TRACK, CI, and production runtime also
disable build and development telemetry.