An assistant with unrestricted access to your mailbox is a bad first configuration; here reading and searching work immediately while `GMAIL_ALLOW_SENDING` and `GMAIL_ALLOW_DRAFTS` stay off until you decide otherwise. The multi-account handling is the other well-judged piece: `extra_info` on each account is free text the assistant reads, so "check my personal account's family calendar" resolves without you naming the address.
An MCP server for Gmail and Google Calendar that handles multiple Google accounts at once, each with its own metadata and description so the assistant knows which is which. Gmail tools cover search with Gmail's own query syntax, reading full message bodies, drafts, replies, attachments and archiving, singly and in bulk; Calendar tools cover listing calendars, reading a date range, and creating and deleting events with attendees and timezones.
- Mail searched with Gmail syntax such as `is:unread`, `from:`, `newer_than:` and `has:attachment`, then read in full singly or in batches — `gmail_query_emails`, `gmail_get_email`, `gmail_bulk_get_emails`
- Drafts created, listed and deleted, with the list returning the `draft_id` that deletion needs — it is distinct from the message ID a search returns — `gmail_create_draft`, `gmail_list_drafts`, `gmail_delete_draft`
- Replies composed and either sent or saved as a draft, with reply-all through CC — `gmail_reply`
- Attachments downloaded to disk or returned as an embedded resource, one at a time or in bulk — `gmail_get_attachment`, `gmail_bulk_save_attachments`
- Inbox cleanup singly or in bulk — `gmail_archive`, `gmail_bulk_archive`
- Calendars listed with access roles and timezone, events read over a date range across several calendars, and events created and deleted with attendees and notifications — `calendar_list`, `calendar_get_events`, `calendar_create_event`, `calendar_delete_event`
- The configured accounts listed with their metadata, including the free-text `extra_info` you write to tell the assistant what each account is for — `gmail_list_accounts`, `calendar_list_accounts`
A Google Cloud project with the Gmail and Calendar APIs enabled and OAuth 2.0 credentials. Node.js >= 20, a clone built with `npm install` and `npm run build`. Two files sit in the project root: `.gauth.json` with the OAuth client, and `.accounts.json` listing which accounts may use the server. Run `npm run authenticate` once per account — it opens a browser, listens on port 4100 for the callback, and stores credentials as `.oauth2.{email}.json`. The scopes requested are `openid`, `https://mail.google.com/`, `gmail.settings.basic`, `calendar` and `userinfo.email`. Three environment variables gate the destructive parts: `GMAIL_ALLOW_SENDING` must be `true` before `gmail_send` actually sends, `GMAIL_ALLOW_DRAFTS` must be `true` before draft creation works, and `GMAIL_ATTACHMENTS_DIR` bounds where attachments may be written — absolute paths, traversal and escaping symlinks are rejected. Both default to disabled.
One command plus a key — npx mcp-google-workspace, then supply credentials
