mcp-calendar
by jermatic1
README.md
# mcp-calendar
An MCP server with read-only access to the calendars of a Google account, using the [Google Calendar API](https://developers.google.com/workspace/calendar/api).
## Setup
Create a Google Cloud project and OAuth client once. The pages below are under **Google Auth Platform** in the [Google Cloud console](https://console.cloud.google.com/auth/overview).
1. Create a project and enable the [Google Calendar API](https://console.cloud.google.com/apis/library/calendar-json.googleapis.com).
2. **Branding**: fill in the fields below. Do not upload a logo; a logo forces Google's verification review.
| Field | Value |
| --- | --- |
| App name | anything, e.g. `mcp-calendar` |
| User support email, developer contact | your email |
| Homepage | `https://github.com/jermatic1/mcp-calendar` |
| Privacy policy | `https://github.com/jermatic1/mcp-calendar/blob/main/PRIVACY.md` |
| Authorized domain | `github.com` |
3. **Audience**: choose **External**, the only option outside a Google Workspace. Click **Publish app** and confirm so the status reads **In production**. In Testing, Google expires the sign-in after 7 days. The dialog mentions verification; skip it. Verification is not required for your own use and only removes the warning in step 6.
4. **Data Access**: add the scope `https://www.googleapis.com/auth/calendar.readonly`.
5. **Clients**: create an OAuth client with application type **Desktop app**. Copy `.env.example` to `.env` and fill in `CALENDAR_CLIENT_ID` and `CALENDAR_CLIENT_SECRET` from it.
6. Sign in once:
```sh
task authorize
```
Open the printed URL in any browser and choose the Google account. On the "Google hasn't verified this app" page click **Advanced**, then **Go to <app name> (unsafe)**, then allow read-only calendar access. The browser then fails to load a `localhost` page; copy that page's full URL and paste it into the terminal. Add the printed `CALENDAR_REFRESH_TOKEN` line to `.env`.
Every calendar the account can see is available, including ones shared with it later.
## Run
Requires [uv](https://docs.astral.sh/uv/) and [Task](https://taskfile.dev/).
```sh
task setup
task serve
```
The server listens at `http://localhost:8000/mcp`.
## Docker
```sh
docker compose up -d
```
To sign in from the container instead of a local checkout, run `docker compose run --rm calendar task authorize` with the client ID and secret already in `.env`.
## Tools
Times are in the configured `TZ`. Events are merged across all calendars, soonest first, each with `title`, `start`, `end`, `all_day`, `calendar`, and `location` when set. All-day events give `start` and `end` as inclusive dates.
- `calendars()`: the account's calendars with id, name, and time zone.
- `agenda(days=1)`: events from the start of today through the next 1 to 31 days.
- `events(start, end)`: events between two ISO 8601 dates or datetimes, up to 92 days. A date-only end includes that whole day.
- `search(query, days_back=30, days_ahead=90)`: events matching free text, each window up to 366 days.
## Development
```sh
task check # tests, lint, formatting
```
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues