Pim Mcp

io.github.da-the-dev由 GitHub 账号 da-the-dev 发布v0.2.0更新于 Nov 6, 2026

Local MCP server for your calendars across Nextcloud, iCloud, Google and any CalDAV server.

已验证STDIO仅桌面效率与工作流沟通与协作

概览

AI 生成的概览

本地 MCP 服务器,把 Nextcloud、iCloud、Google 及其他 CalDAV 日历合并,让助手读取、搜索、新建、修改和删除日程。

可以做什么
  • 列出所有已配置账户的日历与日程,合并排序并展开重复日程
  • 按标题、地点或描述搜索日程,并查看单个日程的完整详情
  • 在所有或指定日历中查找满足时长要求的空闲时段
  • 新建和修改定时或全天日程,支持重复规则、提醒和忙闲状态
  • 删除日程,需匹配标题,并受账户级和日历级保护设置约束
适用场景
适合在多个 CalDAV 账户上都有日历、希望助手从统一视图回答排期问题、寻找空档并安排或调整约会的场景。也适合偏好轻量本地进程、不希望中间经过云端服务的用户。
运行要求
需要 Node.js 22 或更高版本,通过 npx 或全局安装以 stdio 在本地运行。需要位于 ~/.config/pim-mcp/config.toml 的 TOML 配置文件(可用 PIM_MCP_CONFIG 改路径)并列出账户。凭据为应用专用密码或 OAuth 令牌,以系统密钥库、环境变量或命令输出的引用形式提供;Google 需一次性 OAuth 客户端配置。需能访问各 CalDAV 服务器。
安装前请注意
它会保存日历账户的凭据:密码和令牌以系统钥匙串、环境变量或密码管理器的引用形式存放,需保护好这些存储和配置文件。写入会改动真实日历;删除以及任何向他人发送邮件的操作默认关闭,需在保护设置中开启。Google 支持为 beta,多个列出的服务商尚未测试。不支持 Outlook、Microsoft 365 和 Exchange。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Pim Mcp,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

[pim-mcp: your calendars, in every agent]

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.


[npm] [CI] [MCP Registry] [Node] [Platforms] [License: MIT]

Quick start · Accounts · Connect · Tools · Guardrails · Providers · Contributing


text
 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

mermaid
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+.

sh
npm install -g pim-mcp                         # 1 · install (or prefix commands with `npx -y`)pim-mcp init                                   # 2 · write ~/.config/pim-mcp/config.tomlpim-mcp secret set pim-mcp/icloud              # 3 · store an app password (prompted, not echoed)pim-mcp check                                  # 4 · verify every accountclaude mcp add pim -s user -- npx -y pim-mcp   # 5 · connect your agent

pim-mcp check lists what it found:

text
✓ 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:

ReferenceResolves to
keychain:service/accountyour OS secret store. Easiest: pim-mcp secret set service/account
env:NAMEan 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:

sh
sudo apt install libsecret-tools     # Debian / Ubuntusudo dnf install libsecret           # Fedorasudo 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:

toml
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)
  1. Nextcloud → Settings → Security → Devices & sessions → Create new app password
  2. pim-mcp secret set pim-mcp/nextcloud
toml
[[accounts]]id = "nextcloud"provider = "nextcloud"url = "https://your.next.cloud/remote.php/dav"username = "your-login"password = "keychain:pim-mcp/nextcloud"
🍎 iCloud
  1. account.apple.com → Sign-In and Security → App-Specific Passwords
  2. pim-mcp secret set pim-mcp/icloud
toml
[[accounts]]id = "icloud"provider = "icloud"username = "[email protected]"   # the email you sign into your Apple Account withpassword = "keychain:pim-mcp/icloud"
📅 Google (one-time OAuth setup)

Google only allows OAuth for CalDAV:

  1. Google Cloud Console: create a project and enable the CalDAV API.
  2. 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.
  3. 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
  4. pim-mcp auth google --account google opens your browser and stores the refresh token in your OS secret store.
