iCloud Reminders and Calendar MCP Server
Lets Claude read and manage your iCloud Reminders and Calendar through a custom MCP connector, enabling natural language queries and actions.
README
iCloud Reminders and Calendar MCP Server
Lets Claude read and manage your iCloud Reminders and Calendar through a custom MCP connector — ask Claude "what's on my groceries list" or "add milk and eggs" or "What do I need to do today" from any Claude client, including the iPhone app.
Architecture
Claude (iPhone/desktop/web)
| HTTPS + API key
v
Anthropic's cloud infrastructure
| HTTPS
v
EC2 instance (Caddy: auto HTTPS via sslip.io + Let's Encrypt)
| localhost
v
Python MCP server (this repo)
| CalDAV
v
iCloud (your Reminders)
Custom MCP connectors are reached by Anthropic's cloud, not by your device directly — so the server has to be genuinely public, not just reachable on your home network. This deployment gets that for $0/month (within AWS free tier) using:
- EC2 free tier (750 hrs/month for 12 months) instead of a paid VPS
- sslip.io for a free "domain" (no purchase, no signup) instead of a real registered domain
- Caddy for free automatic HTTPS via Let's Encrypt
- CalDAV to talk to iCloud directly — no Mac, no AppleScript required
Why CalDAV instead of AppleScript
Apple Reminders has no public REST API. AppleScript works but only runs locally on a Mac. CalDAV is an open standard Apple also supports for Calendar/Reminders sync, reachable from any OS or cloud server with just an Apple ID and an app-specific password — which is what makes a Mac-free, cloud-hosted version of this possible at all.
Setup
1. Generate an app-specific Apple ID password
- Go to https://appleid.apple.com and sign in
- Sign-In and Security → App-Specific Passwords → generate one
- Save it — you'll need it in step 4. This is not your normal Apple ID password, and can be revoked independently at any time.
2. Launch an EC2 instance
- AWS Console → EC2 → Launch instance
- Choose Ubuntu Server (latest LTS), instance type t3.micro or t2.micro (free tier eligible)
- Create or select a key pair (for SSH access) — download the
.pemfile - Security group: allow inbound SSH (22) from your IP, and
HTTP (80) + HTTPS (443) from anywhere (
0.0.0.0/0) — port 80 is needed briefly for Let's Encrypt's verification, Caddy handles the rest - Launch it
3. Attach an Elastic IP (so the address doesn't change on reboot)
- EC2 → Elastic IPs → Allocate Elastic IP address
- Actions → Associate → select your instance
- Note this IP — you'll need it for the sslip.io hostname
4. SSH in and set up the server
ssh -i your-key.pem ubuntu@YOUR-ELASTIC-IP
sudo apt update
sudo apt install -y python3-venv python3-pip git
git clone https://github.com/YOUR_USERNAME/reminders-mcp.git
cd reminders-mcp
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
nano .env # fill in APPLE_ID, APPLE_APP_PASSWORD, and a generated MCP_API_KEY
Generate a strong API key with:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
5. Install and configure Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
Edit the Caddyfile to use your actual Elastic IP (dots replaced with
dashes), e.g. if your IP is 54.123.45.67:
sudo nano /etc/caddy/Caddyfile
54-123-45-67.sslip.io {
handle_path /REPLACE_WITH_YOUR_MCP_API_KEY/* {
reverse_proxy localhost:8787 {
header_up x-api-key "YOUR_MCP_API_KEY"
}
}
respond 404
}
sudo systemctl restart caddy
Caddy will automatically get a free HTTPS certificate for that hostname the first time it starts — no manual steps needed.
6. Set up the systemd service (so it survives reboots)
sudo cp reminders-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable reminders-mcp
sudo systemctl start reminders-mcp
sudo systemctl status reminders-mcp # confirm it's running
7. Test it's reachable
curl -i https://54-123-45-67.sslip.io/{YOUR_MCP_API_KEY}/mcp
{YOUR_MCP_API_KEY} will be extracted from the path and Caddy will inject it as a request header.
A response other than a connection error means it's working (a 406 here
is expected and fine — it just means the request wasn't a full valid MCP
handshake, which curl alone won't do).
8. Add the connector on claude.ai
Custom connectors can only be added via a browser or Claude Desktop — not from the iPhone app directly. Once added, it's usable everywhere, including mobile.
- Go to claude.ai → Customize → Connectors → "+" → Add custom connector
- Name:
iCloud Reminders - URL:
https://54-123-45-67.sslip.io/{YOUR_MCP_API_KEY}/mcp - Click Add, then enable it in a conversation
9. Use it from your iPhone
Open the Claude app, start a conversation, enable the connector from the "+" menu if it isn't already, and try:
- "What's on my Groceries list?"
- "Add milk and eggs to Groceries"
- "Mark milk as done on Groceries"
- "What do I need to do today?"
Tools this server exposes
| Tool | What it does |
|---|---|
list_reminder_lists() |
Names of all your iCloud Reminders lists |
get_pending_reminders(list_name) |
Incomplete items in a given list |
add_reminder(list_name, title) |
Adds a new reminder to an existing list |
complete_reminder(list_name, title) |
Marks an item done |
Note: add_reminder requires the list to already exist — create it once in
the Reminders app on any Apple device and it syncs to iCloud automatically.
Reliably creating brand-new top-level lists via CalDAV varies across iCloud
accounts, so it's left as a one-time manual step.
Security
- The server requires a valid
YOUR_MCP_API_KEYheader in every request path — without it, requests are rejected with 401. Treat this key like a password. - Your Apple app-specific password only grants limited access and can be revoked anytime from appleid.apple.com without touching your main password.
- The EC2 security group only allows inbound 22/80/443 — the MCP server's
actual port (8787) is only reachable via
localhost, through Caddy. - Never commit your real
.envfile —.gitignoreis already set up to exclude it. Only.env.example(placeholder values) should be in git.
Cost
Within the AWS Free Tier (first 12 months): $0/month.
- EC2 t3.micro/t2.micro: free (750 hrs/month covers 24/7 use)
- Elastic IP: free while attached to a running instance
- sslip.io hostname: free, no signup
- Let's Encrypt certificate via Caddy: free, auto-renewing
After free tier expires, EC2 alone runs roughly $7–9/month if left running continuously — stop the instance when not in use to avoid ongoing charges.
Troubleshooting
- Caddy fails to get a certificate → confirm port 80 is open in your security group (Let's Encrypt needs it briefly for verification), and that the sslip.io hostname matches your Elastic IP exactly.
- 401 Unauthorized from your own curl test → double-check the
YOUR_MCP_API_KEYin URLhttps://54-123-45-67.sslip.io/{YOUR_MCP_API_KEY}/mcpmatchesMCP_API_KEYin.envexactly, no trailing whitespace. - Service won't start →
sudo journalctl -u reminders-mcp -eto see the actual error; usually a missing/incorrect.envvalue. - Claude says the connector won't connect → confirm you can reach the HTTPS URL from a browser or curl first, before troubleshooting on the Claude side.
Next steps
- Add a Calendar tool (
get_todays_events) using the same CalDAV connection, so Claude can start combining "what's on my calendar" with "what's on my todo list" into a single daily briefing.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.