MCP Apps and Events
The message review and meeting picker views for MCP Apps hosts, and MCP Events subscriptions that push new mail and calendar changes.
Two protocol extensions for richer clients: MCP Apps show interactive views beside a tool's result, and MCP Events let a client subscribe a webhook to new mail and calendar changes. Clients without them get the same information as text.
MCP Apps
Hosts that support MCP Apps (io.modelcontextprotocol/ui) show two views beside a tool's result; the result's text says the same for hosts that don't. The views load nothing from outside and follow the host's styles.
| View | Tool | Shows |
|---|---|---|
| Message review | preview_message | The sender, recipients, subject, body and files, with Send and Edit in chat. |
| Meeting time picker | pick_meeting_time | find_availability's free slots in the user's time zone. A pick comes back to the chat with its exact times, for create_event. |
On 2026-07-28 the three tools behind the views (preview_message, commit_message, pick_meeting_time) and both views are offered only to clients that declare the extension; earlier protocol versions always get them.
Message review
- An HTML body shows as recipients' mail clients render it, without remote content, followed by every link target and remote image host, and a note when it carries its own styles.
- Send calls
commit_message, which takes only the preview'sproposalId. The id is given to the card, not the model. - A proposal is single use, valid 10 minutes and bound to the credential and the exact message, so only what the user saw goes out. Otherwise
commit_messageanswersproposal_not_foundorproposal_changed. - It sends through the same path as
send_message, so the send policy and the duplicate guard apply. - Pressing Send counts as the user's confirmation only when both the preview and the commit come from a 2026-07-28 client that declares the extension. A policy rule that asks for confirmation still asks where the client supports forms.
MCP Events
2026-07-28 clients that support MCP Events, such as ChatGPT, subscribe a webhook to events with events/list, events/subscribe and events/unsubscribe. Subscribing takes read. Delivery is by webhook only, with no replay of events missed while a callback was down.
| Event | Fires on | Arguments |
|---|---|---|
mail.message_received | Inbound mail, not drafts or sent copies. | accountId, from (an address or @domain), mailboxRole, unreadOnly |
mail.reply_received | A new inbound message in a watched thread. | threadId (required), accountId |
calendar.event_changed | A calendar event changes. | accountId, calendarId, changes (any of created, updated, cancelled, invitation_received) |
Payloads are metadata only, never subjects or bodies; the agent reads those with get_message, get_thread or get_event:
- mail:
accountId,messageId,threadId, the sender's address (from) andreceivedAt; - calendar:
eventId,calendarId,changeandchangedFields.
Callbacks and delivery
- The callback must be https on a public address and echo a signed challenge before the subscription is stored.
- A credential gets 10 verification attempts and a callback host 20 per 10 minutes. A host that failed is refused for 10 minutes.
- The events methods share tool calls' rate limits.
- Deliveries are signed with the client's
whsec_secret (Standard Webhooks) and carryX-MCP-Subscription-Id. - Deliveries are retried like other webhooks until the subscription ends or its credential loses the account; a 410 or 413 is not retried.
Subscription lifetime
- A subscription lasts 24 hours unless the client asks otherwise, between 5 minutes and 30 days. Subscribing again refreshes it.
- A credential holds at most 20 subscriptions, reaching only its own accounts. They end when its API key, MCP key or OAuth grant does.
- Subscribing and unsubscribing are recorded in the audit log. Subscriptions do not show or count as webhook endpoints.