# MCP overview and tools

`@extrovert.dev/mcp` exposes Extrovert through the Model Context Protocol. Use the hosted endpoint with
OAuth when the client supports remote MCP, or run the packaged server over stdio for a local host.

```text
https://mcp.extrovert.dev/mcp
```
**Free self-signup is paused:** `sign_up` and pending `verify_signup` calls currently return `signup_disabled`. Connect with hosted
  OAuth, an existing agent key, or an enrollment key. Call `GET /v1/signup-status` before presenting
  self-signup as available.

## Connect and identify the key

| Tool | Purpose |
|---|---|
| `sign_up` | Start self-signup when the platform gate is enabled |
| `verify_signup` | Exchange the temporary verification-only key for the durable key |
| `redeem_enrollment` | Create or find an agent by stable handle and return its limited key |
| `whoami` | Read the fixed organization, project, agent, key, and permissions |

Hosted OAuth avoids pasting a key into client configuration. Local stdio stores the durable key in a
permission-restricted credential file after successful enrollment or signup verification.

Hosted MCP permissions follow the signed-in organization role. Owners, admins, and members receive
inbox create, read, send, webhook, and commerce request permissions. Viewers and billing members
receive read and commerce request permissions. Hosted MCP also accepts a limited `pk_agent_...`
bearer credential and rejects enrollment keys.

Enrollment and API keys serve different jobs. An enrollment key creates an agent during setup. An API
key connects an existing agent.

## Inbox tools

| Tool | Purpose |
|---|---|
| `create_inbox` | Create an inbox with optional username, domain, webhook, metadata, and idempotency id |
| `list_inboxes` | List inboxes in the key's allowed breadth |
| `get_inbox` | Read one inbox and its effective review policy |
| `update_inbox` | Change display name, webhook, metadata, or permitted fields |
| `export_email_config` | Export portable IMAP and SMTP configuration when the key and plan allow it |
| `delete_inbox` | Permanently remove an inbox and its messages |

`create_inbox` returns an opaque inbox id and an address. Use the id for durable references.
**Credentials do not enable direct SMTP:** Exported credentials permit IMAP access, but raw SMTP remains disabled unless a human administrator
  enables it for that inbox and the account retains paid entitlement. Direct SMTP bypasses review and
  other platform controls. MCP outbound tools continue through the Review Loop regardless of the
  setting.

## Mail and conversation tools

| Tool | Purpose |
|---|---|
| `send_email` | Submit a new message under the inbox's review policy |
| `reply_email` | Reply by message or thread, with optional reply-all |
| `forward_email` | Forward a message to new recipients under the same review policy |
| `read_messages` | List a bounded page of message headers and bodies |
| `get_message` | Fetch one message and choose source or extracted presentation |
| `search` | Search one inbox or all inboxes the agent owns |
| `list_threads`, `get_thread` | Read conversation summaries and full history |
| `mark_read` | Set one message's read state |
| `batch_update_messages` | Change read state or folder for up to 200 messages |
| `delete_message`, `delete_thread` | Move content to Trash or permanently expunge it |
| `list_attachments`, `get_attachment` | Inspect attachment metadata, then download one part |
| `wait_for_email` | Block for a matching message and return OTP or verification-link extraction |

`get_message` accepts `format: auto | text | html | both` and
`variant: source | extracted`. Source `text` and `html` are independent MIME alternatives. Their
`extracted_text` and `extracted_html` derivatives are nullable and best effort.

## Review Loop tools

Every agent-plane send, reply, and forward follows `effective_review_policy`. New accounts use
`require_review`. Under that policy, outbound calls need `intent.summary` and normally return
`queued_for_review` with an `rr_…` id. A missing intent returns `422 intent_required`; nothing is sent
or queued.

| Tool group | Tools |
|---|---|
| Review records | `list_reviews`, `get_review`, `get_review_turns`, `get_review_feedback` |
| Agent revisions | `post_review_chat`, `submit_revision`, `cancel_review`, `restamp_review` |
| Durable events | `list_review_events`, `wait_for_review_event`, `ack_review_event` |
| Reviewer agent | `get_review_decision_context`, `reviewer_decide` |
| Categories | `list_categories`, `get_category`, `propose_category`, `update_category` |
| Graduation and pacing | `get_risk_dial`, `get_graduation_status`, `get_backlog_status`, `get_pacing_state`, `propose_graduation` |
| Writing rules | `get_rules`, `save_rule`, `promote_rule`, `retire_rule`, `get_rule_audit`, `undo_rule_change` |

Human authority remains separate. Agents may propose categories and graduation, but humans control the
effective review policy, risk settings, graduation decisions, and final approval where configured.
A reviewer agent also needs `review:act` and an active link for the specific inbox or category. It does
not receive the composing agent's send permission.

Use a stable `client_id` on MCP outbound and review mutations. After a transport timeout, reuse the
same value for the same exact intent. Do not reuse it for different content.

## Webhooks, contacts, suppression, and deliverability

| Area | Tools |
|---|---|
| Webhooks | `register_webhook`, `list_webhooks`, `get_webhook`, `update_webhook`, `delete_webhook` |
| Contact lists | `add_contact_list_entry`, `list_contact_lists`, `delete_contact_list_entry` |
| Suppression | `check_suppression`, `list_suppressions`, `revoke_suppression` |
| Deliverability | `get_deliverability_status`, `list_deliverability_findings` |

Webhook secrets are returned once. Verify the signature over the raw request body before parsing or
trusting the event. Contact-list and suppression checks apply again at delivery after review.

## Domains, jobs, and commerce requests

| Area | Tools |
|---|---|
| Customer-controlled domains | `list_domains`, `get_domain`, `onboard_domain`, `verify_domain`, `offboard_domain` |
| Async work | `get_job` |
| Quotes and requests | `quote_domain`, `request_domain_purchase`, `request_plan_change` |
| Request recovery | `get_commerce_request`, `list_commerce_requests`, `cancel_commerce_request` |

`commerce:request` lets an agent quote, request, inspect, and cancel its own eligible pending request.
It never approves payment or grants spending authority. Surface the exact blocker, next action,
approval URL, and recommended poll interval to the human.

`stream_info` reports the current event-stream connection details. Streams and webhooks reduce polling
latency, but durable review events still require list or wait plus acknowledgement.

## Tool annotations and key boundaries

Tools declare read-only, destructive, idempotent, and open-world hints so the host can present them
appropriately. These hints do not replace server authorization.

The key's fixed organization, project, permissions, ownership, and resource breadth are checked on
every request. A project id in tool input is an assertion and cannot switch projects.

## Transports

| Transport | Use it for | Connection |
|---|---|---|
| Hosted Streamable HTTP | Remote OAuth-capable clients | `https://mcp.extrovert.dev/mcp` |
| Local stdio | Hosts that start a child process | `npx -y @extrovert.dev/mcp@next` |
| Self-operated Streamable HTTP | A packaged MCP deployment you operate | `npx -y @extrovert.dev/mcp@next --http --port 8787` |

Set `EXTROVERT_MOCK=1` for deterministic offline fixtures. Mock mode is for integration development and
does not prove live delivery.

## Next

- [MCP client configuration](https://docs.extrovert.dev/mcp/client-configuration/)
- [Wire an agent host](https://docs.extrovert.dev/mcp/agent-host/)
- [MCP `wait_for_email`](https://docs.extrovert.dev/mcp/wait-for-email/)
- [Review Loop agent contract](https://docs.extrovert.dev/review-loop/agent-contract/)
- [Purchase approvals for agents](https://docs.extrovert.dev/concepts/purchase-approvals-for-agents/)