Gmail & Google Calendar Server
БесплатноНе проверенCombines Gmail and Google Calendar operations with multi-account OAuth, attachments, and email templates in a single MCP server.
Описание
Combines Gmail and Google Calendar operations with multi-account OAuth, attachments, and email templates in a single MCP server.
README
Status: beta
gws is a CLI-first Google Workspace tool for local automation. It exposes Gmail, Google Calendar, Google Drive, Google Docs, and Google Sheets workflows from the terminal, with the existing MCP server preserved as gws-mcp for assistant clients.
The direction is deliberate: the CLI is the primary product surface; MCP is a compatibility adapter.
What it includes today
gwsCLI binary for account, config, Gmail, Calendar, Drive, Docs, Sheets, and local diagnosticsgws-mcpbinary preserving the existing stdio MCP server- OAuth2 for personal Gmail and Google Workspace accounts
- Multi-account state via
~/.config/gws/state.json - JSON-first output for scripts, plus table/jsonl/tsv formats
- Gmail list/search/read/send/reply/forward/delete/archive/labels/drafts/threads/attachments/read-status commands
- Calendar list/upcoming/search/freebusy/create/update/delete/respond/quickadd/conference/instances commands, plus secondary calendar create/delete
- Drive list/get/upload/download/mkdir/share/trash/restore/copy/batch-delete/revisions/shared-drives/shortcut commands (full CLI↔MCP parity)
- Docs get/export/create plus insert-text/replace-text/insert-table/insert-image/batch-update commands (CLI↔MCP parity via
documents.batchUpdate) - Sheets get/values (get/update/append)/add-sheet/delete-sheet/rename-sheet/clear/batch-update commands
- Tasks task-list and task list/get/create/update/complete/move/delete commands
- Contacts (People) list/search/get/create/update/delete and contact-group list/get commands
- Existing MCP toolset for Gmail, Calendar, attachments, templates, and Sheets
Install
git clone https://github.com/ftaricano/mcp-gmail-calendar.git
cd mcp-gmail-calendar
npm install
npm run build
npm link
Prerequisites:
- Node.js 20+
- Google Cloud OAuth credentials
- Google APIs enabled for the surfaces you use:
- Gmail API
- Google Calendar API
- Google Drive API
- Google Docs API
- Google Sheets API
- Google Tasks API
- Google People API
If you already authenticated before Drive/Docs/Sheets support existed, run gws auth login --account [email protected] --type workspace again so Google grants the expanded OAuth scopes.
⚠️ Tasks requires re-consent. Google Tasks adds a brand-new OAuth scope (
https://www.googleapis.com/auth/tasks). Any account authenticated before Tasks support existed must re-rungws auth login --account [email protected] --type workspaceto grant it. Without re-consent, every Tasks call returns HTTP 403.gws auth logindetects when a stored account is missing a current scope and re-triggers the Google consent screen automatically (it is no longer a no-op for already-known accounts).
⚠️ Contacts requires re-consent. Google People / Contacts adds a brand-new OAuth scope (
https://www.googleapis.com/auth/contacts). Any account authenticated before Contacts support existed must re-rungws auth login --account [email protected] --type workspaceto grant it. Without re-consent, every Contacts call returns HTTP 403. As with Tasks,gws auth loginauto-detects the missing scope and re-triggers the Google consent screen.
Configure environment:
cp .env.example .env
Set at least:
GOOGLE_CREDENTIALS_PATH=/absolute/path/to/credentials.json
TOKENS_PATH=/absolute/path/to/tokens
OAUTH_CALLBACK_PORT=3000
LOG_LEVEL=info
CLI quickstart
Authenticate:
gws auth login --account [email protected] --type workspace
List accounts:
gws auth list
Set the default account:
gws auth switch [email protected]
Show current account:
gws auth current
Inspect CLI paths:
gws config path
Set config values:
gws config set timezone America/Sao_Paulo
gws config list
Run local diagnostics without printing secrets:
gws doctor --format json
Gmail examples
List recent mail:
gws mail list --query "is:unread" --limit 10
Read and search:
gws mail read MESSAGE_ID
gws mail search "from:[email protected] has:attachment" --limit 20
Send, reply, forward:
gws mail send --to [email protected] --subject "Proposal" --body "Attached." --attachment ./proposal.pdf
gws mail reply MESSAGE_ID --body "Recebido, obrigado."
gws mail forward MESSAGE_ID --to [email protected] --body "Please review."
Archive and delete:
gws mail archive MESSAGE_ID
gws mail delete MESSAGE_ID # move to trash
Drafts:
gws mail drafts list --query "is:draft" --limit 10
gws mail drafts get DRAFT_ID
gws mail drafts create --to [email protected] --subject "Proposal" --body "Draft body"
gws mail drafts send DRAFT_ID
gws mail drafts delete DRAFT_ID
Threads:
gws mail threads list --query "from:[email protected]" --label INBOX --limit 10
gws mail threads get THREAD_ID
gws mail threads modify THREAD_ID --add-label LABEL_ID --remove-label INBOX
gws mail threads trash THREAD_ID
Dry-run destructive or mutating actions:
gws --dry-run mail delete MESSAGE_ID
gws --dry-run mail archive MESSAGE_ID
gws --dry-run mail drafts create --to [email protected] --subject "Proposal" --body "Draft body"
gws --dry-run mail drafts send DRAFT_ID
gws --dry-run mail threads modify THREAD_ID --add-label LABEL_ID
gws --dry-run mail mark-read MESSAGE_ID
Labels and attachments:
gws mail labels
gws mail labels create "Clients"
gws mail labels add MESSAGE_ID LABEL_ID
gws mail labels remove MESSAGE_ID LABEL_ID
gws mail attachments list MESSAGE_ID
gws mail attachments download MESSAGE_ID ATTACHMENT_ID --output ./downloads/file.pdf
Legacy aliases remain available:
gws mail attachments-list MESSAGE_ID
gws mail attachment-download MESSAGE_ID ATTACHMENT_ID --output ./downloads/file.pdf
Calendar examples
List calendars and events:
gws cal calendars
gws cal events upcoming --days 7 --limit 10
gws cal events list --from 2026-05-01T00:00:00-03:00 --to 2026-05-08T00:00:00-03:00
gws cal events search "planning" --limit 5
Secondary calendars (create is mutating, delete is destructive — both support --dry-run):
gws --dry-run cal calendars create --summary "Project X" --description "Tracking" --timezone America/Sao_Paulo
gws cal calendars create --summary "Project X"
gws --dry-run cal calendars delete CALENDAR_ID
Recurring event occurrences (read-only):
gws cal events instances RECURRING_EVENT_ID --from 2026-05-01T00:00:00-03:00 --to 2026-06-01T00:00:00-03:00 --limit 20
Each instance returned by cal events instances has its own id. To edit or delete a single occurrence, pass that instance id to the regular update/delete commands — the Calendar API treats each instance as an independent event:
gws cal events update INSTANCE_ID --summary "Moved this one only"
gws cal events delete INSTANCE_ID
Create and update events:
gws cal events create --summary "Client call" --start 2026-05-03T10:00:00-03:00 --end 2026-05-03T11:00:00-03:00 --attendee [email protected] --meet
gws cal events update EVENT_ID --summary "Updated title" --send-notifications
Free/busy, invitation response, quick add, Meet conference:
gws cal freebusy --from 2026-05-01T00:00:00-03:00 --to 2026-05-02T00:00:00-03:00 --calendar primary
gws --dry-run cal events respond EVENT_ID --response accepted --comment "Confirmado"
gws cal events quickadd "Lunch with Ana tomorrow noon"
gws cal events conference EVENT_ID --type hangoutsMeet
Drive examples
gws drive list --query "mimeType != 'application/vnd.google-apps.folder'" --limit 20
gws drive get FILE_ID
gws --dry-run drive upload --path ./proposal.pdf --name "Proposal.pdf" --parent FOLDER_ID
gws drive download FILE_ID --output ./downloads/proposal.pdf
gws drive mkdir "Client Docs" --parent PARENT_FOLDER_ID
gws --dry-run drive share FILE_ID --role reader --type user --email [email protected]
gws --dry-run drive trash FILE_ID
gws --dry-run drive restore FILE_ID
gws --dry-run drive copy FILE_ID --name "Copy.pdf" --parent FOLDER_ID
gws --dry-run drive batch-delete FILE_ID_1 FILE_ID_2 FILE_ID_3
gws --dry-run drive shortcut TARGET_FILE_ID --name "Shortcut" --parent FOLDER_ID
gws drive revisions FILE_ID
gws drive shared-drives --limit 20
Allowed Drive share roles: reader, commenter, writer.
Allowed Drive share types: user, group, domain, anyone.
drive trash, drive restore, drive copy, drive batch-delete, and drive shortcut are mutating and support --dry-run. For safety, drive trash and drive batch-delete move files to the Drive trash (recoverable) rather than deleting permanently; batch-delete continues past per-file errors and reports a per-id status. drive revisions and drive shared-drives are read-only.
Docs examples
gws docs get DOCUMENT_ID
gws docs export DOCUMENT_ID --mime-type pdf --output ./doc.pdf
gws docs create --title "Meeting Notes" --content "Initial notes"
gws --dry-run docs insert-text DOCUMENT_ID --text "Appended line" --index 1
gws --dry-run docs replace-text DOCUMENT_ID --find "{{name}}" --replace "Ferd" --match-case
gws --dry-run docs insert-table DOCUMENT_ID --rows 3 --columns 2 --index 1
gws --dry-run docs insert-image DOCUMENT_ID --uri https://example.com/logo.png --index 1
gws --dry-run docs batch-update DOCUMENT_ID --requests '[{"insertText":{"location":{"index":1},"text":"raw"}}]'
Export MIME aliases include pdf, docx, txt, and html.
The edit commands (insert-text, replace-text, insert-table, insert-image, batch-update)
are mutating and support --dry-run, returning a { "dryRun": true, "would": ... } envelope. They
are backed by Google Docs documents.batchUpdate; batch-update accepts a raw request array for
operations not covered by the typed helpers (text styling, paragraph formatting, etc.).
Sheets examples
gws sheets get SPREADSHEET_ID
gws sheets values SPREADSHEET_ID --range "Sheet1!A1:C10"
gws --dry-run sheets update SPREADSHEET_ID --range "Sheet1!A1:B2" --values '[["a","b"],["c","d"]]' --value-input-option USER_ENTERED
gws sheets append SPREADSHEET_ID --range "Sheet1!A:B" --values '[["new","row"]]'
gws --dry-run sheets add-sheet SPREADSHEET_ID --title "Q3" --rows 200 --columns 12
gws --dry-run sheets rename-sheet SPREADSHEET_ID --sheet-id 0 --title "Summary"
gws --dry-run sheets delete-sheet SPREADSHEET_ID --sheet-id 123456
gws --dry-run sheets clear SPREADSHEET_ID --range "Sheet1!A1:Z100"
gws --dry-run sheets batch-update SPREADSHEET_ID --requests '[{"repeatCell":{"range":{"sheetId":0},"cell":{"userEnteredFormat":{"textFormat":{"bold":true}}},"fields":"userEnteredFormat.textFormat.bold"}}]'
Allowed value input options: RAW, USER_ENTERED.
Formulas are written through the regular values update/values append commands with
--value-input-option USER_ENTERED, which tells Sheets to parse formulas and numbers
instead of storing literal strings. add-sheet, delete-sheet, rename-sheet, clear,
and batch-update are mutating and support --dry-run, returning a
{ "dryRun": true, "would": ... } envelope. batch-update takes a raw JSON array of
Sheets API Request objects (formatting, data validation, conditional formatting, etc.);
malformed JSON fails with a clear requests must be valid JSON validation error.
Tasks examples
Tasks needs the
tasksOAuth scope. If you authenticated before Tasks support existed, re-rungws auth login --account [email protected] --type workspacefirst, otherwise calls return 403.
gws tasks lists list
gws tasks lists get LIST_ID
gws --dry-run tasks lists create --title "Groceries"
gws --dry-run tasks lists update LIST_ID --title "Renamed"
gws --dry-run tasks lists delete LIST_ID
gws tasks list LIST_ID --show-completed --limit 50
gws tasks get LIST_ID TASK_ID
gws --dry-run tasks create LIST_ID --title "Buy milk" --notes "whole" --due 2026-06-20T00:00:00Z
gws --dry-run tasks update LIST_ID TASK_ID --title "New title" --status needsAction
gws --dry-run tasks complete LIST_ID TASK_ID
gws --dry-run tasks move LIST_ID TASK_ID --parent PARENT_ID --previous SIBLING_ID
gws --dry-run tasks delete LIST_ID TASK_ID
Allowed task status values: needsAction, completed.
Contacts examples
Contacts needs the
contactsOAuth scope. If you authenticated before Contacts support existed, re-rungws auth login --account [email protected] --type workspacefirst, otherwise calls return 403.
gws contacts list --page-size 50
gws contacts search "Ada"
gws contacts get people/c123
gws --dry-run contacts create --json '{"names":[{"givenName":"Ada","familyName":"Lovelace"}],"emailAddresses":[{"value":"[email protected]"}]}'
gws --dry-run contacts update people/c123 --json '{"names":[{"givenName":"Grace"}]}' --fields names
gws --dry-run contacts delete people/c123
gws contacts groups list
gws contacts groups get contactGroups/abc
The --json payload is a People API Person resource. contacts update resolves the required etag automatically (it reuses etag from the payload when present, otherwise fetches the current one before patching).
Output formats
Default output is JSON and stdout is kept data-only for successful commands.
gws mail list --format json
gws mail list --format table
gws mail list --format jsonl
gws mail list --format tsv
yaml is reserved but not bundled yet.
Account resolution
Commands resolve the active account in this order:
--account [email protected]GWS_ACCOUNTenvironment variable~/.config/gws/state.jsoncurrent account- first authenticated account
- auth error
Safety and automation conventions
- Mutating commands support
--dry-runwhere practical and return{ "dryRun": true, "would": ... }. - CLI output redacts token/secret-like values in error details.
- Attachment downloads preserve the existing account sandbox protections.
- Tests use injected fake services and do not require real Google credentials.
MCP compatibility
The MCP server is still available as gws-mcp and preserves the current tool names.
Example MCP config:
{
"mcpServers": {
"gmail-calendar": {
"command": "gws-mcp",
"env": {
"GOOGLE_CREDENTIALS_PATH": "/absolute/path/to/credentials.json",
"TOKENS_PATH": "/absolute/path/to/tokens",
"OAUTH_CALLBACK_PORT": "3000"
}
}
}
}
Existing direct path usage also works:
node /absolute/path/to/mcp-gmail-calendar/dist/index.js
MCP tool groups
- Account:
authenticate,list_accounts,switch_account,remove_account,get_current_account - Gmail:
email_list,email_read,email_send,email_reply,email_forward,email_delete,email_mark_read,email_mark_unread,email_search, labels, batch operations - Attachments:
email_list_attachments,email_download_attachment - Calendar:
calendar_list,event_list,event_get,event_create,event_update,event_delete, availability, invitation response, quick add, upcoming - Drive:
drive_list,drive_get,drive_upload,drive_download,drive_mkdir,drive_share,drive_trash,drive_restore,drive_copy,drive_batch_delete,drive_revisions,drive_shared_drives,drive_shortcut - Templates: list, render, create
- Docs:
docs_get,docs_create,docs_export,docs_batch_update,docs_insert_text,docs_replace_text,docs_insert_table,docs_insert_image - Sheets:
sheets_get,sheets_values_get,sheets_values_update,sheets_values_append,sheets_batch_update,sheets_add_sheet,sheets_delete_sheet,sheets_rename_sheet,sheets_clear
Docs has full CLI↔MCP parity: every gws docs <command> maps to a docs_* MCP tool with the same
underlying service method. Mutating MCP tools validate arguments with zod and reject malformed input
with InvalidParams; the CLI exposes the same operations behind --dry-run.
Drive now has CLI↔MCP parity: every gws drive command has a matching drive_* MCP tool. As in the CLI, drive_trash and drive_batch_delete move files to the trash (recoverable) instead of deleting permanently.
The Sheets surface is at parity between the CLI (gws sheets ...) and MCP (sheets_*
tools): both cover values get/update/append, structural mutations (add/delete/rename
sheet), range clears, and raw batchUpdate requests. Use --value-input-option USER_ENTERED (CLI) or valueInputOption: "USER_ENTERED" (MCP) to write formulas.
- Tasks:
tasks_lists_list,tasks_lists_get,tasks_lists_create,tasks_lists_update,tasks_lists_delete,tasks_list,tasks_get,tasks_create,tasks_update,tasks_complete,tasks_move,tasks_delete - Contacts (People):
people_contacts_list,people_contacts_search,people_contacts_get,people_contacts_create,people_contacts_update,people_contacts_delete,people_groups_list,people_groups_get
Development
npm run cli -- --help
npm run build
npm test
npm run lint
npm pack --dry-run --json
CI runs lint, build, and tests on Node 20 and 22.
Roadmap
- Split the large CLI program into command modules as the command surface grows
- Expand People/Contacts support
- Add incremental OAuth scopes per Workspace surface
- Add richer Drive/Docs/Sheets operations after real-world CLI usage
Security
See SECURITY.md. Tokens stay local and are never printed by CLI account commands.
Установка Gmail & Google Calendar Server
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/ftaricano/mcp-gmail-calendarFAQ
Gmail & Google Calendar Server MCP бесплатный?
Да, Gmail & Google Calendar Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Gmail & Google Calendar Server?
Нет, Gmail & Google Calendar Server работает без API-ключей и переменных окружения.
Gmail & Google Calendar Server — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Gmail & Google Calendar Server в Claude Desktop, Claude Code или Cursor?
Открой Gmail & Google Calendar Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Gmail
Read, send and search emails from Claude
автор: GoogleSlack
Send, search and summarize Slack messages
автор: SlackRunbear
No-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
Discord Server
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)
Compare Gmail & Google Calendar Server with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории communication
