Skip to main content
Glama
nweii
by nweii

Apple Calendar MCP

Give Claude, ChatGPT, and other compatible AI assistants remote read and write access to your iCloud calendars.

Apple Calendar MCP runs headlessly in your own Cloudflare account. You don't need a Mac or another computer hosting a local MCP server. Each deployment serves one Apple Account.

Deploy to Cloudflare

Features

  • Remote calendar access from anywhere. Connect compatible AI clients over HTTPS using a Cloudflare workers.dev address or your own custom domain.

  • Self-hosted and under your control. Runs in your Cloudflare account. You control the server, credentials, and which clients can access your calendars.

  • Configurable permissions. Give each client read-only access to search events and check availability, or write access to create, edit, and delete events and respond to invitations.

  • Locations with Apple Calendar map previews. Events created or edited by an AI assistant can include a place name, address, and verified coordinates so Apple Calendar displays its map preview.

  • Time zones and recurring schedules. Create one-off or recurring events with time zone support, notes, URLs, and alerts.

For guided setup, use the agent setup prompt.

Related MCP server: calendar-app-mcp

Before you deploy

You need:

  • A Cloudflare account.

  • An Apple Account with two-factor authentication.

  • An MCP client that supports remote HTTPS servers and OAuth.

  • Your IANA time zone name, such as America/New_York.

An agent can guide you and verify setup without knowing your passwords. Sign in to Apple yourself and enter the app-specific password and approval password directly in Cloudflare.

Create an Apple app-specific password

  1. Open account.apple.com and sign in.

  2. Select Sign-In and Security > App-Specific Passwords.

  3. Select Generate an app-specific password.

  4. Give it a clear label, such as Apple Calendar MCP.

  5. Keep the generated value on the Apple page until Cloudflare asks for it.

Changing or resetting your main Apple Account password revokes all app-specific passwords. See Apple's instructions for generating and revoking them.

Apple doesn't let you restrict an app-specific password to Calendar. This server uses it only to access your calendars.

Deploy to Cloudflare

  1. Select Deploy to Cloudflare at the top of this page.

  2. Sign in to Cloudflare and follow the deployment form.

  3. Fill in the secret fields:

    • ICLOUD_USERNAME: the full email address used for your Apple Account and iCloud Calendar.

    • ICLOUD_APP_PASSWORD: the app-specific password that Apple generated.

    • APPROVAL_PASSWORD: a separate password for approving client connections. Choose one you don't use for Apple.

  4. Change CALENDAR_TIME_ZONE from UTC to your IANA time zone name. Cloudflare cannot detect your time zone automatically.

  5. Turn off Protect with Cloudflare Access. The built-in approval page handles client connections; that toggle can block them. To use Access instead, follow Add Cloudflare Access after deployment.

  6. Deploy the Worker and wait for the deployment to finish.

  7. Copy the endpoint in this form: https://<worker-name>.<account-subdomain>.workers.dev/mcp.

Cloudflare stores these values as encrypted secrets, outside the generated repository.

If you skipped a secret or need to replace one, open Workers & Pages, select the Worker, select Settings, find Variables and Secrets, add or edit the value as a Secret, and select Deploy.

Cloudflare creates OAUTH_KV automatically to store client registrations and authorizations. It does not store calendar events.

Connect an MCP client

  1. Add the deployed /mcp endpoint as a custom remote MCP server or app.

  2. Select Connect. Your client should discover OAuth and open the Apple Calendar MCP approval page.

  3. Confirm the client name and requested permission.

  4. Enter APPROVAL_PASSWORD and select Allow and return. Select Cancel if the page asks for more access than you want.

  5. Wait for the client to report that the connection is complete. Close the browser tab if it remains open after completion.

  6. Refresh or rescan the client's tools. Clients can cache tool catalogs after a connection or server update.

For Claude, see Use custom connectors with remote MCP. For ChatGPT, see Developer mode and full MCP connectors.

The approval page offers two permissions:

  • Read calendars and events enables the seven read tools.

  • Read and edit calendars and events also enables creation, editing, deletion, and invitation responses.

To change a client's permission, authorize it again and refresh its tools.

WARNING

Write actions involving attendees or invitations can send email or notifications to other people.

Verify the connection

Verify read access first:

  1. Call calendar_get_profile. Confirm the Apple Account identity and time zone.

  2. Call calendar_list_calendars. Confirm that the expected calendar names appear.

  3. If you approved read-only access, confirm that the client does not show mutation tools.

A successful calendar read confirms that the Apple credential works. Connecting the client alone does not.

To test writes, create an empty temporary calendar in Apple Calendar and ask the agent to:

  1. Create one future event with a unique title, no attendees, no recurrence, and no alerts.

  2. Read the event and keep its current ETag.

  3. Change only its title by using that ETag.

  4. Read the event again and use the returned ETag to delete it.

  5. Confirm that the event is absent.

Keep this test in the temporary calendar. If cleanup fails, have the agent give you the calendar, title, and time so you can remove the event yourself.

Tools

Tool

Scope

Purpose

calendar_get_profile

calendar:read

Return the configured iCloud account identity and default time zone.

calendar_list_calendars

calendar:read

List visible calendars, effective time zones, and opaque IDs.

calendar_search_events

calendar:read

Search a bounded time range across calendars.

calendar_list_events

calendar:read

List a bounded time range from one calendar.

calendar_get_event

calendar:read

Read full event details and the current ETag.

calendar_batch_get_events

calendar:read

Read up to 20 events with per-event errors.

calendar_get_availability

calendar:read

Return merged busy windows without event details.

calendar_create_event

calendar:write

Create timed, all-day, recurring, invited, located, or alerted events.

