Skip to main content
Glama
README.md
# mcp-calendar

The caller's Apple iCloud calendar over CalDAV, as an [MCP](https://modelcontextprotocol.io)
server.

| Tool | |
|---|---|
| `list_calendar_events` | events in a time window, across the caller's calendars |
| `create_calendar_event` | add an event to the write calendar (created on first write) |
| `update_calendar_event` | change title/time/place/description of an event by id |
| `delete_calendar_event` | **gated**: `confirm=false` previews, `confirm=true` deletes |
| `whoami` | which client and principal your key acts as |

**Accounts are per principal** (`config/accounts.example.yaml`): a user id forwarded by a
trusted client such as Jarvis (`X-On-Behalf-Of: owner`), or a client's own id. The file names
the environment variables that hold each account's Apple ID and app-specific password — the
credentials themselves stay in the environment and never reach the model. A caller without an
account gets an error, never someone else's calendar.

Part of the Jarvis tool servers; built on
[jarvis-mcp-kit](https://github.com/jaknow01/jarvis-mcp-kit) (API keys, rate limits, logs).

## Run

```bash
cp .env.example .env                                  # ICLOUD_CALDAV_USER, ICLOUD_APP_PASSWORD
cp config/clients.example.yaml config/clients.yaml
cp config/accounts.example.yaml config/accounts.yaml
uv run --env-file .env mcp-calendar serve             # http://localhost:8010/mcp/calendar
```

Kubernetes: `deploy/kubernetes.yaml`. Personal data — keep it ClusterIP-only.

## Connect

- **Jarvis:** `config/subagents.yaml` entry with `identity: user`.
- **Claude Code:** `claude mcp add --transport http calendar https://<host>/mcp/calendar --header "Authorization: Bearer jvk_…"`
  (add your client id to an account's `principals`).