# Connections and access

Connect an agent to your existing Extrovert account with only the inboxes and actions
it needs. Start at [Set up your agent](https://docs.extrovert.dev/quickstart/install/) or **Agents -> Connect an agent**
in the console. Ordinary mailbox setup does not require Full account control. You choose the access at consent and can inspect it in
[Connections](https://app.extrovert.dev/account/connections).

## Choose a connection for the job

| Your task | Start with | Why |
|---|---|---|
| Read or reply from existing inboxes | Hosted OAuth with Selected inboxes | Choose the exact inboxes and read/send actions; this is the consent default |
| Create and operate inboxes in one project | Project reach with the required actions | Includes current and future resources in that project |
| Manage a team of agents in one project | Project reach -> Project manager | Create personas, inboxes, and independent workers within the same project and permission ceiling |
| Work across projects in one organization | Organization reach with the required actions | Includes current and future resources in that organization |
| Explore and configure the account with your assistant | Explicit Full account control, 24 hours | Customer administration, including projects, billing, policies, approvals, and credentials |
| Run a deployed worker | A separately configured scoped connection or agent key | The worker keeps its own access when the setup connection ends |

Use [hosted MCP OAuth](https://docs.extrovert.dev/mcp/client-configuration/) for an interactive assistant. For a local
worker, [sign in with CLI OAuth, enroll a new agent, or install an existing credential](https://docs.extrovert.dev/quickstart/authentication/).
Installing a skill or MCP configuration does not sign in. After connecting, call `whoami`
in the actual host session and confirm its account, identity, reach, actions, and expiry.

## Identity, resources, and actions are separate choices

**Dedicated agent** is the recommended initial choice for an email agent. **Personal
assistant** acts on your behalf but is still limited by the chosen resources and actions;
it does not automatically receive human administrator access. **Dedicated agent** acts as the named agent you
explicitly select or create. A connection is one grant of access for an application;
an agent can have several connections and own several inboxes. Connecting to an inbox
does not change its owner.

**Selected inboxes** grants the selected stable inbox IDs in one project. It excludes future
inboxes, including a replacement created later at the same address. **Project** and
**Organization** include future resources inside their named boundary. Project membership,
an agent's name, or knowing an address does not itself grant access.

Choose actions separately: read, send, create, delete, or export credentials as needed.
Send permission alone does not imply read/list permission. When read access and the resource
boundary are the same, list and direct lookup should agree. See
[diagnosing mailbox visibility](#diagnose-mailbox-visibility).

## Give a manager one project

To hand your manager a key without an OAuth login, select the organization and
project in the console, then open **Credentials -> API keys -> Create project manager
key**. Name it, choose **In 24 hours** or **Until revoked**, and review the permissions.
Enable **Allow sending mail** if the manager or its workers need to send. Copy the
secret into the manager's `EXTROVERT_API_KEY` setting before closing; it is shown once.
Only an organization owner or admin can create this key.

The key covers current and future resources in that project and can create worker
credentials or submanagers with a subset of its permissions. Use it with the API,
SDK, CLI, or local MCP. Hosted MCP requires OAuth. Manage expiry status, activity,
and revocation in **Connections**; choose **Also revoke all workers** to stop the team.
This is an independent connection credential, not a persona API key or enrollment key.
The human-only API endpoint is `POST /v1/admin/orgs/{org_id}/projects/{project_id}/manager-keys`.
An existing authorized connection uses `createConnectionCredential` for delegation.

For a manager that creates its own team, start OAuth from that manager's MCP host or
CLI. Open the returned authorization link, sign in, select **Project**, choose the
project, and select **Project manager**. Review the identity and expiry, then authorize.
Check `whoami` in the manager's actual runtime: its reach must be `project`, its
`project_id` must match your selection, and its scopes must include `agent:manage`
and `credential:delegate`.

The preset allows persona management, inbox creation/read/deletion, and domain
listing. It does not include sending mail. If workers need to send, choose **Custom**
and add **Send mail** alongside the manager permissions. A manager can delegate only
permissions it already holds. It cannot grant another project, organization reach,
Full account control, billing changes, policy changes, or review approvals.

Use `createAgent` to create each persona, then `adminCreateInbox` with its `agent_id`.
Use `issueAgentKey` for a persona-owned worker key, or `createConnectionCredential`
for a connection limited to selected inbox IDs. Discover the exact inputs through
`describe_administrative_action`; pass the organization and project from `whoami`
under `path`. `adminMe` requires Full account control and is unnecessary for a
project manager.

A project manager seeing every project inbox is expected. Its connection name does
not make it the dedicated persona with a similar name. A separate worker key is
useful when that persona runs independently with narrower access; it is not needed
to repair the manager's project visibility.

Before issuing a worker key, run `extrovert whoami --json`, then
`extrovert admin describe listAgentKeys`. Use `extrovert admin read listAgentKeys
--input '<json>'` with organization/project IDs under `path` and the existing
persona's `agent_id` under `query`. Check expiry and revocation, and verify any
credential already installed in the worker's actual runtime. A listed key is not
proof that the worker has its secret. Secrets are shown only at creation and cannot
be recovered from the key list. If a replacement is needed, describe `issueAgentKey`
and issue it for the existing persona with only the required scopes through
`admin change ... --input-stdin`. Keep the returned secret private and verify the
worker before revoking old access.

If an older packaged CLI prints **Unknown command or option: admin** despite
advertising it in help, this is a local dispatch bug fixed in **0.1.0-pre.35**.
Check `extrovert --version` and update through your installation manager, preserving
explicit pins and profile settings. With an unpinned npm installation, use
`npx --yes --prefer-online @extrovert.dev/mcp admin describe listAgentKeys`.
This error occurs before authentication; another login or broader consent will not
fix it.

For a submanager, explicitly include `agent:manage` and `credential:delegate` in a
new **project** connection, together with the actions that submanager may delegate.
Leave those permissions out of ordinary worker credentials. An API key's scopes do
not turn it into an OAuth project manager.

Workers have their own expiry and revocation. Expiring or revoking the manager
alone leaves its workers running. To stop the whole team, open **Connections**, revoke
the manager, and select **Also revoke all workers**. The API equivalent is
`revokeConnection` with `body: { "include_workers": true }`. It recursively revokes
child connections, keys, and enrollment tokens, including redeemed descendants;
the operation fails atomically if its 10,000-record safety limit is exceeded.

## Keep domains and inboxes in the right project

Ordinary domains belong to exactly one project. Account-level domain creation with
no project specified uses **Default**. A project connection sees only its project's
domains plus platform-designated shared domains, such as `extrovertmail.com` and
`free.extrovertmail.com`. Shared domains provide addresses; their inboxes still belong
to individual projects and remain isolated.

**Mail -> Conversations** shows conversations across inboxes in the selected project.
**Mail -> Inboxes** lists that project's inboxes. Choose **Open inbox** to read one
inbox's mail, or **Manage inbox** to change its sender name, daily limit, or delete it.
Deletion requires typing the exact address.

To move a domain, use **Domains -> Move to project**. For a shared-domain inbox, use
**Manage inbox -> Move to project**. Personas also have **Move to project** on the
Agents page. Choose a destination in the same organization and select **Preview move**.
The preview lists the domains, inboxes, personas, worker keys, connections, and
webhooks involved. A custom-domain inbox always moves with its domain and every
inbox on that domain. A sole inbox moves with its domain and persona. When a domain
has multiple inboxes, review the domain group and explicitly confirm that all listed
inboxes and their owners move together. Only inboxes on platform-designated shared
domains can move without the domain.

**Include related resources** is separate: it optionally includes other inboxes and
domains owned by the same personas or linked by selected-inbox grants and webhooks.
It does not replace domain-group confirmation or consent to move a whole-project
connection. Resolve ownership and mixed-grant blockers before continuing. Legacy
inboxes split across projects or missing their domain ownership must be repaired
before the transfer; the service will not silently detach them.

Mailbox addresses, passwords, messages, sending limits, and review policy are
preserved. Worker credentials keep their existing actions and expiry; domain access
is limited to the transferred persona's inbox domains. Enrollment tokens remain in
the source project. Whole-project managers remain there too unless their original
authorizer separately selects the checkbox granting the entire destination project.
Pending drafts require fresh review, and active reviews or sends block the move.
Historical billing stays attributed to the project that owned the resource then.

The API, SDK, CLI, and MCP expose `previewProjectTransfer` and
`executeProjectTransfer`. Send the preview token with execution and a stable
`client_id` (or `Idempotency-Key` header). Review the `domain_groups` member arrays.
When `requires_domain_confirmation` is true, include `confirm_domain_transfer: true`
with that exact preview token. Changed group membership, project state or expansion
choices invalidate the preview;
refresh it before retrying. Transfers require human administration or explicit Full
account control. The initial safety limits are 100 inboxes per organization,
100 domains/personas per source project, and 1,000 credentials or webhooks per
transfer inspection. Exceeding a limit returns an error without making changes.

## Explore with full control

Select **Full account control** explicitly when you want your assistant to set up and
administer your account. It can manage customer organizations you administer, including
future ones; use other agents' inboxes; change settings and access; make purchases; and
approve review or purchase requests, including its own. Your current roles remain its
upper bound. Private platform administration is excluded.

The default is **24 hours from authorization**. Refreshing a token keeps the connection
working within that period and never restarts the clock. **Until revoked** is an explicit
alternative when you want continuing full control.

The deadline applies to that connection. Credentials it creates, **including administrative
credentials**, have their own lifetime and revocation. Settings, policies, webhooks, and
exported mail credentials can also continue after setup ends. Expiry is not a rollback
of the assistant's work or a guarantee that all broad access is gone.

Full control enables administrative decisions without another required human click for
each one. Such decisions are attributed to the connection; they are not reported as a
human approval. Ordinary mail actions still follow the effective review policy until an
authorized administrator changes it.

## Hand off to deployed agents

1. Use the setup connection to configure the requested projects, inboxes, and policies.
2. Give each worker its own named identity and credential or separately approved connection.
   Select the inboxes and actions its job needs. Use enrollment when setup must create the
   agent, or issue an API key for an existing agent. Store secrets in the worker's secret
   manager or private credential store; they are shown once.
3. In **each worker's actual runtime**, call `whoami`, list the intended inboxes, and verify
   its required actions. The setup assistant's successful call does not verify the worker.
4. Open **Connections**, inspect the setup connection's activity and created credentials,
   and revoke access you no longer want. Check each independently created credential.
5. Revoke the setup connection when finished, or let its 24-hour deadline expire. The
   workers continue using their own valid credentials.

An independent administrative credential is an explicit choice for an administrative job.
It is not required for an ordinary mail worker or to troubleshoot a missing inbox.
Revoking an enrollment key stops future redemption; revoke already issued agent keys
separately if their access must stop too.

## Find administrative actions

For a project manager, start with `whoami` and use its exact organization and project.
For Full account control, start with this MCP read:

```json title="read_administrative_action"
{ "action_id": "adminMe" }
```

It returns the organizations and projects you currently administer. Search
`list_administrative_actions` for your task, then call `describe_administrative_action`
with a returned `action_id`. Use its exact schemas: parameters go under `path` and
`query`, and JSON payloads under `body`. Execute reads with `read_administrative_action`
and authorized changes with `change_administrative_action`. Catalog discovery alone
does not grant administrative access.

The packaged CLI offers `admin actions`, `admin describe`, `admin read`, and
`admin change --input-stdin`. The [TypeScript SDK](https://docs.extrovert.dev/sdk/typescript/#administrative-workflows)
offers the same catalog and typed calls. After an ambiguous mutation result, read the
current state before repeating the change. Keep returned credentials private.

## Diagnose mailbox visibility

Use `whoami`, `list_inboxes`, and `get_inbox` on the **same connection**. For a domain,
pass its exact name to `list_inboxes` and follow every `next_cursor` with the same filters.
An empty page says only that no inboxes matched that connection and those filters.
Domain counts describe visible inboxes, not every inbox in the account.

Hosted OAuth and the local CLI can use different credentials even on the same machine.
Compare their connection/agent IDs, authentication method, account/project, reach, and
permissions separately. A display name is not proof of ownership or identical access.

| Result | Next step |
|---|---|
| Send succeeds; read/list is denied | Inspect read permission separately from send permission |
| A known inbox is readable but absent from a complete list with the same filters and reach | Report a list/read inconsistency with non-secret request IDs and client versions; do not guess that ownership explains it |
| Empty inventory | Check identity, reach, filters, and pagination before creating anything |
| Malformed response or service error | Report unavailable inventory; do not turn it into an empty list |
| `401` | Check whether this exact connection expired or was revoked; reconnect through the host when needed |
| `403` | Inspect the missing action or required reach; request the access needed for the task |
| `404` | Check the opaque ID and granted boundary; the resource may not exist or may be outside your access |

Inbox lifecycle, sender setup, and review policy are separate facts. Missing sender
readiness is **unknown**, not "pending." Use explicit send errors and review outcomes;
`queued_for_review` is not sent, and `sent` does not prove receipt or reading.

## Reconnect or stop access

After expiry or revocation, reconnect through your host to approve a new grant if the
task still needs access. An installed package, saved credential, or token refresh does
not override expiry. Do not silently switch to another credential or broaden access.

Older hosted OAuth connections must reconnect through explicit consent. If approval
succeeds but `whoami` still fails, retain the error and non-secret request ID, verify
the host session, and contact support instead of repeating approvals indefinitely.

In **Connections**, inspect identity, reach, expiry, activity, and created credentials.
Revoke the connection and each unwanted independent credential separately. To stop a
webhook or undo a policy change, remove or change that resource as well.

A completed [ownership transfer](https://docs.extrovert.dev/concepts/ownership-transfers/) is different from
ordinary connection revocation: the former owner's organization access and
independent credentials end together. Only verified humans can offer and accept
this handoff. Stop using old credentials; the new owner must explicitly reconnect
any agents or integrations they want to retain.

## Feedback and case permissions

New connection and key presets include `support:submit` for filing feedback and
support cases and following the identity's own or explicitly shared records.
Uncheck reporting to opt out. Read or update other reports only when the user
selects `support:read` or `support:write` within the connection's resource reach.
The Project manager preset includes all three for its selected project.
[Reporting access and examples](https://docs.extrovert.dev/operating/support/#choose-reporting-access)
explain the console, API and SDK choices.