calendar_update_event

calendar:write

Change one occurrence, this and later occurrences, or an entire series.

calendar_delete_event

calendar:write

Delete one occurrence, this and later occurrences, or an entire series.

calendar_respond_to_invitation

calendar:write

Accept, decline, or tentatively accept an invitation.

Update, delete, and invitation-response tools require the latest ETag. Recurring occurrence changes also require the original recurrenceId returned by a search.

Timed inputs use RFC 3339 timestamps with Z or an explicit offset. Clients can omit timeZone; creation uses the calendar's published IANA time zone, then CALENDAR_TIME_ZONE. Timed outputs include UTC and local values.

location is the visible Calendar field. structuredLocation can add a title, address, latitude, longitude, and radius. Verified coordinates enable Apple Calendar's map preview. Do not guess coordinates.

description maps to Calendar Notes. url maps to the event URL field. The MCP preserves unsupported attachments and alarm types during unrelated changes, but it does not upload, download, or modify attachments. It does not import raw ICS.

Use a custom domain

The default workers.dev address works without extra configuration. To use your own domain:

  1. Open the Worker in Cloudflare.

  2. Select Settings > Domains & Routes > Add > Custom Domain and add the hostname.

  3. Under Variables and Secrets, add MCP_HOSTNAME as a plain-text variable. Enter only the hostname, such as calendar.example.com. Do not include https://, a path, a port, or credentials.

  4. Deploy the setting.

  5. Connect clients again at https://<custom-host>/mcp and complete authorization again.

Clients need to reconnect when you change the server's hostname.

Add Cloudflare Access

Cloudflare Access can replace the approval password. Configure it after deployment: the form's Previews only option does not protect your live server, while All traffic can block client connections.

To replace the approval password with Access, deploy the Worker first. Then create a path-based Access application for <hostname>/authorize.

Leave /mcp, /.well-known/*, /oauth/token, and /oauth/register reachable by MCP clients. When Access protects /authorize, add EXTERNAL_AUTHORIZATION=true as a plain-text Worker variable.

To use Access without an approval password, delete APPROVAL_PASSWORD only after you deploy EXTERNAL_AUTHORIZATION=true. If both settings exist, users must pass both checks.

WARNING

SetEXTERNAL_AUTHORIZATION=true only after Access protects /authorize. This setting disables the requirement for an approval password; it does not configure Access for you.

Security

This is a self-hosted deployment in your Cloudflare account. You control its code, secrets, and connected clients, and you can update or disable it yourself. The project maintainer does not operate your server or receive your credentials or calendar data.

The Worker uses your Apple username and app-specific password to connect to iCloud. Cloudflare stores the credentials as encrypted secrets and runs the code that processes calendar requests. Calendar data passes through your Worker to the AI clients you authorize; those clients receive calendar results, not your Apple password.

APPROVAL_PASSWORD protects new client connections. Approval is unavailable unless a password is configured or you enable the Access configuration described above. Anyone who can pass this check can connect a client to the configured Apple Account.

WARNING

RotatingAPPROVAL_PASSWORD does not revoke OAuth tokens that were already issued.

OAuth credentials are stored as hashes in KV, with authorization properties encrypted. Client names and permission records remain readable. See the OAuth provider's storage documentation for details.

The Worker sends Apple credentials only to approved iCloud Calendar hosts over HTTPS. Tool inputs cannot redirect those requests. Errors redact credentials, and the Worker does not log tool inputs or event contents.

Tool results can include titles, notes, locations, attendees, and URLs. MCP clients can retain this data under their own product and workspace policies.

Write access allows event creation, editing, deletion, and invitation responses. Updates check for newer edits before saving and preserve unsupported Apple properties when possible. Changes involving attendees can send notifications.

Review source changes before deploying updates, and connect only AI clients you trust.

Revoke or rotate access

Goal

Action

Result

Stop one client

Disconnect or remove it in that client's settings. Use its revoke flow when available.

The client stops using its connection.

Stop new approvals

Rotate APPROVAL_PASSWORD or disable the Worker.

Existing OAuth tokens are unaffected.

Stop all Apple access immediately

Disable the Worker and revoke its app-specific password at account.apple.com.

Calendar calls fail until you configure a new app-specific password.

Rotate normally

Create a new Apple app-specific password, replace ICLOUD_APP_PASSWORD in Cloudflare, verify a read call, then revoke the old password.

You verify the replacement before revocation and avoid downtime.

Recover after an Apple Account password reset

Create a new app-specific password and replace the Worker secret.

Apple already revoked the old app-specific password.

If you suspect compromise, revoke the old Apple app-specific password first. Then replace it and verify access. This causes a short outage.

Troubleshooting

  • A 401 or iCloud password rejection usually means that the app-specific password is missing or revoked. Create or replace it in Apple and Cloudflare.

  • Missing write tools usually mean that the client has a read-only grant or a cached tool catalog. Refresh tools, then disconnect and authorize again if needed.

  • A custom domain that rejects /mcp usually has a missing or invalid MCP_HOSTNAME. Set the exact hostname and redeploy.

  • An approval page that fails closed has neither APPROVAL_PASSWORD nor a declared external guard. Add the approval secret unless you have already verified Cloudflare Access on /authorize.

Develop locally

bun install
cp .dev.vars.example .dev.vars
bun run test
bun run typecheck
bun run cloudflare:check

Keep .dev.vars local. Deploy with bun run deploy.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables calendar management with iCloud through CalDAV, allowing users to list, create, update, and delete events via a standardized API.
    38 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides AI calendar operators full iCloud Calendar access through CalDAV, with two-factor authentication and app-specific passwords.
    MIT