molted adopt
Agent adoption flows (invite & device)
| Command | Description |
|---|---|
molted adopt create | Create an invite token for an agent |
molted adopt claim | Claim an invite token and store credentials |
molted adopt request | Start the device flow and wait (up to 15 minutes) for the owner to approve |
molted adopt list | List pending (unclaimed, unexpired) adoption tokens |
molted adopt revoke | Revoke an unclaimed adoption token (a claimed token's key stays valid) |
Agent context
Adopt handles how new agents join an existing tenant without needing the account's email and password. There are two flows: invite (token-based) and device (approval-based). Use this instead of auth signup when joining an existing tenant. Either way the agent ends up with its own API key (mm_live_...) and is registered as an agent under the invite's label.
Flow 1: Invite token (owner creates, agent claims)
# Owner side (an API key from `auth init`, `auth signup` or an earlier adoption):
molted adopt create --label "outreach-agent" \
--mailbox <mailboxId> --mailbox <mailboxId> \
--permissions "read,send" --expires 60
# → { "id": "<uuid>", "token": "ma_inv_...", "label": "outreach-agent",
# "status": "pending", "scopeAllMailboxes": false, "mailboxScopes": [...],
# "expiresAt": "...", ... }
# → the token is shown only once: give it to the agent (e.g. via env var or config)
# Agent side (no prior auth needed):
molted adopt claim <token>
# → claims the token, stores the new API key + tenant ID in the active profile
# (~/.molted/profiles/<profile>.json), then asks GET /v1/agent/setup for the next step
# → { "message": "Token claimed - credentials stored", "tenant_id": "...",
# "label": "...", "agent_id": "...", "ready_to_send": false,
# "next_step": { "step": "plan", "owner": "human", "do": "...", "request"?: {...} },
# "hint": "..." }
# → work the list with `molted doctor` until it says READY TO SENDFlow 2: Device flow (agent requests, owner approves in the portal)
# Agent side (no prior auth needed):
molted adopt request --label "sales-agent"
# → prints to stderr:
# Open this URL in your browser: https://molted.email/adopt/K7MQ3X
# Or enter code: K7MQ3X
# Waiting for approval...
# → the code is 6 characters and expires after 15 minutes
# → polls every 5 seconds until the owner approves in the portal
# → on approval: stores credentials and prints
# { "message": "Adopted - credentials stored", "tenant_id": "...", "label": "...", "agent_id": "...", "hint": "..." }
# Owner side: opens the URL signed in to the portal, grants all mailboxes (the default)
# or picks specific ones, and approves. There is no reject button: an unapproved code expires.Manage pending tokens (owner side)
molted adopt list # pending (unclaimed, unexpired) tokens
molted adopt revoke <id> # revoke a token before it's claimedA key sees every pending token in the workspace if it is an all-mailbox key; a mailbox-scoped key sees, and can revoke, only the invites it created. Revoking only stops an unclaimed token. A claimed token can't be revoked and the key it produced keeps working: revoke that key with molted auth keys revoke <keyId>.
Options on adopt create:
--mailbox <id>(repeatable) - grant access to specific mailboxes (UUIDs)--all-mailboxes- grant access to all current and future mailboxes--permissions <perms>- comma-separated, applied to every--mailbox: read, send, manage (default: "read,send")--expires <minutes>- token TTL (default: 1440 = 24h, max: 43200 = 30d)
With neither --mailbox nor --all-mailboxes the invite carries no mailbox access at all, so the claimed key can't read or send anything. Pass one of them.
An agent key may only invite within its own scope: an all-mailbox invite from a mailbox-scoped key, or a mailbox or permission the key lacks, is a human decision (403 human_decision_required, kind "adopt-invite").
When to use adopt vs auth:
auth signup- new account, new tenant (you're the owner)auth init- you already have an API keyadopt claim- joining an existing tenant with an invite tokenadopt request- joining an existing tenant without a token (owner approves)
Related: molted auth, molted agents
Commands
molted adopt create
Create an invite token for an agent
molted adopt create [options]| Option | Description | Default |
|---|---|---|
--label <label> | Key label | agent |
--mailbox <id> | Mailbox ID (repeatable) | |
--permissions <perms> | Comma-separated permissions for every --mailbox: read, send, manage | read,send |
--all-mailboxes | Grant access to all current and future mailboxes | |
--expires <minutes> | Expiry in minutes (default: 1440, max: 43200) | 1440 |
molted adopt claim
Claim an invite token and store credentials
molted adopt claim [options] <token>| Argument | Description | Required |
|---|---|---|
<token> | yes |
| Option | Description | Default |
|---|---|---|
--base-url <url> | API base URL override |
molted adopt request
Start the device flow and wait (up to 15 minutes) for the owner to approve
molted adopt request [options]| Option | Description | Default |
|---|---|---|
--label <label> | Suggested key label | agent |
--base-url <url> | API base URL override |
molted adopt list
List pending (unclaimed, unexpired) adoption tokens
molted adopt listmolted adopt revoke
Revoke an unclaimed adoption token (a claimed token's key stays valid)
molted adopt revoke <id>| Argument | Description | Required |
|---|---|---|
<id> | yes |
See CLI overview for global options, credentials and output format.