---
title: "MCP server for email, calendar and contacts · Workwae"
description: "Workwae's hosted MCP server gives Claude, ChatGPT, Cursor and other MCP clients scoped access to mail, calendars and contacts, with every send confirmed by default."
url: https://workwae.com/mcp
---

MCP server

# Give an AI agent real mailboxes, and keep the send button yours.

A hosted Model Context Protocol server for the Gmail, Microsoft 365 and IMAP accounts you connect. Agents search and read mail, draft replies, manage events and contacts. Scopes decide which tools exist, and sends are confirmed by default.

Connect a client [Read the MCP guide](https://docs.workwae.com/guides/mcp)

api.workwae.com/mcp

```text
# Sign in with OAuth: pick the workspace, scopes and accounts
claude mcp add --transport http workwae https://api.workwae.com/mcp
```

What it is

## One endpoint, the same API underneath.

Tool calls go through the same API as `/v1`: scopes, plan limits, rate limits and metering apply as they do there, and every call, reads included, lands in the audit log under the surface MCP.

| Property | Value |
| --- | --- |
| URL | `https://api.workwae.com/mcp` |
| Transport | Streamable HTTP, stateless |
| Protocol versions | `2026-07-28`, `2025-11-25`, `2025-06-18` |
| Authentication | An API key, an MCP key, or OAuth |
| Tools | 32, listed to a client only when its credential's scopes allow them |
| Prompts | 5, offered as slash commands |
| Extensions | MCP Apps views (message review, meeting time picker); MCP Events by webhook on `2026-07-28` |
| Discovery | Server card at `/mcp/server-card`, readable without a token; listed in the MCP Registry as `com.workwae/mcp` |

Connect

## Pick the credential by who is using it.

The credential decides the scopes, and the scopes decide which tools the client sees.

### API key

For your backend or a headless agent. Send it as a bearer token. Limit it to the accounts it needs; account tokens (`wat_`) are refused.

### OAuth

For a person with a console login, in Claude, ChatGPT, Claude Code, Cursor or VS Code. The client needs only the URL. The user picks the workspace, the scopes (`read`, `write`, `send`, capped by their role) and the accounts.

### MCP key

For your own users, who have no console login. Mint one per connected account; it works only at `/mcp` and answers `mcp_only_key` anywhere else.

### API key or MCP key: send it as a header

Claude Code

```text
claude mcp add --transport http workwae https://api.workwae.com/mcp \
  --header "Authorization: Bearer $WORKWAE_API_KEY"
```

Cursor

```jsonc
// ~/.cursor/mcp.json
{
  "mcpServers": {
    "workwae": {
      "url": "https://api.workwae.com/mcp",
      "headers": { "Authorization": "Bearer ${env:WORKWAE_API_KEY}" }
    }
  }
}
```

Codex CLI

```text
# ~/.codex/config.toml
[mcp_servers.workwae]
url = "https://api.workwae.com/mcp"
bearer_token_env_var = "WORKWAE_API_KEY"
```

Any other client

```text
POST https://api.workwae.com/mcp
Authorization: Bearer <API key or MCP key>
Content-Type: application/json
```

Use an MCP key in place of the API key in any of these. Claude.ai and ChatGPT custom connectors sign in only with OAuth, so they take the URL and no key.

### OAuth

Add the URL without a header. The client sends you to the Workwae console to sign in and consent; Claude, Claude Code, ChatGPT and VS Code publish a client ID metadata document, so they connect without registering. Access tokens last 15 minutes, and every request is checked against the grant and your current role, so revoking it, lowering your role or leaving the workspace takes effect at once. Revoke a grant under Connected apps in the console.

Tools

## 32 tools, by the scope each needs.

Scopes do not imply each other: a credential that sends mail needs `send`, and also `read` if it should find mail first. `admin` is never granted to an MCP client, and no tool here needs it.

| Tool | Area | What it does |
| --- | --- | --- |
| `read` Look, never change. |  |  |
| `list_accounts` | Accounts | The accounts the credential reaches: id, provider, status, time zone, capabilities and send-as addresses. |
| `get_current_time` | Accounts | The current date, weekday and time in a zone. |
| `list_changes` | Accounts | What changed across the accounts (messages, events, contacts, sends), oldest first, by cursor. |
| `list_mailboxes` | Mail | An account's folders or Gmail labels, with ids, roles and counts. |
| `search_messages` | Mail | Find or list mail by text, sender, recipient, date, flags, attachments or mailbox. With no account named, searches every account the caller reaches. |
| `get_message` | Mail | One message: body as text, recipients and attachment list. |
| `list_threads` | Mail | Conversations by latest activity, optionally in one mailbox. |
| `get_thread` | Mail | A whole conversation, oldest first, in one call. |
| `get_attachment` | Mail | Downloads an attachment, up to 10 MiB. |
| `list_calendars` | Calendar | An account's calendars: id, name, primary, editable and time zone. |
| `list_events` | Calendar | Lists or searches events overlapping a range, recurring occurrences included. |
| `get_event` | Calendar | One event in full: description, attendees and their answers, join link, recurrence rule. |
| `find_availability` | Calendar | When the given people and the account are busy, and free slots they share. |
| `pick_meeting_time` | Calendar | find_availability with a slot picker, where the client shows MCP Apps views. |
| `search_contacts` | Contacts | Finds contacts by name, email, phone or organization; returns full records. |
| `write` Change data, and save drafts. Nothing here sends mail by itself. |  |  |
| `connect_account` | Accounts | A link, valid an hour, where the user signs in to connect another Google, Microsoft 365 or IMAP mailbox. Refused for a key limited to accounts. |
| `create_draft` | Mail | Saves a draft in the account's Drafts for the user to review and send; nothing goes out. |
| `update_draft` | Mail | Replaces a draft's whole content; the draft gets a new id. |
| `delete_draft` | Mail | Deletes a draft for good; nothing is sent. |
| `mark_messages` | Mail | Marks up to 50 messages, or a thread, read or unread, flagged or not. |
| `move_messages` | Mail | Moves up to 50 messages, or a thread, to a mailbox (including trash), or changes Gmail labels. |
| `create_event` | Calendar | Creates an event or recurring series, optionally with an online meeting. Needs send as well when it invites people outside the account. |
| `update_event` | Calendar | Changes the fields given on an event or one occurrence. Needs send as well when it notifies attendees. |
| `delete_event` | Calendar | Deletes an event or a series. Needs send as well when it cancels for attendees. |
| `respond_to_event` | Calendar | Accepts, tentatively accepts or declines an invitation. Needs send as well when it tells the organizer or carries a comment. |
| `create_contact` | Contacts | Adds a contact to the account's address book. |
| `update_contact` | Contacts | Changes the fields given on a contact. |
| `send` Anything that leaves the account as email. |  |  |
| `send_message` | Mail | Sends an email now or at sendAt. Subject to the send policy and the user's confirmation. |
| `send_draft` | Mail | Sends a draft now or at sendAt. Subject to the send policy and the user's confirmation. |
| `cancel_send` | Mail | Cancels a queued send during the account's undo window or before its sendAt. |
| `preview_message` | Mail | Shows a message as it would go out, unsent; in clients with MCP Apps, as a card with Send and Edit. |
| `commit_message` | Mail | The review card's Send: sends what preview_message showed, once, within 10 minutes. |

`preview_message`, `commit_message` and `pick_meeting_time` back the MCP Apps views; on `2026-07-28` they are offered only to clients that declare the extension. Calendar writes that email anyone outside the account follow the send policy like a send. Tools that act on one account take `accountId` (its id or email), which a credential limited to one account may leave out.

### Prompts

Clients list these as slash commands. A prompt is offered only to a caller holding every scope it needs, and mentions a writing tool only when the caller has its scope.

| Prompt | Needs | What it does |
| --- | --- | --- |
| `triage_inbox` | read | Sorts recent inbox mail into replies needed, actions, FYI and noise. |
| `draft_reply` | read, write | Drafts a reply to a message for the user to review. |
| `schedule_meeting` | read | Finds times everyone is free and, once the user picks one, books it. |
| `weekly_agenda` | read | The week's events by day, with conflicts, open invitations and free blocks. |
| `summarize_thread` | read | Positions, decisions, open questions and next steps of a conversation. |

Safety model

## Agents read mail written by strangers. Sending is the risky part.

The strongest control is the credential: without `send`, an agent cannot be talked into sending mail or meeting invitations, whatever the model does.

### Scopes decide the tool list

A client sees only the tools its scopes allow. Without `send` there is no send tool, and a calendar change that emails people outside the account is refused with `missing_scope`.

### Sends are confirmed by default

The default send policy is `confirm`: every send needs the user's confirmation of subject, recipients and account, in a form or on the review card. A client that can do neither cannot send, and neither can a headless agent on a backend API key.

### Undo and duplicate guard

`cancel_send` cancels a queued send during the account's undo window or before its `sendAt`. An identical send within 10 minutes is refused with `duplicate_send`, so a retried call does not send twice.

### Third-party text is marked as data

Mail, event and contact text comes back in a separate block fenced by a random marker, labeled untrusted, with invisible characters stripped. It helps the model; it is not a guarantee, so keep confirmation on for agents that read mail from strangers.

### Only the accounts you pick

An API key or OAuth grant can be limited to specific accounts, and an MCP key is bound to one. A grant is for one workspace.

### Audited and revocable

Every tool call is recorded in the audit log, reads included. Revoke an OAuth grant, an MCP key or an API key at any time.

### The send policy

Owners and admins set it under Settings, Agents (MCP), or with `mcpSendPolicy` in `PATCH /v1/settings`. It covers sends and calendar writes that email people through MCP; sends through `/v1` are not affected.

| Field | Values | Effect |
| --- | --- | --- |
| `mode` | `confirm` (default) `allow` `drafts_only` | `confirm`: every send needs the user's confirmation. `allow`: agents send, and clients that can ask still confirm each send. `drafts_only`: agents save drafts and never send. |
| `allowedRecipientDomains` | Up to 100 domains, or `null` | Recipients must be in these domains, their subdomains or the sending account's own. For a public mailbox provider such as gmail.com, only the account's own addresses. |
| `dailySendLimit` | 1 to 10,000, or `null` | Sends per credential per UTC day. |
| `externalRecipientConfirmation` | `true` or `false` | A send to an address the account has never sent to needs the user's confirmation. |

Example: confirm, at most 50 sends a day

```text
curl -X PATCH "https://api.workwae.com/v1/settings" \
  -H "Authorization: Bearer $WORKWAE_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "mcpSendPolicy": { "mode": "confirm", "dailySendLimit": 50 } }'
```

A send the policy stops answers `send_policy_refused` with the rule (`drafts_only`, `recipient_domain`, `daily_limit`, `confirm` or `external_recipient_confirmation`) and tells the model to save a draft for the user instead. An MCP key can carry its own send policy on top of the workspace's; it can only tighten it.

### What an agent cannot do

- **Change your configuration.** No tool edits settings, API keys, webhooks or the send policy, and `admin` is never granted over OAuth or to an MCP key.
- **Send without the `send` scope.** Nor can it email attendees, or the organizer, from a calendar change.
- **Send under `confirm` when it cannot ask you.** A client with neither forms nor the review card cannot send.
- **Send outside the policy.** Recipients outside `allowedRecipientDomains` and sends past `dailySendLimit` are refused.
- **Reach other accounts or workspaces.** Accounts outside its key or grant are out of reach, and so is every other workspace.
- **Use an MCP key on the REST API.** `/v1` answers `mcp_only_key`.

Example

## Draft first, send only when you confirm.

An illustration, not a recording: tool and argument names are the server's, while ids and values are made up. It assumes a one-account credential with `read`, `write` and `send`, the default send policy, and a client that can show a form.

1. You

   Find Ada's unread email about the budget and draft a reply saying Thursday works.

2. Agent calls

   `search_messages``{ "q": "budget", "from": "ada@example.com", "unread": true }`

3. Result, summarized

   One unread message from Ada Lovelace, subject "Q4 budget", id msg_1.

4. Agent calls

   `get_message``{ "messageId": "msg_1" }`

5. Agent calls

   `create_draft``{ "reply": { "messageId": "msg_1", "mode": "reply" }, "body": "Thursday works for me." }`

6. Result

   Created draft drf_1 in account acc_1. To: ada@example.com From: me@example.com Subject: Re: Q4 budget

7. You

   Looks right. Send it.

8. Agent calls

   `send_draft``{ "messageId": "drf_1" }`

9. Your client asks you

   Send to ada@example.com from me@example.com, subject "Re: Q4 budget"? [ ] Send this message

10. You

   Tick Send this message, accept.

11. Result

   Queued send out_1 in account acc_1, status …, going out at …. It can be cancelled with cancel_send (outboxId out_1) until ….

Had the credential lacked `send`, the agent would have had no `send_draft` to call, and the draft would wait in Drafts. Under `drafts_only`, the call is refused with `send_policy_refused` and the same outcome.

Early access

## Point an agent at a mailbox, with the controls on.

Workwae is in early access; tell us what you are building, and read the MCP guide in the meantime.

[Request early access](https://workwae.com/early-access/) [Read the MCP guide](https://docs.workwae.com/guides/mcp)
