entityId is the Vendo
principal subject, so isolation is structural: every list, initiate, and
disconnect operation is scoped to exactly one subject. No token ever enters
Vendo — the broker holds the credentials, and initiate hands back only the
hosted redirect URL.
Setup
You have two options: bring your own Composio key, or ride the Vendo Cloud broker. Bring your own key. PasscomposioConnector to createVendo:
VENDO_API_KEY and ship no Composio key of your
own. Connection endpoints then ride the Vendo Cloud broker using Vendo’s
Composio credentials, so cloud users bring zero keys. A BYO
composioConnector always wins when both are configured, because connections
must live where the connector’s tools execute.
GET /api/vendo/status reports the active posture under blocks.connections:
"byo", "cloud", or false when neither path is wired.
The in-flow connect card
When a tool call needs a connection the user does not have yet, the connector returns a typedconnect-required outcome instead of an opaque error. The
shipped VendoThread renders an inline connect card next to the tool call,
following the same pattern as approvals:
- The user selects Connect. The card opens the broker’s hosted OAuth page in a popup.
- The card polls the connection until it becomes active.
- The thread retries the original tool call through the fresh connection — no re-prompting required.
connect-required as an actionable in-band error that names the connector and
toolkit the user needs to connect.
The settings panel
ConnectedAccountsPanel (exported from @vendoai/ui/chrome) lists a user’s
connected accounts and disconnects them. Disconnect severs the account on the
broker.
VendoPage chrome mounts the panel automatically under a new Accounts
tab. If you render your own chrome, drop the panel in wherever you already
handle user settings, or read the same state through the useConnections
hook from @vendoai/ui.
Connection endpoints
Every connection route is per-principal. The wire uses exactly the resolved principal’s subject — there is no caller-supplied subject and no cross-user read.
Anonymous (ephemeral) visitors cannot initiate a connection — an external
account would outlive the session it was minted for. Synthetic subjects
(webhook principals, reserved
webhook: and vendo: prefixes) are refused
for the same reason.
Risk labels for Composio tools
Composio tools now carry a curated risk instead of the previous blanketwrite default. The connector resolves risk in three steps:
- Metadata hints. Composio
destructiveHintandreadOnlyHinttags take precedence when present. - Slug patterns. Destructive verbs anywhere in the slug (
DELETE,REMOVE,DESTROY, and similar) mark the tool destructive. Leading read verbs (GET,LIST,FETCH, and similar) mark it read. - Conservative default. Anything else falls back to
write.
.vendo/overrides.json still wins over the curated map, so you can pin risk
per tool.
MCP connector credentials
mcpConnector({ headers }) accepts either shared static headers (the simple
default) or an async per-principal resolver. Use the resolver when the MCP
server binds authentication to the session and you need each user to get
their own MCP session:
entityId, and whether the credential was shared or per-principal —
in the tool-call event’s detail. The identity is stripped from the outcome
the model and UI see, so no broker identifier leaks into a message.