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.