# Wire it into an agent host

The Extrovert MCP server works with hosts that support the
[Model Context Protocol](https://modelcontextprotocol.io). This page covers the connection and tool
flow; for host-specific config files see
[Client configuration](https://docs.extrovert.dev/mcp/client-configuration/).

## Two transports, one binary

| Transport | Use it for | Command |
|---|---|---|
| **stdio** | Local hosts that spawn the packaged process. | `npx -y @extrovert.dev/mcp@next` |
| **Hosted OAuth** | Existing human console accounts in OAuth-capable hosts. | `https://mcp.extrovert.dev/mcp` |
| **HTTP (Streamable)** | A deployment you operate: `POST /mcp`, default `:8787`. | `npx -y @extrovert.dev/mcp@next --http --port 8787` |

```bash frame="terminal"
npx -y @extrovert.dev/mcp@next --help
```

## Minimal host config

Almost every MCP host uses the same `mcpServers` shape. For a local (stdio) host:

```json title="mcp config (stdio)"
{
  "mcpServers": {
    "extrovert": {
      "command": "npx",
      "args": ["-y", "@extrovert.dev/mcp@next"]
    }
  }
}
```

For Extrovert's hosted OAuth endpoint:

```json title="mcp config (hosted OAuth)"
{
  "mcpServers": {
    "extrovert": {
      "url": "https://mcp.extrovert.dev/mcp"
    }
  }
}
```

For a self-hosted runtime over HTTP, point at your deployment and pass the key as a bearer header:

```json title="mcp config (hosted HTTP)"
{
  "mcpServers": {
    "extrovert": {
      "url": "https://your-mcp-host.example/mcp",
      "headers": { "Authorization": "Bearer pk_agent_…" }
    }
  }
}
```

Copy-paste configs for Claude Desktop, Claude Code, and Cursor are in
[Client configuration](https://docs.extrovert.dev/mcp/client-configuration/).
**One-command Codex setup:** Install the complete plugin with `codex plugin marketplace add extrovert-dot-dev/extrovert-skills`
  followed by `codex plugin add extrovert@extrovert`, or configure only stdio with
  `npx -y @extrovert.dev/mcp@next setup --host codex`. Start a new session afterward.

## The key the host holds

1. Use hosted OAuth, supply a limited `pk_agent_…` key, or give the packaged stdio server a short-lived
   `pk_enroll_…` key to redeem. Do not provide an organization-wide administrative key.
   limited credentials only

2. Local stdio reads its permission-restricted credential file. `EXTROVERT_API_KEY` is an explicit
   override; a self-hosted HTTP client uses an `Authorization` header.

3. With an enrollment key, the host's first tool call is `redeem_enrollment`, which creates or finds
   the agent and returns its project-bound key. The packaged stdio server stores that key
   automatically.
**Host config leaks easily:** Synced dotfiles, screen shares, and support bundles can expose host config. Prefer hosted OAuth or
  the packaged credential store; do not paste a durable key into JSON. If an explicit enrollment key
  leaks, revoke it instantly and in isolation without touching any other agent.

## The tool-call loop

Once connected, the agent uses ordinary tool calls. A typical enrollment, inbox, and review flow is:

```text
redeem_enrollment { enrollment_token,
                    agent_handle }           → project-bound agent key
create_inbox { display_name }                → agent7@extrovertmail.com
get_inbox { inbox }                          → … effective_review_policy: "require_review"
send_email { inbox, to, subject, text,
             intent }                        → queued_for_review { review: { id: "rr_…" } }
wait_for_review_event { review_id }          → reason: "sent" → the human released it
wait_for_email { inbox, from }               → { message, otp_code, verification_link }
reply_email { inbox, message_id, text,
              intent }                       → queued_for_review (same policy applies)
```

Outbound mail is **queued for a human by default**, so it carries an `intent` (one sentence of reviewer
context; without it the call is rejected `422 intent_required`)
and it finishes on a terminal `sent` / `send_failed` review event rather than at the moment the tool
returns. Read `effective_review_policy` once and branch on it; an
[`allow_direct`](https://docs.extrovert.dev/concepts/inboxes/#review-policy-applies-to-every-outbound-request) inbox sends straight away.

Tools are annotated (`readOnlyHint`, `destructiveHint`, and related hints) so a host can present read tools freely and
gate `delete_inbox` / `delete_webhook` behind confirmation. The standout is
[`wait_for_email`](https://docs.extrovert.dev/mcp/wait-for-email/): it blocks server-side and returns the OTP and verification link
already extracted, so the agent can continue without its own polling loop.

## Environment

| Variable | Default | Purpose |
|---|---|---|
| `EXTROVERT_API_BASE_URL` | `https://api.extrovert.dev` | Base URL of the Extrovert REST API. |
| `EXTROVERT_API_KEY` | *(empty)* | Limited agent key (`pk_agent_…`) or an enrollment key for local redemption (`pk_enroll_…`). |
| `EXTROVERT_CONFIG_DIR` | platform config directory | Override the local credential directory. |
| `EXTROVERT_MOCK` | *(off)* | Set `1` to force offline fixtures: every tool works with no key, no network. |
| `EXTROVERT_REQUEST_TIMEOUT_MS` | `30000` | Per-request timeout for non-blocking calls. |
| `EXTROVERT_MAX_WAIT_MS` | `300000` | Upper bound the server allows `wait_for_email` to block. |
| `PORT` / `HOST` | `8787` / `0.0.0.0` | `--http` bind. |
**Validate offline first:** Drop `EXTROVERT_API_KEY` and set `"EXTROVERT_MOCK": "1"` in any config above. The server boots against
  deterministic fixtures so you can exercise every tool, including `wait_for_email`, before you have a
  live key.

## Next

- [Client configuration](https://docs.extrovert.dev/mcp/client-configuration/): per-host config files.
- [MCP overview & tools](https://docs.extrovert.dev/mcp/overview/): the full tool list and security model.
- [wait_for_email](https://docs.extrovert.dev/mcp/wait-for-email/): the blocking primitive, in depth.