Google Calendar MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCP_DATA_DIR | No | Registry and vault location. | ./data |
| MCP_LOG_LEVEL | No | Log level: debug, info, warn, error, or silent. | info |
| MCP_MASTER_KEY | Yes | Token-vault encryption passphrase. | |
| MCP_OAUTH_PORT | No | Loopback port for npm run auth. | 42813 |
| GOOGLE_CLIENT_ID | Yes | OAuth client id from Google Cloud. | |
| MCP_PRINCIPAL_ROLE | No | Session role ceiling. | admin |
| GOOGLE_CLIENT_SECRET | Yes | OAuth client secret from Google Cloud. | |
| MCP_DEFAULT_TIMEZONE | No | IANA zone, e.g. Asia/Jakarta. Defaults to the host system timezone. | |
| MCP_PLAN_TTL_SECONDS | No | How long a proposed schedule stays applicable. | 3600 |
| MCP_DYNAMIC_TOOL_EXPOSURE | No | Hide tools the session role cannot use. | true |
| MCP_CONFIRMATION_TTL_SECONDS | No | Confirm-token lifetime in seconds. | 300 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_accountsA | List every connected Google account with its id, email, role, enabled state and what it is permitted to do. Call this first when the user refers to a calendar by name ("my work calendar") so you can map it to an account id. |
| get_accountA | Show one account in detail: its role, the OAuth access level actually granted by Google, its calendars policy and its effective permissions. |
| describe_permissionsA | Explain the role model: which permissions each role grants, what role this session runs as, and what each connected account may do. Use this to answer "why can't you delete that?" accurately instead of guessing. |
| connect_accountA | Return the exact command the user must run to connect a new Google account. OAuth consent happens in the user's browser, not through this tool, so this returns instructions rather than performing the login. |
| disconnect_accountA | Revoke this server's access to a Google account, delete its stored tokens and remove it from the registry. Destructive and irreversible: reconnecting requires the user to complete Google consent again. Requires confirmation. |
| set_account_roleA | Change the role assigned to a connected account. Note that a role can never exceed the OAuth scopes Google actually granted: promoting a read-only account to editor will not let it write. |
| set_account_enabledA | Enable or disable an account without deleting its tokens. A disabled account is excluded from every operation, including read fan-outs. |
| list_calendarsA | List the calendars available on one or more connected accounts. Returns the calendar id needed by the event tools, along with the access level the account has on each calendar. |
| list_eventsA | List events in a time range. With no |
| list_all_eventsA | Unified view of every event across every readable account and calendar in a time range, sorted by start time. Use this when the user asks about their whole schedule, or before reasoning about cross-account conflicts. |
| search_eventsA | Full-text search across events in a time range. Matches titles, descriptions, locations and attendees. Searches every readable account unless |
| get_eventA | Fetch a single event by id. The account must be given explicitly, because an event id is only meaningful within the account it came from. |
| create_eventA | Create an event on one account. If |
| update_eventA | Change fields on an existing event. Only the fields you supply are modified; everything else is left alone. The account must be explicit because event ids are account-scoped. |
| move_eventA | Move an event to a different calendar on the SAME account. Google cannot move an event between two different Google accounts; to do that, create it on the target account and delete the original. |
| delete_eventA | Permanently delete an event. Destructive and irreversible. The first call returns CONFIRMATION_REQUIRED with a description of exactly what would be deleted and a confirm_token; show that to the user, and only call again with the token once they have explicitly approved it. |
| check_freebusyA | Return the busy periods across accounts in a time range, plus the merged busy timeline. Use this to answer "am I free at 3pm?" without reading event details. |
| find_cross_account_conflictsA | Find events that overlap across different accounts - for example a doctor appointment on personal that collides with a meeting on work. Returns each conflicting pair with the exact overlap window. |
| find_available_slotsA | Find times when the user is free across all their calendars at once. Merges busy periods from every checked account, then returns slots of the requested length. Always report which accounts were checked, since a slot is only trustworthy if every relevant calendar was included. |
| get_routineA | Show the routine that drives scheduling: sleep and wake times, the main job window, and every recurring activity with its duration, preferred window and energy level. Read this before proposing a schedule so you can explain what is fixed and what is flexible. |
| update_routineA | Change sleep times, daily limits, or one activity in the routine. Use this when the user says things like "make DSA 60 minutes", "I want to wake at 6", or "move part-time work earlier". Changes persist to data/routine.json. |
| reset_routineB | Restore the built-in default routine: early wake, morning exercise, a 10:00–19:00 work-from-anywhere main job with flexible gaps, morning DSA study, midday English practice, and evening part-time work. Overwrites any customisation. |
| propose_scheduleA | Read every connected calendar, find the real commitments, and compute a balanced schedule around them. Writes nothing — it returns a plan with a plan_id, an explanation of why each block landed where it did, and an honest workload verdict. Show the plan to the user and get explicit approval before calling apply_schedule. |
| apply_scheduleA | Create calendar events for a plan the user has approved. Requires a plan_id from propose_schedule. The first call returns a confirm_token and a summary of exactly what will be created; call again with the token only after the user has said yes. Busy time is re-checked immediately before writing, so anything that became busy since the proposal is skipped rather than double-booked. |
| review_weekA | Analyse a week that already exists on the calendars: hours per category, how balanced the days are, where the long unbroken stretches are, and whether sleep is being protected. Use this to open a weekly planning session, before proposing the next week. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| plan_week | Full weekly planning session: review the week just gone, read every calendar, propose a balanced schedule for the week ahead, and apply it only after approval. |
| plan_tomorrow | Plan a single day around what is already on the calendars, with a realistic shape from wake-up to wind-down. |
| daily_check_in | A short morning briefing: what is on today across every calendar, where the conflicts are, and what the first focused block should be. |
| find_time_for | Find realistic slots for a specific commitment across every calendar, respecting the routine and existing obligations. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 25 tools
Most tools target a distinct resource+action pair (event CRUD, account admin, free/busy, scheduling). The one real overlap is list_events vs list_all_events: list_events with no `accounts` argument already queries every readable account and calendar, which makes it functionally near-identical to list_all_events, so an agent may hesitate between them. search_events and the free/busy trio are sufficiently differentiated.
Consistent snake_case verb_noun pattern throughout: get_/list_/create_/update_/delete_/set_ prefixes applied uniformly (get_account, list_events, create_event, set_account_role, find_available_slots, propose_schedule). No mixed conventions or vague verbs like 'process' or 'run'.
25 tools sits at the heavy end of the range for a single-domain calendar server. The breadth (multi-account admin, routine management, free/busy analytics, plan propose/apply) justifies many of them, but the surface is larger than needed and some clustering (three free/busy tools, two list/all-event tools) could be consolidated.
Covers event lifecycle (create/update/move/delete/get/list/search), account lifecycle (connect/disconnect/roles/enabled), calendars, availability reasoning and scheduling plans. Minor gaps: no attendee/invite handling, no recurring-event management, and no calendar creation/deletion. Core workflows are otherwise complete with proper confirmation flows for destructive ops.