pim-mcp
Connects to Google Calendar through the CalDAV API with OAuth (desktop client + stored refresh token), merging its calendars into the shared view for listing, searching, free-time finding, and event creation, update and deletion.
Connects to iCloud calendars over CalDAV using an Apple app-specific password, exposing them for merged event listing and search, free-time finding, and creating, updating or deleting events (with recurring-event scope handling).
Connects to a Nextcloud server over CalDAV (app-password auth), exposing its calendars for merged event listing and search, event details, free/busy time finding, and creating, updating or deleting events.
Connects to an ownCloud server over CalDAV alongside Nextcloud, making its calendars available for merged listing, search, free-time lookup and event creation, update and deletion.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pim-mcpFind me an hour Thursday afternoon and book the dentist"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
One thin, local MCP server for all your calendars. Nextcloud · iCloud · Google · any CalDAV, merged into a single view your agent can read and manage.
Quick start · Accounts · Connect · Tools · Guardrails · Providers · Contributing
you › Find me an hour on Thursday afternoon and put the dentist there.
agent › find_free_time start=Thu 12:00 end=Thu 18:00 duration_minutes=60
↳ 13:00–15:30 · 16:15–18:00
› create_event calendar="icloud/personal" title="Dentist" start=Thu 13:00
↳ ✓ created Thu 13:00–14:00 · icloud/personal
Done. Thursday 13:00 is booked; you're free again from 14:00.✨ Why
🗂️ One merged view Every calendar on every account in one sorted list, with recurring events expanded. No more "which account was that in?"
🧳 Portable One TOML file with no secrets in it. Secrets are references to your OS secret store, env vars or a password manager, so the same config works on every machine.
🪶 Thin and local Your agent client starts it over stdio when needed. Nothing runs in the background, there's no port open, and no cloud sits in between.
🛡️ Safe by default Deleting events and anything that emails other people stay off until you allow them. Edits never overwrite changes made elsewhere.
Related MCP server: Radicale CalDAV MCP Server
🧭 How it works
flowchart LR
A["🤖 Agent<br><sub>Claude Code · Claude Desktop · Cursor</sub>"] -- "MCP · stdio" --> P["<b>pim-mcp</b><br><sub>on your machine</sub>"]
S[("🔐 OS secret store<br><sub>Keychain · Secret Service · DPAPI</sub>")] -. "app passwords / tokens" .-> P
P -- CalDAV --> N["☁️ Nextcloud"]
P -- CalDAV --> I["🍎 iCloud"]
P -- "CalDAV + OAuth" --> G["📅 Google"]
P -- CalDAV --> O["🌐 any CalDAV"]🚀 Quick start
Requires Node.js 22+.
npm install -g pim-mcp # 1 · install (or prefix commands with `npx -y`)
pim-mcp init # 2 · write ~/.config/pim-mcp/config.toml
pim-mcp secret set pim-mcp/icloud # 3 · store an app password (prompted, not echoed)
pim-mcp check # 4 · verify every account
claude mcp add pim -s user -- npx -y pim-mcp # 5 · connect your agentpim-mcp check lists what it found:
✓ nextcloud (nextcloud) — 3 calendar(s)
nextcloud/personal Personal
nextcloud/work Work
✓ icloud (icloud) — 2 calendar(s)
icloud/family Family
icloud/travel TravelThe config lives at ~/.config/pim-mcp/config.toml on every OS (C:\Users\<you>\.config\pim-mcp\config.toml on Windows). Set PIM_MCP_CONFIG to use another path.
🔐 Secrets
Passwords and tokens never go in the config. It holds a reference instead:
Reference | Resolves to |
| your OS secret store. Easiest: |
| an environment variable |
| a command's output, e.g. |
Stored as generic passwords in your login Keychain. You can also manage them in Keychain Access, or with security add-generic-password -s pim-mcp -a icloud -w.
Needs secret-tool:
sudo apt install libsecret-tools # Debian / Ubuntu
sudo dnf install libsecret # Fedora
sudo pacman -S libsecret # ArchOn a headless machine there's usually no keyring running. Use env: refs (set them in your MCP client's env block) or pass:
password = "cmd:pass show pim-mcp/icloud"Secrets are encrypted with DPAPI, the per-user encryption Credential Manager also uses. They're stored under %APPDATA%\pim-mcp\secrets\, and only your Windows user on this machine can decrypt them. Nothing to install. cmd: refs run in cmd.exe.
👤 Accounts
Nextcloud → Settings → Security → Devices & sessions → Create new app password
pim-mcp secret set pim-mcp/nextcloud
[[accounts]]
id = "nextcloud"
provider = "nextcloud"
url = "https://your.next.cloud/remote.php/dav"
username = "your-login"
password = "keychain:pim-mcp/nextcloud"account.apple.com → Sign-In and Security → App-Specific Passwords
pim-mcp secret set pim-mcp/icloud
[[accounts]]
id = "icloud"
provider = "icloud"
username = "you@icloud.com" # the email you sign into your Apple Account with
password = "keychain:pim-mcp/icloud"Google only allows OAuth for CalDAV:
Google Cloud Console: create a project and enable the CalDAV API.
OAuth consent screen: choose External and add yourself as a test user. Then set the publishing status to In production, because tokens issued in "Testing" mode expire after 7 days. An "unverified app" warning at sign-in is expected for a personal app.
Credentials → Create OAuth client ID → Desktop app. Put the client ID in the config and store the secret:
pim-mcp secret set pim-mcp/google-client-secretpim-mcp auth google --account googleopens your browser and stores the refresh token in your OS secret store.
[[accounts]]
id = "google"
provider = "google"
username = "you@gmail.com"
client_id = "xxxx.apps.googleusercontent.com"
client_secret = "keychain:pim-mcp/google-client-secret"
refresh_token = "keychain:pim-mcp/google"[[accounts]]
id = "fastmail"
provider = "caldav"
url = "https://caldav.fastmail.com/"
username = "you@fastmail.com"
password = "keychain:pim-mcp/fastmail"Known URLs are in Providers.
🔌 Connect your agent
Claude Code (any OS)
claude mcp add pim -s user -- npx -y pim-mcpClaude Desktop, Cursor and other GUI clients. Add this to the client's MCP config:
{
"mcpServers": {
"pim": { "command": "npx", "args": ["-y", "pim-mcp"] }
}
}GUI apps don't always see your shell's PATH. If the server fails to start, replace npx with the full path from which npx, e.g. /opt/homebrew/bin/npx.
{
"mcpServers": {
"pim": { "command": "cmd", "args": ["/c", "npx", "-y", "pim-mcp"] }
}
}npx is a batch script on Windows, so it runs through cmd /c.
Claude Desktop isn't available for Linux; use Claude Code or another MCP client with the same command / args as macOS. env: refs go in the client's env block:
"pim": {
"command": "npx",
"args": ["-y", "pim-mcp"],
"env": { "ICLOUD_PASSWORD": "…" }
}🧰 Tools
Tool | What it does | |
📚 |
| All calendars and their ids ( |
🗓️ |
| Events from all calendars in a range, merged and sorted. Defaults to today through the next 7 days. |
🔎 |
| Text search over title, location and description. |
📄 |
| Full details: description, attendees, organizer, recurrence rule. |
🕐 |
| Free windows of at least N minutes, optionally within working hours. |
➕ |
| Timed or all-day, with recurrence, a reminder, and busy/free status. |
✏️ |
| Changes only the fields you pass. Recurring events take |
🗑️ |
| Off unless |
What agents see:
Times without an offset are in your configured
timezone.Output is ISO 8601 with offsets.
All-day events use
YYYY-MM-DD, and their end date is inclusive.
🛡️ Guardrails
timezone = "Europe/Amsterdam" # default: the system timezone
[guardrails]
allow_delete = false # delete_event is refused
allow_invites = false # no adding attendees, no editing/deleting events that have them
[[accounts]]
# …
read_only = true # no writes to this account at all
read_only_calendars = ["Family"] # protect specific calendars
hide_calendars = ["Birthdays"] # don't show these at allRefusals explain themselves. When a guardrail blocks something, the agent is told which setting would allow it, so it asks you instead of retrying.
No lost edits. Every write checks the event's ETag. If the event changed elsewhere since it was read, the write fails instead of overwriting.
🌍 Providers
Provider | Status | Setup |
Nextcloud / ownCloud | ✅ tested |
|
iCloud | ✅ tested |
|
Google Calendar | 🧪 beta |
|
Fastmail | 🟡 untested |
|
Yahoo | 🟡 untested |
|
mailbox.org | 🟡 untested |
|
Posteo | 🟡 untested |
|
Radicale · Baïkal · SOGo · Synology | 🟡 untested |
|
Outlook · Microsoft 365 · Exchange | 🚧 wanted | no CalDAV; needs a Microsoft Graph backend |
Proton Calendar | ❌ n/a | no CalDAV or public API |
🟡 untested means standard CalDAV that should just work but hasn't been confirmed with pim-mcp yet. Tried one? A PR updating this table is very welcome.
🗺️ Roadmap
Calendars over CalDAV: Nextcloud, iCloud, Google, generic
macOS · Linux · Windows secret stores
Outlook / Microsoft 365 via Microsoft Graph
Mail: IMAP / SMTP, same accounts and config
Files: WebDAV (Nextcloud, …)
🤝 Contributing
New providers, bug fixes and "it works with X" confirmations are all welcome. See CONTRIBUTING.md for dev setup, a throwaway local CalDAV server for testing, and how to add a provider.
Related MCP Connectors
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Sync Google, Outlook, and iCloud calendars and manage events, availability, and booking links.
Manage Google, Outlook & Apple calendars and create private sync rules from chat.
Scheduling infrastructure for AI agents across Google and Microsoft calendars.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceEnables interaction with any CalDAV-compatible calendar server (Yandex, Google, Nextcloud, iCloud, etc.) to list calendars, create/manage events with reminders and attendees, search events, and handle recurring events through natural language.15-
- FlicenseNot gradedqualityCmaintenanceEnables LLM agents to read, schedule, update, and delete calendar events and tasks on a self-hosted CalDAV server, and to query availability for free/busy slots.-
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to connect to calendar servers and manage events and tasks, including listing calendars, querying timeframes, creating, updating, completing, and deleting items through tools.307 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to connect to CalDAV servers and manage calendars, events, and tasks through tools for listing, creating, updating, completing, and deleting items.307 npmMIT