Skip to content

Apple Calendar MCP Server

Overview

Provides an MCP server (buddai-calendar) that synchronises an iCloud/CalDAV calendar into MongoDB, generates sentence embeddings, and exposes tools for reading, semantic searching, and creating calendar events. It is packaged as the Docker image buddai/mcp-apple-calendar, launched with apple-calendar.mcp.yml over STDIO.

Components

  • index.js – boots the MCP server and registers the four tools exposed to clients.
  • calendar.js – high-level orchestration of CalDAV sync, semantic search, and event creation.
  • calDav.js – handles CalDAV login with tsdav, runs the sync loop, and writes calendars/events into MongoDB.
  • mongo.js – MongoDB helper: stores calendars in calendars, events in events, manages vector-search indexes, and feeds data back to the tools.
  • sync.js – end-to-end sync pipeline that calls updateCalendars, (re)creates indexes, and backfills embeddings for pending events.
  • embeddings.js / models/ – loads the local ONNX model nomic-embed-text-v1.5 (via @xenova/transformers) and normalises vectors for semantic search.
  • calendarUtils.js, utils.js – recurrence expansion, alarm flattening, and field normalisation helpers.
  • Dockerfile – multi-stage Node 22 build; ships compiled dependencies plus the models/ directory and runs node index.js as user mcp.

Exposed MCP tools

ToolPurposeInput
createCalendarEventCreates an event in the first iCloud calendar via CalDAV, generating a fresh .ics.summary, start, end, optional location, description (ISO strings).
getCalendarEventsBetweenDatesReturns all events (including recurrences) between two ISO strings.startDate, endDate, optional timezone (defaults Europe/Madrid).
searchCalendarEventsBySemanticVector search over summary/location/description, constrained to a date window.prompt, optional start, end, timezone.
updateEventsToDBFull resync: fetches events from CalDAV, stores them in MongoDB, and recomputes embeddings.none

Events are stored in events with Agenda-style metadata plus:

  • __raw (original VEVENT payload), rrule, recurrenceId when applicable.
  • embedding (768-dim float array) when syncCalendarsToMongo has processed the entry.
  • vectorSearchOnSummaryDescriptionLocation Atlas Search index for semantic retrieval.

Configuration

Environment variables consumed by the service:

  • APPLE_ID / APPLE_PASSWORD – primary credentials used by tsdav during sync.
  • ICLOUD_USERNAME / ICLOUD_PASSWORD – optional overrides used by createCalendarEvent; defaults fall back to the previous pair.
  • CALDAV_SERVER_URL – optional CalDAV endpoint (defaults to https://caldav.icloud.com).
  • MONGO_URI – connection string. Collections are created in the default database.
  • DEBUG – enable diagnostics with namespaces like mcp_calendar:*.

The apple-calendar.mcp.yml host definition injects these variables and runs the container on the shared buddai_net Docker network:

yaml
apple-calendar:
  transport: stdio
  command: docker
  args:
    - run
    - --init
    - -i
    - --rm
    - --network
    - buddai_net
    - -e
    - APPLE_ID
    - -e
    - APPLE_PASSWORD
    - -e
    - MONGO_URI
    - -e
    - DEBUG
    - buddai/mcp-apple-calendar
  env:
    DEBUG: "*"
    APPLE_ID: "${APPLE_ID}"
    APPLE_PASSWORD: "${APPLE_PASSWORD}"
    MONGO_URI: "${MONGO_URI}"

Set matching variables in the host runtime (e.g. .env).

MongoDB must support Atlas Search / vector search (Atlas or a replica set with search enabled). The embeddings loader expects the ONNX model to exist in models/; run download_model.sh before building if the folder is empty.

Running locally

  1. Install Node.js ≥ 20.
  2. npm install to fetch runtime deps (install will pull @xenova/transformers).
  3. Populate .env with APPLE_ID, APPLE_PASSWORD, MONGO_URI, DEBUG=mcp_calendar:*.
  4. Download the embedding model: ./download_model.sh (downloads to models/).
  5. Start MongoDB (replica set/Atlas) and run node index.js to expose the MCP STDIO server.
  6. (Optional) Run node sync.js or call the updateEventsToDB tool to trigger the CalDAV sync and embedding pipeline.

Docker usage

Build the image expected by the MCP host:

bash
docker build -t buddai/mcp-apple-calendar mcp_servers/calendarTool

To emulate the host configuration:

bash
docker network create buddai_net                # once per host
docker run --rm --init -i \
  --network buddai_net \
  -e APPLE_ID=your@icloud.com \
  -e APPLE_PASSWORD=app-specific-pass \
  -e MONGO_URI=mongodb+srv://.../calendars \
  -e DEBUG=mcp_calendar:* \
  buddai/mcp-apple-calendar

This exposes the MCP server over STDIO for integration with a MultiServer MCP host.

Development notes

  • syncCalendarsToMongo regenerates indexes and embeddings on each run; ensure Atlas Search quotas allow index creation.
  • models/ contains large binary assets and is required at runtime; keep them in sync with the embedding code.
  • Tests under test_*.js are out of date; they reference legacy helpers and will fail. Replace them with targeted MCP tool tests when updating the service.
  • The service assumes CalDAV credentials have access to at least one calendar; it currently uses the first calendar returned by the DAV client when creating events.

Troubleshooting

  • No events returned: confirm syncCalendarsToMongo ran successfully and the events collection contains VEVENT data.
  • Vector search empty: MongoDB must support $vectorSearch; ensure the Atlas Search index vectorSearchOnSummaryDescriptionLocation exists and embeddings are populated.
  • CalDAV login failure: verify that APPLE_ID has an app-specific password and 2FA is configured for the iCloud account.
  • Create event errors: set ICLOUD_USERNAME/ICLOUD_PASSWORD if they differ from APPLE_ID credentials, and ensure the account includes at least one writable calendar.