Skip to main content
Glama
TimeTree MCP Server

TimeTree MCP Server

by ehs208
NOTE

Unofficial and for personal use. Not affiliated with TimeTree, Inc. It uses the TimeTree web app's undocumented endpoints, which can change at any time. SeeDISCLAIMER.md.

Ask your AI assistant things like:

  • "Summarize our family calendar this week. Any conflicts?"

  • "When was the last dentist appointment?"

  • "Add a dinner on Saturday at 7 pm to the Family calendar."

  • "Turn this trip plan into events and a packing memo."

  • "Who changed the calendar today, and what did they change?"

What it does

  • Reads your calendars. Events with date, keyword, and label filters. Recurring events are expanded into their actual dates.

  • Reads comment images. Pass images attached to event comments to your AI client, including images posted by free accounts.

  • Changes them when you ask. Create, update, copy, and delete events, memos, and comments, and rename or recolor labels. Change or delete a single occurrence of a recurring event, or it and the ones after it.

  • Manages virtual members. Add, rename, or remove members without a TimeTree account, such as children or pets.

  • Keeps you up to date. See what changed since a given time, and who made recent changes.

  • Knows the context. Calendar members and public holidays by country.

  • Runs on your computer. Your email and password are sent only to TimeTree. The session stays in memory.

Related MCP server: Chronos MCP

Install

Claude Desktop (macOS, Windows): one-click extension

  1. Download timetree-mcp-<version>.mcpb from the latest release.

  2. Open the file. Claude Desktop shows an install dialog.

  3. Enter your TimeTree email and password, then enable the extension.

No Git, Node.js install, or config file editing is needed. The extension runs on the Node.js that comes with Claude Desktop on macOS and Windows.

Claude Code, Codex, Cursor, and other clients

Requires Node.js 22 or later and Git.

Ask your coding agent. Paste this into Claude Code, Codex, or a similar agent:

Clone https://github.com/ehs208/TimeTree-MCP, enter the cloned directory, run npm ci && npm run build, then configure my MCP client with a server named timetree that runs node /absolute/path/to/TimeTree-MCP/dist/index.js (use the real cloned path). Store TIMETREE_EMAIL and TIMETREE_PASSWORD only in the MCP client environment configuration, and never hardcode or print secrets.

Or run the installer. It clones, builds, and prints a config example for each client:

curl -fsSL https://raw.githubusercontent.com/ehs208/TimeTree-MCP/main/TimeTree-MCP-install.sh | bash
git clone https://github.com/ehs208/TimeTree-MCP.git
cd TimeTree-MCP
npm ci
npm run build

Then add the server to your MCP client. Example for Claude Desktop on macOS (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "timetree": {
      "command": "node",
      "args": ["/absolute/path/to/TimeTree-MCP/dist/index.js"],
      "env": {
        "TIMETREE_EMAIL": "your-email@example.com",
        "TIMETREE_PASSWORD": "your-password"
      }
    }
  }
}

If a GUI client cannot find node, use the absolute path from command -v node as command.

Setup for each client (Claude Code, Codex, Cursor, Windsurf, VS Code, Antigravity, and more): docs/MCP_CLIENTS.md

This project is not published to npm. Install it from a GitHub release or a clone of this repository.

Updating

When a newer version is out, the server adds a one-time notice to a tool response, so your assistant can tell you. Set TIMETREE_UPDATE_CHECK=false in the MCP env to turn this off.

  • Claude Desktop extension: download the new .mcpb from the latest release and open it.

  • Git clone: run git pull origin main && npm ci && npm run build in the folder, then restart your MCP client.

Details: docs/UPDATING.md. Changes: CHANGELOG.md.

Tools

Area

Tools

Calendars

list_calendars, create_calendar, get_current_user

Events

get_events, get_updated_events, create_event, update_event, delete_event, copy_event

Recurring events

update_event_occurrence, delete_event_occurrence

Memos

list_memos, create_memo, update_memo, delete_memo

Comments

list_event_comments, get_event_comment_image, add_event_comment, update_event_comment, delete_event_comment

Labels and members

get_calendar_labels, update_calendar_labels, get_calendar_members, get_calendar_virtual_members, create_virtual_member, update_virtual_member, delete_virtual_member

Other

get_holidays, get_recent_activity

Parameters and examples: COMMANDS.md

create_calendar requires a name (1–20 characters) and an explicit purpose. It does not invite members. Timeouts and server errors are not retried. If the creation response cannot be validated, check existing calendars before trying again.

