proton-calendar-mcp
by cora-p
README.md
# proton-calendar-mcp
An MCP server for reading — and eventually modifying — a Proton Calendar.
## Architecture
Proton Calendar has no public API and no CalDAV support, and event data is
end-to-end encrypted. This server is built in phases:
- **Phase 1 (working): reads** via the calendar's secret ICS share link
(Proton Calendar → Settings → Calendars → Share via link, "full view").
The feed is fetched on demand and cached for 60 seconds. Recurring events
are expanded into concrete occurrences (RRULE, EXDATE, and overridden
instances are honored).
- **Phase 2 (planned): writes.** See DEVELOPMENT.md once started.
## Tools
| Tool | Purpose |
| --- | --- |
| `list_events` | Events in a date range (default: next 7 days) |
| `search_events` | Text search over title/description/location |
| `get_event` | Full details for one event by UID |
## Setup
```sh
npm install
npm run build
```
Configure in your MCP client (e.g. `claude_desktop_config.json`):
```json
{
"mcpServers": {
"proton-calendar": {
"command": "node",
"args": ["/path/to/proton-mcp/dist/index.js"],
"env": {
"PROTON_ICS_URL": "https://calendar.proton.me/api/calendar/v1/url/..."
}
}
}
}
```
The ICS URL is a secret — anyone holding it can read the calendar. Keep it
out of version control.
## Development
```sh
npm run dev # tsc --watch
```
Smoke test without an MCP client by piping JSON-RPC over stdin:
```sh
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_events","arguments":{}}}' \
| PROTON_ICS_URL="..." node dist/index.js
```
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing