Who is calling
An agent that turns up with nothing gets a401, and the challenge on it points
at your broker. Vendo Cloud runs that broker for you: the person signs in there
with your app’s own login, and the agent leaves with a short-lived bearer. The
door itself serves no /authorize or /token on that posture, which is why the
exchange in Service keys & broker
posts to the broker instead. A door init wired for local dev is its own
authorization server and does advertise both, at /api/vendo/mcp/authorize and
/api/vendo/mcp/token.
The bearer names one of your own user ids, in your own spelling. The door
verifies its signature, then asks your auth code to turn that id into a live
user — on every request, not once per session. Return null there and the token
is dead on the next call, sessions included. That is the kill switch, and
Wire auth is where it lives.
What the agent sees
tools/list answers with your enabled tools whose audience is end-user or
unset. Operator and internal tools stay off it. Names, descriptions, and input
schemas are served verbatim from your registry, and a tool’s title is what a
client shows a person instead of the wire name.
Vendo’s own vendo_* tools ride along: vendo_make for a generated screen, the
saved-apps viewer, and the caller’s own files. The file tools are scoped to the
bearer’s subject and take no subject argument, so a token for user_1904 reaches
that person’s files and no one else’s. See User data for
what saves and what reads back.
Each listing carries MCP annotations derived from the tool’s risk label, so a
client can warn before a write without re-reading prose.
An
ungraded tool asserts neither hint, which leaves the client on MCP’s own
cautious reading of a tool it knows nothing about.
Curate the menu
For a shorter, deliberate menu, name the tools you want in.vendo/overrides.json:
.vendo/overrides.json
vendo_* tools bypass the filter.
How a call reaches your host tools
The agent has no session in your product, so the inbound bearer is never forwarded to your host routes. Door calls reach your API through theactAs
seam: Vendo hands actAs the caller and the consent recorded for that client,
and uses the auth material you return. Without actAs configured, the tool
returns a not-implemented error.
The signed-in user is the authority. Scopes on the token buy no exemption, and
the door adds none.
What comes back
Five outcomes, all of them in-band so a retry never re-executes a committed write.vendo_make answers with an id, a title, a status, and one line to say out loud.
The screen itself lands in your product, never in the agent’s transcript. That
line is say, written for the person rather than the model, so an agent relays
it close to verbatim and reports nothing else.
If the chat calling
vendo_make is your own frontend, <VendoAppEmbed> puts the
app inline in it, off the receipt’s own id — see
Embeds in your chat.
Where a screen lands
A new screen goes to the person’s own list of views. Passslot on vendo_make
and it takes a named place on your page instead — slot ids belong to your
product, so an agent passes one it was told rather than one it invented.
Generate screens is where slots come from.
slot is for something new. vendo_apps_pin and vendo_apps_unpin move an app
the person already has, and since a slot holds one app, a pin replaces and names
what it evicted.
Approvals wait for the person
On thecautious preset, reads answer straight away and writes park. The agent
gets an error naming the approval and where it is waiting.
Approving does not resume the call. The agent has to call again, and it has to be
on the same MCP session — a client that reconnects between attempts parks a
second time instead of running. Approve actions is where the
grading lives.