list_event_comments includes image metadata. Use get_event_comment_image to retrieve one image as standard MCP image content over stdio; the client must support image tool results. JPEG, PNG, GIF, and WebP up to 5 MiB are supported. Images stay in memory and are not saved to disk. Premium files attached directly to an event and image uploads are not supported.

Privacy and security

  • Your email and password are stored only in your MCP client configuration, or in Claude Desktop's extension settings. They are sent only to TimeTree.

  • Session cookies and CSRF tokens stay in memory and are never written to disk.

  • Logs mask passwords, cookies, and tokens.

  • On startup, the server makes one request to GitHub to check for a newer version. No credentials or calendar data are sent.

Troubleshooting

"Missing required environment variables": set TIMETREE_EMAIL and TIMETREE_PASSWORD in your MCP configuration. For the Claude Desktop extension, open its settings and enter them again.

Sign-in fails: check that you can sign in on the TimeTree web app with the same email and password. The server signs in with email and password only.

No calendars or events: make sure the account has calendars, and check the client's MCP logs. TimeTree may have changed its web API; please open an issue.

How it works

The server signs in to the TimeTree web app with your email and password, then calls the same endpoints the web app uses. It signs in again when the session expires, limits requests to 10 per second with retries on HTTP 429, and reads every page of large calendars.

Write requests need a CSRF token, which the server reads from the TimeTree web page after signing in.

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md.

Thanks to everyone who has contributed.

Credits

API insights from TimeTree-Exporter by @eoleedi.

License

MIT. See LICENSE. Not affiliated with TimeTree, Inc. See DISCLAIMER.md.

Available Tools

29 tools
add_event_commentA

Post a comment on an event and return it with its id. Comments are visible to everyone in the calendar; by default no push notification is sent (silent). Get event_uuid from get_events. To change the event's own note use update_event; to edit or remove a comment later use update_event_comment or delete_event_comment.

Inputs: content (required), event_uuid (required), calendar_id (required), silent. Returns: comment, message, success

copy_eventA

Copy an existing event to a new date and time, optionally into another calendar, and return the new event. Keeps the title, note, location, URL, label, reminders, and checklist; recurrence is not copied, so the copy is a single event. Attendees and virtual attendees are kept only within the same calendar. The original is unchanged.

Inputs: start_at (required), event_uuid (required), calendar_id (required), title, +2 more. Returns: event, message, success

create_calendarA

Create a new, empty calendar owned by you and return its ID. Does not invite anyone or change existing calendars. Name is 1-20 characters and purpose is required. After a timeout or server error, check list_calendars before retrying, since the calendar may already exist.

Inputs: name (required), purpose (required). Returns: id, name, alias_code

create_eventA

Create an event in a TimeTree calendar and return it with its uuid. Other calendar members see it, and attendees may be notified. Supports all-day events, reminders, RRULE recurrence, attendees (user IDs from get_calendar_members), virtual member attendees, and a checklist. For a memo without a date use create_memo; to duplicate an existing event use copy_event.

Inputs: title (required), end_at (required), start_at (required), calendar_id (required), +14 more. Returns: event, message, success

create_memoA

Create a memo in a calendar and return it with its uuid: a note, list, or checklist that is not a scheduled event, such as a shopping list. Other calendar members can see it. Use create_event for something that happens at a time. Change it later with update_memo.

Inputs: title (required), calendar_id (required), url, date, +5 more. Returns: memo, message, success

create_virtual_memberA

Add a virtual member to a calendar: someone or something without a TimeTree account, such as a child, pet, or car, so events can be assigned to it with virtual_user_attendees. Everyone in the calendar sees it. A calendar can have at most 10. Returns the new member with its id and uuid.

Inputs: name (required), calendar_id (required), type, birthday, +2 more. Returns: message, success, virtual_member

delete_eventA
DestructiveIdempotent

Delete an event, including every occurrence of a recurring event. Cannot be undone. To delete one occurrence or the ones after it, use delete_event_occurrence. For memos use delete_memo.

Inputs: event_uuid (required), calendar_id (required). Returns: message, success, deleted_event_uuid

delete_event_commentA
DestructiveIdempotent

Delete a comment from an event. Cannot be undone, and TimeTree lets only the comment's author delete it. Get comment_id from list_event_comments.

Inputs: comment_id (required), event_uuid (required), calendar_id (required). Returns: message, success, deleted_comment_id

