MCP permissions and security
What an agent can do through MCP is bounded twice: by the scopes on the API key behind the connection, and by the server's own handling of email content it did not write. This page covers choosing connection permissions, how the server treats untrusted content, including in events, and the smoke test to run against production before trusting a new setup. For the tool list, see tools, resources and prompts.
Last updated
Choose connection permissions
OAuth connections are configured under Developer, Connections. Choose Read and draft, Mail assistant, Full access, or Custom. Full access grants every permission your role can hold, with no mailbox or domain limit. Custom groups the permissions by area, and its mailbox and domain limits are optional. Leave them alone and the connection reaches everything you can reach, now and later. Stdio uses the same policy through its API key. Changing the policy takes effect on the next REST call. Reconnect the host to refresh a cached tool list after expanding access.
A client may also request OAuth scopes, which use the API key scope names. Its token then reaches only the tools, resources and events those scopes allow, and only within the permissions you approved. A client that requests no API scope gets everything your approval allows. After you approve specific API scopes, a token request that drops them gets invalid_scope; disconnect the app in Developer, Connections to approve it again without them.
When you approve a connection with a mailbox password, it stays limited to the mailbox you signed in with. You can choose member-tier capabilities for that mailbox, but cannot add another organization or mailbox. An account sign-in is required for broader access. Resetting the mailbox password, revoking an app password, signing out of the mailbox, or losing mailbox access disconnects its mailbox-approved AI connections.
Existing AI connections need to reconnect once so Shipmail can apply the current connection boundary. Reconnect from the AI client and review the permissions again.
Check the app before connecting
Shipmail supports open OAuth client registration so MCP apps can connect without a manual registration step. Registering an app does not grant access to your account or email. You must sign in, complete any required multi-factor authentication, and approve the connection permissions.
Check the callback destination on the consent screen before approving. App names are supplied by the app, and a familiar name does not prove who operates it. A local callback also does not verify the app's publisher. Only connect apps you intended to use, and choose the organizations, mailboxes, and permissions they need.
Each request checks the connection's current permissions and approved client ID. Revoking a connection stops its MCP access even if an access token has not expired. Reconnecting with a new client registration replaces the previously approved registration.
Registration requests are rate limited. New anonymous registrations that remain unused may be removed after seven days; an app can register again when you connect it. Cleanup preserves registrations with stored consent, tokens, or a connection.
Security behavior
- Email bodies, addresses, and error text are sanitized before reaching the LLM.
- Email bodies and attachments remain untrusted data and cannot authorize outbound tool calls.
- Unexpected upstream errors are redacted while preserving the request ID for support.
- Webhook URLs must be public HTTPS endpoints.
- Risky tools have per-session circuit-breaker limits.
- Destructive tools are annotated so MCP hosts can require confirmation.
Untrusted content in events
An MCP event for new mail carries the subject and the sender's name and address. Whoever sent the message wrote them, so a subject can contain text that reads like an instruction. The event schema marks those fields as untrusted, and an event never carries the body, a snippet or attachment names. Calendar and booking events work the same way: an invitation's title and a booker's name are marked untrusted, and an event never carries an event description or a booking note.
An automation runs with the connection's permissions, without you watching. Give the connection only what the automation needs, and prefer drafting a reply over sending one when the trigger is mail from people you do not know. Filter on a sender or a domain where you can.
Production smoke test
The repository QA command installs the published npm package in a temporary directory and connects over MCP stdio. It verifies startup, tool registration, and status access without changing account state.
bun run qa