toml
[[accounts]]id = "google"provider = "google"username = "[email protected]"client_id = "xxxx.apps.googleusercontent.com"client_secret = "keychain:pim-mcp/google-client-secret"refresh_token = "keychain:pim-mcp/google"
🌐 Any other CalDAV server
toml
[[accounts]]id = "fastmail"provider = "caldav"url = "https://caldav.fastmail.com/"username = "[email protected]"password = "keychain:pim-mcp/fastmail"

Known URLs are in Providers.

🔌 Connect your agent

Claude Code (any OS)

sh
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
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
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:

json
"pim": {  "command": "npx",  "args": ["-y", "pim-mcp"],  "env": { "ICLOUD_PASSWORD": "…" }}

🧰 Tools

ToolWhat it does
📚list_calendarsAll calendars and their ids (icloud/work). Anywhere a tool takes a calendar, a plain name works too.
🗓️list_eventsEvents from all calendars in a range, merged and sorted. Defaults to today through the next 7 days.
🔎search_eventsText search over title, location and description.
📄get_eventFull details: description, attendees, organizer, recurrence rule, reminders.
🕐find_free_timeFree windows of at least N minutes, optionally within working hours.
➕create_eventTimed or all-day, with recurrence, up to 3 reminders, and busy/free status.
✏️update_eventChanges only the fields you pass. Recurring events take scope: instance or series.
🗑️delete_eventOff unless allow_delete = true. Takes the event's title, so approval prompts show its name, and refuses a title that doesn't match the event.

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

toml
timezone = "Europe/Amsterdam"            # default: the system timezone
[guardrails]allow_delete  = false                    # delete_event is refusedallow_invites = false                    # no adding attendees, no editing/deleting events that have them
[[accounts]]# …read_only           = true               # no writes to this account at allread_only_calendars = ["Family"]         # protect specific calendarshide_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

ProviderStatusSetup
Nextcloud / ownCloud✅ testednextcloud · https://<host>/remote.php/dav
iCloud✅ testedicloud · app-specific password
Google Calendar🧪 betagoogle · OAuth. Not yet tried with a real account; reports welcome
Fastmail🟡 untestedcaldav · https://caldav.fastmail.com/
Yahoo🟡 untestedcaldav · https://caldav.calendar.yahoo.com
mailbox.org🟡 untestedcaldav · https://dav.mailbox.org/
Posteo🟡 untestedcaldav · https://posteo.de:8443/
Radicale · Baïkal · SOGo · Synology🟡 untestedcaldav · your server's DAV URL
Outlook · Microsoft 365 · Exchange🚧 wantedno CalDAV; needs a Microsoft Graph backend
Proton Calendar❌ n/ano 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.


MIT © Aleksey Tkachenko · built for agents, readable by humans

来源:README.md,提交 006f369

工具

8

list_calendars

List every calendar across all configured accounts (Nextcloud, iCloud, Google, …), with ids usable in other tools.

无需输入参数。

list_events

Events in a time range, merged across all calendars and sorted by start. Recurring events are expanded into occurrences. Defaults to today through the next 7 days.

输入参数endstartaccountscalendars

search_events

Find events whose title, location or description contains the query (case-insensitive). Defaults to 90 days back through 365 days ahead.

输入参数endquery必填startcalendars

get_event

Full details of one event (description, attendees, organizer, recurrence rule, reminders).

输入参数id必填

find_free_time

Free time windows of at least `duration_minutes` across all (or selected) calendars. Events marked free/transparent and cancelled events do not block time.

输入参数end必填start必填accountscalendarsworking_hoursduration_minutes必填

create_event

Create an event. `start` as a date makes an all-day event. Without `end`, timed events last 1 hour and all-day events 1 day.

输入参数endbusyrrulestart必填title必填calendar必填locationattendeesdescriptionalarm_minutes

update_event

Change an event. Only the fields you pass change; moving `start` alone keeps the duration. For recurring events pass `scope`.

输入参数id必填endbusyrrulescopestarttitlelocationattendeesdescriptionalarm_minutes

delete_event

Delete an event. The user reviews this call by its `title`, and a title that does not match the event is refused. For recurring events pass `scope` ("instance" removes one occurrence, "series" removes all).

输入参数id必填scopetitle必填

版本历史

2
  1. v0.2.0最新Nov 5, 2026
  2. v0.1.0Oct 25, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分