delete_event_occurrenceA
DestructiveIdempotent

Delete one occurrence of a recurring event, or that occurrence and all later ones (scope "this_and_following"), keeping the rest of the series. Use delete_event to delete the whole series. Get the series uuid and occurrence_start_at from get_events with start_before set. Deleting from the first occurrence onward deletes the whole series. Cannot be undone.

Inputs: event_uuid (required), calendar_id (required), occurrence_start_at (required), scope. Returns: scope, message, success, series_uuid, +2 more

delete_memoA
DestructiveIdempotent

Delete a memo. Cannot be undone. Get memo_uuid from list_memos. Fails for regular events (use delete_event).

Inputs: memo_uuid (required), calendar_id (required). Returns: message, success, deleted_memo_uuid

delete_virtual_memberA
DestructiveIdempotent

Remove a virtual member from a calendar. Cannot be undone. Get virtual_member_uuid from get_calendar_virtual_members (the uuid, not the id).

Inputs: calendar_id (required), virtual_member_uuid (required). Returns: message, success, deleted_virtual_member_uuid

get_calendar_labelsA
Read-only

List the 10 color labels of a calendar with their IDs, names, colors, and order. Use the IDs as label_id when creating or filtering events; rename or recolor them with update_calendar_labels.

Inputs: calendar_id (required). Returns: total, labels, calendar_id

get_calendar_membersA
Read-only

List the people who share a calendar (members with TimeTree accounts) with their user IDs, names, and roles. Use user_id for event attendees. For members without an account, such as children or pets, use get_calendar_virtual_members.

Inputs: calendar_id (required), include_deactivated. Returns: total, members, calendar_id

get_calendar_virtual_membersA
Read-only

List the virtual members of a calendar: people or things without a TimeTree account, such as a child, pet, or car, that events can be assigned to. Returns id (for virtual_user_attendees on events) and uuid (to update or delete the member). For members with accounts use get_calendar_members.

Inputs: calendar_id (required), include_deactivated. Returns: total, calendar_id, virtual_members

get_current_userA
Read-only

Return the signed-in TimeTree user's user ID and name. Use it to find "me" among calendar members (get_calendar_members), event attendees, comment authors, and activity.

Inputs: no named parameters. Returns: name, user_id

get_event_comment_imageA
Read-only

View one image attached to an event comment, including images posted by free accounts. Get comment_id and image_index from list_event_comments. Returns image content directly, without saving a file. Supports JPEG, PNG, GIF, and WebP up to 5 MiB. Premium event file attachments are not supported.

Inputs: comment_id (required), event_uuid (required), calendar_id (required), image_index. Returns: width, height, filename, byte_size, +5 more

get_eventsA
Read-only

Find events in a calendar by start time range, keyword, or label, sorted by start time. Use this to answer "what is on my schedule"; use get_updated_events or get_recent_activity for "what changed". Reads every page of the calendar, then filters; limit applies after sorting. Memos are included unless include_memos is false (list_memos returns only memos). When start_before is set, recurring events are expanded into each occurrence in the range. Occurrences share the series uuid, so update_event changes the whole series; use update_event_occurrence or delete_event_occurrence with the occurrence start_at to change one.

Inputs: calendar_id (required), limit, query, label_id, +4 more. Returns: total, events, calendar_id, total_fetched, +2 more

get_holidaysA
Read-only

Look up public holidays and observances for up to 5 countries in a date range of up to 2 years, sorted by date. day_off tells whether it is a day off. These are national holidays, not events in your calendars (use get_events for those).

Inputs: end_date (required), start_date (required), country_iso (required), days_off_only. Returns: total, holidays

get_recent_activityA
Read-only

See who recently created, changed, or deleted events and memos in a calendar, newest first (created, title/date/label/note/location/reminder/URL/checklist updated, deleted), with member names. TimeTree keeps only the last few activities per event, so this is a recent feed, not full history. Use get_updated_events for the current content of changed events.

Inputs: calendar_id (required), limit, since. Returns: total, events, calendar_id

get_updated_eventsA
Read-only

List events and memos changed after a point in time, with their current content. Deleted ones are included with deleted: true. Use this to sync or review changes since a time; use get_recent_activity to see who changed what, and get_events to look up a schedule. Recurring events are returned once, not expanded.

Inputs: calendar_id (required), updated_after (required), limit. Returns: total, events, calendar_id, total_fetched, +1 more

list_calendarsA
Read-only

