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

A Google Calendar [MCP](https://modelcontextprotocol.io) server written in TypeScript. Can be run as a stdio MCP server or used directly as a library with imported functions.

## Tools

All tools are prefixed with `googleCalendar`:

| Tool | Description |
|---|---|
| `googleCalendarListCalendars` | List all calendars accessible by the authenticated user |
| `googleCalendarListEvents` | List events from a calendar, with optional filters |
| `googleCalendarGetEvent` | Get a specific event by ID |
| `googleCalendarCreateEvent` | Create a new event |
| `googleCalendarUpdateEvent` | Update an existing event |
| `googleCalendarDeleteEvent` | Delete an event |

## Authentication

Every tool accepts optional auth parameters. If not provided, the server falls back to environment variables.

| Parameter | Environment variable |
|---|---|
| `accessToken` | `GOOGLE_ACCESS_TOKEN` |
| `refreshToken` | `GOOGLE_REFRESH_TOKEN` |
| `clientId` | `GOOGLE_CLIENT_ID` |
| `clientSecret` | `GOOGLE_CLIENT_SECRET` |

Only `accessToken` is required. `clientId` and `clientSecret` are needed only if you want the client to auto-refresh expired tokens using the `refreshToken`.

To obtain credentials, create an OAuth 2.0 client in the [Google Cloud Console](https://console.cloud.google.com/) with the `https://www.googleapis.com/auth/calendar` scope.

## Usage

### As an MCP stdio server

Build and run:

```bash
npm install
npm run build
node dist/index.js
```

Or during development:

```bash
npm run dev
```

#### Claude Desktop configuration

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "google-calendar": {
      "command": "node",
      "args": ["/absolute/path/to/dist/index.js"],
      "env": {
        "GOOGLE_ACCESS_TOKEN": "ya29.xxx",
        "GOOGLE_REFRESH_TOKEN": "1//xxx",
        "GOOGLE_CLIENT_ID": "xxx.apps.googleusercontent.com",
        "GOOGLE_CLIENT_SECRET": "xxx"
      }
    }
  }
}
```

### As a library

Import and call functions directly, passing credentials per-call:

```ts
import {
  googleCalendarListEvents,
  googleCalendarCreateEvent,
  googleCalendarDeleteEvent,
} from "./dist/api.js";

// List upcoming events
const events = await googleCalendarListEvents({
  accessToken: "ya29.xxx",
  calendarId: "primary",
  timeMin: new Date().toISOString(),
  maxResults: 10,
});

// Create an event
const event = await googleCalendarCreateEvent({
  accessToken: "ya29.xxx",
  summary: "Team standup",
  start: { dateTime: "2026-03-10T09:00:00-08:00", timeZone: "America/Los_Angeles" },
  end:   { dateTime: "2026-03-10T09:30:00-08:00", timeZone: "America/Los_Angeles" },
  attendees: [{ email: "colleague@example.com" }],
  sendUpdates: "all",
});

// Delete it
await googleCalendarDeleteEvent({
  accessToken: "ya29.xxx",
  eventId: event.id,
});
```

Or rely on environment variables and omit auth params entirely:

```bash
export GOOGLE_ACCESS_TOKEN=ya29.xxx
```

```ts
const calendars = await googleCalendarListCalendars({});
```

## Development

```bash
npm install          # install dependencies
npm run build        # compile TypeScript → dist/
npm run dev          # run stdio server with tsx (no build step)
```

## Project structure

```
src/
  auth.ts      — credential resolution and OAuth2Client factory
  calendar.ts  — Google Calendar API v3 wrappers
  tools.ts     — callable functions + Zod input schemas
  server.ts    — MCP server with all tools registered
  api.ts       — library entry point (re-exports everything)
  index.ts     — stdio entry point (bin)
```