Apple Calendar MCP
Provides read and write access to Apple Calendar for an Apple Account, enabling tools to manage calendars, events, availability, and invitations.
Allows remote read and write access to one iCloud Calendar account, including listing calendars, searching and managing events, checking availability, and responding to invitations.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
iCloud Calendar MCP
Give Claude, ChatGPT, and other compatible AI assistants remote read and write access to your iCloud calendars.
iCloud 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.
Features
Remote calendar access from anywhere. Connect compatible AI clients over HTTPS using a Cloudflare
workers.devaddress 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
Compared with OpenAI's iCloud Calendar connector
This is an independent MCP server that you deploy in your own Cloudflare account and connect to compatible AI clients. OpenAI also offers an iCloud Calendar connector for ChatGPT.
In the tool catalog reviewed in November 2026, OpenAI's connector accepts text locations. This server also accepts verified latitude and longitude so Apple Calendar can display a map preview. It provides dedicated availability queries and batch event reads. OpenAI's connector includes contact lookup and attachment management, which this server does not expose.
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
Open account.apple.com and sign in.
Select Sign-In and Security > App-Specific Passwords.
Select Generate an app-specific password.
Give it a clear label, such as
iCloud Calendar MCP.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
Select Deploy to Cloudflare at the top of this page.
Sign in to Cloudflare and follow the deployment form.
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.
Change
CALENDAR_TIME_ZONEfromUTCto your IANA time zone name. Cloudflare cannot detect your time zone automatically.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.
Keep the deploy command
bunx wrangler deploy --config wrangler.jsoncfor this dashboard workflow. Deploy the Worker and wait for the deployment to finish.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
Add the deployed
/mcpendpoint as a custom remote MCP server or app.Select Connect. Your client should discover OAuth and open the iCloud Calendar MCP approval page.
Confirm the client name and requested permission.
Enter
APPROVAL_PASSWORDand select Allow and return. Select Cancel if the page asks for more access than you want.Wait for the client to report that the connection is complete. Close the browser tab if it remains open after completion.
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.
Write actions involving attendees or invitations can send email or notifications to other people.
Verify the connection
Verify read access first:
Call
calendar_get_profile. Confirm the Apple Account identity and time zone.Call
calendar_list_calendars. Confirm that the expected calendar names appear.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:
Create one future event with a unique title, no attendees, no recurrence, and no alerts.
Read the event and keep its current ETag.
Change only its title by using that ETag.
Read the event again and use the returned ETag to delete it.
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 |
|
| Return the configured iCloud account identity and default time zone. |
|
| List visible calendars, effective time zones, and opaque IDs. |
|
| Search a bounded time range across calendars. |
|
| List a bounded time range from one calendar. |
|
| Read full event details and the current ETag. |
|
| Read up to 20 events with per-event errors. |
|
| Return merged busy windows without event details. |
|
| Create timed, all-day, recurring, invited, located, or alerted events. |
|
| Change one occurrence, this and later occurrences, or an entire series. |
|
| Delete one occurrence, this and later occurrences, or an entire series. |
|
| Accept, decline, or tentatively accept an invitation. |
List and search results include total, offset, hasMore, and nextOffset. Continue with nextOffset until hasMore is false for a complete schedule. Queries span at most 366 days. Concurrent calendar changes can shift offsets between pages.
Update and delete require explicit updateScope for recurring events. One-time events can omit it.
A mutation error can return JSON text with write_outcome_unknown or write_succeeded_readback_failed, the operation, and recoverable calendar and event IDs. Read that resource before retrying. The latter means iCloud acknowledged the write, so do not repeat it. A repeated create call can make a duplicate.
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:
Open the Worker in Cloudflare.
Select Settings > Domains & Routes > Add > Custom Domain and add the hostname.
Under Variables and Secrets, add
MCP_HOSTNAMEas a plain-text variable. Enter only the hostname, such ascalendar.example.com. Do not includehttps://, a path, a port, or credentials.Deploy the setting.
Connect clients again at
https://<custom-host>/mcpand 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.
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.
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 | 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 | 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
401or 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
/mcpusually has a missing or invalidMCP_HOSTNAME. Set the exact hostname and redeploy.An approval page that fails closed has neither
APPROVAL_PASSWORDnor a declared external guard. Add the approval secret unless you have already verified Cloudflare Access on/authorize.
Update an existing dashboard-managed Worker
Use bun run deploy:existing when Cloudflare's dashboard owns the Worker's configuration. Set CLOUDFLARE_API_TOKEN (Workers Scripts edit permission), CLOUDFLARE_ACCOUNT_ID, and WORKER_NAME in your shell or Cloudflare Builds environment. Keep the token secret.
bun install --frozen-lockfile
bun run deploy:existingFor Cloudflare Builds, connect this repository to the existing Worker, select your production branch, and use bun run deploy:existing as the deploy command. The build uses cf deploy --dry-run, checks that the named Worker exists and has the same compatibility date and flags as cloudflare.config.ts, then uploads only the bundled code through Cloudflare's content-only endpoint. It does not apply the config file's bindings, variables, secrets, routes, or domains. OAuth KV data and dashboard configuration stay in place. No private source repository is required.
This command cannot create or rename a Worker. If runtime settings differ, update the dashboard deliberately before retrying. A successful upload confirms Cloudflare accepted the code; verify the MCP connection after deployment. Use the workflow below when creating a Worker or managing its configuration in source.
Develop and deploy with cf
Use Node.js 22.23+, 24.22+, or 26.12+ and Bun. The project pins the Cloudflare CLI (cf) and uses cloudflare.config.ts for local development, tests, and CLI deployments. cf is in beta.
bun install
cp .dev.vars.example .dev.vars
bun run lint
bun run test
bun run typecheck
bun run cloudflare:checkOxlint and vendored anti-slop rules run with bun run lint and in CI. Rule provenance and adaptations explain the boundary and formatting exceptions.
Keep .dev.vars local. Run bun run cloudflare:dev for local development.
Before deploying with cf, sign in with bunx cf auth login and configure cloudflare.config.ts for your deployment. Set the time zone, existing OAuth KV namespace ID, and any custom domain or external authorization settings. cf treats this file as the configuration source and does not support Wrangler's keep_vars; copy dashboard settings into the file before switching an existing deployment. Keep secret values in Cloudflare and retain their bindings.secret() declarations. Run bun run cloudflare:check, then bun run deploy.
The Deploy to Cloudflare button retains wrangler.jsonc as its dashboard setup template. For that workflow, keep the deploy command bunx wrangler deploy --config wrangler.jsonc; it preserves dashboard variables. The CLI workflow uses cf and cloudflare.config.ts instead. Keep shared runtime defaults in both configurations aligned.
License
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Connect Apple iCloud and Microsoft 365 mail, calendars, contacts and tasks to AI.
Let your agent into iCloud Mail, calendar and contacts. It gets actions, never your password.
Sync Google, Outlook, and iCloud calendars and manage events, availability, and booking links.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables users to view and create events in their iCloud Calendar using natural language through supported LLMs. It integrates with Apple's infrastructure via app-specific passwords to provide secure calendar management.1-
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to access and interact with macOS Calendar.app events and reminders, including viewing, searching, and filtering calendar data.30 PyPI2MIT
- AlicenseNot gradedqualityBmaintenanceEnables calendar management with iCloud through CalDAV, allowing users to list, create, update, and delete events via a standardized API.280 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables compatible AI assistants to remotely read and write iCloud calendars with configurable permissions. Supports event search, availability checks, creation, editing, deletion, invitation responses, time zones, recurring schedules, and map-ready locations.28 npmMIT