PluginWorld
Mu

multi-gcal-mcp

MCP

Enables Claude to read and manage Google Calendar across several independently authenticated Google accounts through one local connection, with dry-run previews for all writes.

@sharlenaluyen · v1.0.0 · MIT License · updated today

SECURITY

B

SCORE

68

STARS

▲ 0

PLUG IN

git clone https://github.com/sharlenaluyen/multi-gcal-mcp.git

See the README to configure this MCP server

README

multi-gcal-mcp

A local MCP server that lets Claude read and manage Google Calendar across several Google accounts through one connection. It runs on your own computer (stdio) and plugs into the Claude desktop app.

Accounts come from the shared google-mcp-accounts login, the same one the Gmail, Drive, and Docs/Sheets/Slides servers use. Authorize each Google account once there, and this server can use it.

Tools

Read:

  • list_accounts: connected accounts, their aliases, nicknames, and emails
  • list_calendars: calendars an account is subscribed to (id, name, access role)
  • list_events: events in a time window, soonest first, recurring events expanded
  • search_events: free-text search (title, description, location, attendees)

Write. Every one of these defaults to a dry run and needs an explicit confirm flag to touch your calendar:

Tool Confirm flag What the preview shows
create_event confirm_create: true The exact event (including any attached Drive files), and every guest Google will email an invitation to
update_event confirm_update: true A field-by-field before/after (attachments included), and everyone who'll get an update email
delete_event confirm_delete: true plus the preview's etag The event, who'll get a cancellation (only if this account is the organizer), a warning if the id is a whole recurring series, and an etag. If the event changes after the preview, nothing is deleted and a fresh preview is returned
respond_to_event confirm_send: true Your response changing from X to Y, and the organizer who's notified

Every dry run and every real write is appended to the shared audit log (~/.google-mcp/audit.log, tagged "server": "multi-gcal-mcp").

Attaching agendas and documents

create_event and update_event take an optional attachments list. Each entry is { file_url, title? }, where file_url is a Google Drive link, for example the link (webViewLink) that multi-gdrive-mcp's search_files returns. Calendar only accepts Drive files, so any other URL is refused before Google sees it. Requests are sent with supportsAttachments: true. On update_event, attachments replaces the whole list, like attendees does. Pass [] to remove every attachment.

Attaching a file doesn't share it. Guests can see an attached file but can open it only if they already have access. When an event has attachments, the preview reminds you of this. Share the file first with multi-gdrive-mcp's share_file.

Why every write gets a dry run

All four write tools can email other people: invitations, update notices, cancellations, and RSVPs. That mail can't be unsent, so these tools follow multi-gmail-mcp's send_email pattern: preview first, act only on an explicit confirm. respond_to_event was the closest call, because it only notifies the organizer. It still gets the treatment, since an RSVP is something another person sees.

None of the writes are ever auto-retried. A retry after a timeout could send a second invite or cancellation. Reads are retried with backoff on 429/5xx.

Scopes

Scope Why
calendar.events Read, create, change, delete, and RSVP to events. This server checks for it on every call.
calendar.calendarlist.readonly Needed beyond calendar.events, for list_calendars only. calendar.events doesn't cover calendarList.list (Google's discovery doc lists only calendar, calendar.readonly, calendar.calendarlist, and calendar.calendarlist.readonly for that call). This is the narrowest of those: read-only, and limited to the list of calendars you're subscribed to. It can't read events or change any calendar's settings.

The full calendar scope is deliberately not requested. Without calendar.calendarlist.readonly, every other tool still works when you use calendar_id: "primary" or a calendar id you already know. list_calendars tells you to re-run auth.js for that alias.

Setup

  1. Set up google-mcp-accounts and connect your accounts (node auth.js <alias>). Make sure the Google Calendar API is enabled on the Cloud project.

  2. Install this server:

    cd multi-gcal-mcp
    npm install
    

    Requires Node.js 20+. This repo depends on google-mcp-accounts as a local folder, "google-mcp-accounts": "file:../google-mcp-accounts". That works only while the two repos are siblings in the same parent folder. If you clone this somewhere they aren't, switch that line to a git dependency pinned to a tag, e.g. "github:<you>/google-mcp-accounts#v1.0.0". The tradeoff: file: picks up shared changes immediately, and a git tag picks them up only when you bump it.

Claude Desktop config

Add this under mcpServers in ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), then fully quit and reopen Claude Desktop:

{
  "mcpServers": {
    "multi-gcal": {
      "command": "node",
      "args": ["/absolute/path/to/multi-gcal-mcp/src/server.js"]
    }
  }
}

Input validation

  • Times: YYYY-MM-DD (all-day) or RFC 3339 (2026-11-03T15:00:00-08:00). A time without an offset needs time_zone, and the end must be after the start. Defaults are one hour, or one day for all-day events.
  • Guests: each must be one plain email address (no display names, no comma-lists), deduplicated, at most 100.
  • Attachments: https://drive.google.com/... or https://docs.google.com/... links only, deduplicated, at most 25 (Google's cap), title up to 256 chars.
  • Length caps: title 1,024 chars, description 8,192, location 1,024, search query 500, RSVP comment 1,000.

Security notes

  • Untrusted event text. Anyone can send you an invitation, so event titles, descriptions, locations, and calendar names come back wrapped in <untrusted_calendar_content> tags, with a notice telling Claude to treat them as data. That helps against indirect prompt injection but doesn't prevent it. The dry-run step and Claude Desktop's approval prompt are the real checks, so read them.
  • Tool annotations. Read tools are marked read-only. All four write tools are marked destructive and non-idempotent, so Claude Desktop asks before running them.
  • Every tool call is wrapped. A Google API error or a validation failure becomes a normal MCP error result and never crashes the server.
  • This server never writes to ~/.google-mcp/accounts.json. It only reads tokens.

Development

npm test      # node:test - time parsing, guest validation, diffs, RSVP, tool wrapper
npm run lint
npm run format

SIMILAR PLUGINS