List your active TimeTree calendars with their IDs, names, and members. Call this first: every other tool needs a calendar_id from here. Use the member names to pick a calendar when the user mentions a person (e.g., "events with [name]").

Inputs: no named parameters. Returns: total, calendars

list_event_commentsA
Read-only

List comments with their ids, author user IDs, and attached image metadata. Use get_event_comment_image to view an image. Only comments are returned, not change history; use get_recent_activity for who changed what.

Inputs: event_uuid (required), calendar_id (required). Returns: total, comments, event_uuid, calendar_id

list_memosA
Read-only

List the memos in a calendar: notes, lists, and checklists that are not scheduled events. Use get_events for events (it also includes memos unless include_memos is false). Optionally only memos updated after a time.

Inputs: calendar_id (required), limit, updated_after. Returns: memos, total, calendar_id

update_calendar_labelsA
DestructiveIdempotent

Rename or recolor calendar labels for everyone in the calendar, and return all labels. Only the labels you pass change; the others are read first and kept. Label IDs come from get_calendar_labels.

Inputs: labels (required), calendar_id (required). Returns: labels, message, success, calendar_id

update_eventA
DestructiveIdempotent

Change an event and return the updated event. Only provide the fields to change; array fields (attendees, alerts, recurrences, checklist, virtual attendees) replace the current values. For a recurring event this changes every occurrence; to change one occurrence or the ones after it, use update_event_occurrence. For memos use update_memo.

Inputs: event_uuid (required), calendar_id (required), url, note, +15 more. Returns: event, message, success

update_event_commentA
DestructiveIdempotent

Replace the text of an existing comment and return it. TimeTree lets only the comment's author edit it. Get comment_id from list_event_comments; use add_event_comment to post a new comment instead.

Inputs: content (required), comment_id (required), event_uuid (required), calendar_id (required). Returns: comment, message, success

update_event_occurrenceA
Destructive

Change one occurrence of a recurring event ("only this week"), or that occurrence and all later ones (scope "this_and_following", e.g. "from next month on"), keeping earlier occurrences as they are. Use update_event to change the whole series. Get the series uuid and occurrence_start_at from get_events with start_before set. Only provide the fields to change; start_at moves the occurrence and keeps its length unless end_at is given. scope "this" creates a separate event linked to the series (parent_id); "this_and_following" ends the series before the occurrence and starts a new series with a new uuid, or changes the whole series when it is the first occurrence.

Inputs: event_uuid (required), calendar_id (required), occurrence_start_at (required), url, +14 more. Returns: event, scope, result, message, +3 more

update_memoA
DestructiveIdempotent

Change a memo and return it. Only provide the fields to change; checklist and virtual attendees replace the current lists. Get memo_uuid from list_memos. Fails for regular events (use update_event).

Inputs: memo_uuid (required), calendar_id (required), url, note, +5 more. Returns: memo, message, success

update_virtual_memberA
DestructiveIdempotent

Change a virtual member's name, type, short description, or birthday, and return it. Only provide the fields to change. Get virtual_member_uuid from get_calendar_virtual_members (the uuid, not the id).

Inputs: calendar_id (required), virtual_member_uuid (required), name, type, +3 more. Returns: message, success, virtual_member

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 29 tools

    Disambiguation4/5

    Descriptions are unusually explicit about boundaries, repeatedly steering the agent between get_events, get_updated_events, get_recent_activity, and list_memos, and between update_event/update_event_occurrence/delete_event_occurrence. The remaining ambiguity is mostly the density of event-listing tools, but cross-references resolve it in practice.

    Naming Consistency4/5

    Almost all tools follow a clean snake_case verb_noun pattern (list_calendars, create_event, get_calendar_members, delete_virtual_member). Minor deviations: add_event_comment rather than create_, and get_event_comment_image mixed with list_event_comments, but the convention is still predictable.

    Tool Count3/5

    29 tools is heavy and above the comfortable range, though the domain genuinely spans events, memos, occurrences, comments, labels, members, virtual members, and holidays. Nearly every tool earns its place, but the surface is large enough to burden selection and could likely be consolidated.

    Completeness3/5

    Events, memos, comments, and virtual members have solid CRUD coverage, but there are notable gaps: only list/create for calendars (no update or delete calendar), no way to add/remove real members, and labels can be renamed/recolored but not created or deleted. Agents will hit dead ends on membership and calendar lifecycle operations.

    Maintenance

    ActivityMaintained
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers