io.github.da-the-dev/pim-mcp
Local MCP server for your calendars across Nextcloud, iCloud, Google and any CalDAV server.
Que pouvez-vous faire avec io.github.da-the-dev/pim-mcp ?
- 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.
Installation
Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).
pim-mcpclaude mcp add pim-mcp -- npx -y pim-mcp@0.1.0
{
"mcpServers": {
"pim-mcp": {
"command": "npx",
"args": [
"-y",
"pim-mcp@0.1.0"
]
}
}
}
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
Sommaire
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.
🧭 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 agent
pim-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 Travel
The 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 |
|---|---|
keychain:service/account | your OS secret store. Easiest: pim-mcp secret set service/account |
env:NAME | an environment variable |
cmd:<command> | a command's output, e.g. cmd:op read op://Private/iCloud/password, cmd:pass show icloud, cmd:bw get password icloud |
🍎 macOS: login Keychain
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.
🐧 Linux: Secret Service (GNOME Keyring / KWallet)
Needs secret-tool:
sudo apt install libsecret-tools # Debian / Ubuntu
sudo dnf install libsecret # Fedora
sudo pacman -S libsecret # Arch
On 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"
🪟 Windows: DPAPI
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 (any Nextcloud / ownCloud server)
- 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"
🍎 iCloud
- 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 (one-time OAuth setup)
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-secret pim-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"
🌐 Any other CalDAV server
[[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-mcp
Claude Desktop, Cursor and other GUI clients. Add this to the client's MCP config:
🍎 macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
"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.
🪟 Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"pim": { "command": "cmd", "args": ["/c", "npx", "-y", "pim-mcp"] }
}
}
npx is a batch script on Windows, so it runs through cmd /c.
🐧 Linux
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 |
|:-:|---|---|
| 📚 | list_calendars | All calendars and their ids (icloud/work). Anywhere a tool takes a calendar, a plain name works too. |
| 🗓️ | list_events | Events from all calendars in a range, merged and sorted. Defaults to today through the next 7 days. |
| 🔎 | search_events | Text search over title, location and description. |
| 📄 | get_event | Full details: description, attendees, organizer, recurrence rule. |
| 🕐 | find_free_time | Free windows of at least N minutes, optionally within working hours. |
| ➕ | create_event | Timed or all-day, with recurrence, a reminder, and busy/free status. |
| ✏️ | update_event | Changes only the fields you pass. Recurring events take scope: instance or series. |
| 🗑️ | delete_event | Off unless allow_delete = true. |
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 all
- Refusals 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 | nextcloud · https://<host>/remote.php/dav |
| iCloud | ✅ tested | icloud · app-specific password |
| Google Calendar | 🧪 beta | google · OAuth. Not yet tried with a real account; reports welcome |
| Fastmail | 🟡 untested | caldav · https://caldav.fastmail.com/ |
| Yahoo | 🟡 untested | caldav · https://caldav.calendar.yahoo.com |
| mailbox.org | 🟡 untested | caldav · https://dav.mailbox.org/ |
| Posteo | 🟡 untested | caldav · https://posteo.de:8443/ |
| Radicale · Baïkal · SOGo · Synology | 🟡 untested | caldav · your server's DAV URL |
| 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
- [x] Calendars over CalDAV: Nextcloud, iCloud, Google, generic
- [x] 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.
MIT © Aleksey Tkachenko · built for agents, readable by humans
Questions fréquentes
Qu'est-ce que io.github.da-the-dev/pim-mcp ?
Local MCP server for your calendars across Nextcloud, iCloud, Google and any CalDAV server.
Comment installer io.github.da-the-dev/pim-mcp ?
Il s'exécute sur votre machine. Dans Claude Code : claude mcp add pim-mcp -- npx -y pim-mcp@0.1.0. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.
Faut-il une clé API pour io.github.da-the-dev/pim-mcp ?
Son entrée au registre n'indique aucune clé ni secret obligatoire. Certaines fonctions peuvent tout de même demander un compte auprès du service auquel il se connecte.
io.github.da-the-dev/pim-mcp est-il open source ?
Oui. Son code est sur GitHub sous licence MIT.
Qui maintient io.github.da-the-dev/pim-mcp ?
Il est publié par da-the-dev. AI.tn le référence sans le maintenir ni le recommander.
Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.