@prmichaelsen/google-calendar-mcp 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +177 -0
- package/README.md +333 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +33 -0
- package/build/index.js.map +1 -0
- package/build/server-factory.d.ts +18 -0
- package/build/server-factory.d.ts.map +1 -0
- package/build/server-factory.js +317 -0
- package/build/server-factory.js.map +1 -0
- package/build/tools/calendar-tools.d.ts +7 -0
- package/build/tools/calendar-tools.d.ts.map +1 -0
- package/build/tools/calendar-tools.js +110 -0
- package/build/tools/calendar-tools.js.map +1 -0
- package/build/tools/email-tools.d.ts +7 -0
- package/build/tools/email-tools.d.ts.map +1 -0
- package/build/tools/email-tools.js +141 -0
- package/build/tools/email-tools.js.map +1 -0
- package/package.json +50 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.0.0] - 2026-02-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Multi-Tenancy Support
|
|
13
|
+
- **Server Factory Pattern**: New `createGoogleCalendarServer()` factory function for creating per-user server instances
|
|
14
|
+
- **Library Exports**: Package can now be imported as a library with exports for:
|
|
15
|
+
- `@prmichaelsen/google-calendar-mcp/factory` - Server factory function
|
|
16
|
+
- `@prmichaelsen/google-calendar-mcp/tools/calendar` - Calendar tool implementations
|
|
17
|
+
- `@prmichaelsen/google-calendar-mcp/tools/email` - Email tool implementations
|
|
18
|
+
- **Modular Architecture**: Tool implementations extracted to separate files for reusability
|
|
19
|
+
- `src/tools/calendar-tools.ts` - Calendar operations
|
|
20
|
+
- `src/tools/email-tools.ts` - Email operations
|
|
21
|
+
- `src/server-factory.ts` - Factory function
|
|
22
|
+
|
|
23
|
+
#### Documentation
|
|
24
|
+
- Multi-tenancy design document ([`agent/design/multi-tenancy-design.md`](agent/design/multi-tenancy-design.md))
|
|
25
|
+
- MCP Auth integration plan ([`agent/design/mcp-auth-integration-plan.md`](agent/design/mcp-auth-integration-plan.md))
|
|
26
|
+
- Factory usage examples in README
|
|
27
|
+
- Task 16 documentation for refactoring process
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
#### Breaking Changes
|
|
32
|
+
- **Tool Names**: All tools now prefixed with `google_` for multi-tenant compatibility:
|
|
33
|
+
- `create_calendar_event` → `google_create_calendar_event`
|
|
34
|
+
- `list_calendar_events` → `google_list_calendar_events`
|
|
35
|
+
- `update_calendar_event` → `google_update_calendar_event`
|
|
36
|
+
- `send_email` → `google_send_email`
|
|
37
|
+
- `list_emails` → `google_list_emails`
|
|
38
|
+
- `read_email` → `google_read_email`
|
|
39
|
+
|
|
40
|
+
#### Architecture
|
|
41
|
+
- **Refactored `index.ts`**: Now uses factory pattern while maintaining backward compatibility
|
|
42
|
+
- **Server Version**: Updated to 2.0.0 in server metadata
|
|
43
|
+
- **Package Exports**: Added explicit exports map in `package.json`
|
|
44
|
+
- **Files Field**: Added files field to control npm package contents
|
|
45
|
+
|
|
46
|
+
### Migration Guide
|
|
47
|
+
|
|
48
|
+
#### For Standalone Users
|
|
49
|
+
Update your MCP settings to use new tool names:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"@prmichaelsen/google-calendar-mcp": {
|
|
55
|
+
"alwaysAllow": [
|
|
56
|
+
"google_create_calendar_event",
|
|
57
|
+
"google_list_calendar_events",
|
|
58
|
+
"google_update_calendar_event",
|
|
59
|
+
"google_send_email",
|
|
60
|
+
"google_list_emails",
|
|
61
|
+
"google_read_email"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### For Library Users
|
|
69
|
+
Import and use the factory:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { createGoogleCalendarServer } from '@prmichaelsen/google-calendar-mcp/factory';
|
|
73
|
+
|
|
74
|
+
const server = createGoogleCalendarServer(
|
|
75
|
+
'user@workspace.com',
|
|
76
|
+
'user-id',
|
|
77
|
+
{ serviceAccountKeyPath: '/path/to/key.json' }
|
|
78
|
+
);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Technical Details
|
|
82
|
+
- Maintained backward compatibility for single-user deployments
|
|
83
|
+
- No changes to Google API integration or authentication logic
|
|
84
|
+
- All existing features preserved
|
|
85
|
+
- TypeScript compilation with declaration files
|
|
86
|
+
- Proper module resolution with Node16
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## [1.0.0] - 2026-02-13
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
#### Core Features
|
|
95
|
+
- **Calendar Management**
|
|
96
|
+
- `create_calendar_event` - Create events with attendees, reminders, and notifications
|
|
97
|
+
- `list_calendar_events` - List upcoming events with time range filtering
|
|
98
|
+
- `update_calendar_event` - Update existing events by ID
|
|
99
|
+
- Support for custom reminders (popup/email at any interval)
|
|
100
|
+
- Automatic attendee invitation emails
|
|
101
|
+
|
|
102
|
+
#### Email Management
|
|
103
|
+
- **Gmail Integration**
|
|
104
|
+
- `send_email` - Send plain text or HTML emails with CC/BCC support
|
|
105
|
+
- `list_emails` - Query inbox with Gmail search syntax
|
|
106
|
+
- `read_email` - Read full email content with optional mark-as-read
|
|
107
|
+
- Proper MIME formatting for HTML emails
|
|
108
|
+
|
|
109
|
+
#### Authentication
|
|
110
|
+
- Service account authentication with JSON key file
|
|
111
|
+
- Domain-wide delegation for user impersonation
|
|
112
|
+
- Support for multiple Google API scopes (Calendar, Gmail)
|
|
113
|
+
- Environment-based configuration
|
|
114
|
+
|
|
115
|
+
#### MCP Protocol
|
|
116
|
+
- Full MCP SDK integration with stdio transport
|
|
117
|
+
- 6 tools with comprehensive JSON schemas
|
|
118
|
+
- Structured error responses
|
|
119
|
+
- Type-safe tool definitions
|
|
120
|
+
|
|
121
|
+
#### Documentation
|
|
122
|
+
- Comprehensive README with setup instructions
|
|
123
|
+
- Google Cloud Console setup guide
|
|
124
|
+
- Domain-wide delegation configuration steps
|
|
125
|
+
- Troubleshooting guide for common issues
|
|
126
|
+
- API documentation with examples for all tools
|
|
127
|
+
- Architecture documentation
|
|
128
|
+
|
|
129
|
+
#### Agent Context Protocol (ACP)
|
|
130
|
+
- Complete ACP structure for agent continuity
|
|
131
|
+
- Design documents (requirements, architecture)
|
|
132
|
+
- Pattern documents (MCP server, authentication, error handling)
|
|
133
|
+
- Milestone documents (3 completed milestones)
|
|
134
|
+
- Progress tracking with YAML
|
|
135
|
+
|
|
136
|
+
### Technical Details
|
|
137
|
+
- TypeScript implementation with strict type checking
|
|
138
|
+
- ES2022 target with Node16 module resolution
|
|
139
|
+
- Full type safety with `@types/node`
|
|
140
|
+
- Error handling at all levels
|
|
141
|
+
- Environment variable validation
|
|
142
|
+
|
|
143
|
+
### Configuration
|
|
144
|
+
- `GOOGLE_APPLICATION_CREDENTIALS` - Service account key path
|
|
145
|
+
- `GOOGLE_CALENDAR_ID` - Calendar to use (defaults to "primary")
|
|
146
|
+
- `GOOGLE_CALENDAR_SUBJECT` - User email for domain-wide delegation
|
|
147
|
+
|
|
148
|
+
### Repository
|
|
149
|
+
- Initial release as `@prmichaelsen/google-calendar-mcp`
|
|
150
|
+
- Published to GitHub: https://github.com/prmichaelsen/calendar-mcp-server
|
|
151
|
+
- MIT License
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Future Enhancements
|
|
156
|
+
|
|
157
|
+
### Planned Features
|
|
158
|
+
- Event deletion support
|
|
159
|
+
- Recurring event management
|
|
160
|
+
- Calendar creation/deletion
|
|
161
|
+
- Email attachment support
|
|
162
|
+
- Advanced Gmail features (labels, filters)
|
|
163
|
+
- Calendar ACL management
|
|
164
|
+
- Free/busy time queries
|
|
165
|
+
|
|
166
|
+
### Technical Improvements
|
|
167
|
+
- Unit tests with mocked APIs
|
|
168
|
+
- Integration tests
|
|
169
|
+
- CI/CD pipeline
|
|
170
|
+
- Docker containerization
|
|
171
|
+
- Health check endpoint
|
|
172
|
+
- Metrics and logging
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
[2.0.0]: https://github.com/prmichaelsen/calendar-mcp-server/releases/tag/v2.0.0
|
|
177
|
+
[1.0.0]: https://github.com/prmichaelsen/calendar-mcp-server/releases/tag/v1.0.0
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Google Calendar MCP Server
|
|
2
|
+
|
|
3
|
+
**Package**: `@prmichaelsen/google-calendar-mcp`
|
|
4
|
+
**Version**: 2.0.0
|
|
5
|
+
|
|
6
|
+
A TypeScript-based Model Context Protocol (MCP) server for Google Calendar and Gmail integration using service account authentication with domain-wide delegation.
|
|
7
|
+
|
|
8
|
+
**New in v2.0**: Factory pattern support for multi-tenant deployments. Can be used as a standalone server or imported as a library for wrapper projects.
|
|
9
|
+
|
|
10
|
+
**Note:** This is a minimal implementation covering the most common use cases. The Google Calendar API has many more features (recurring events, calendar management, ACLs, etc.) that are not implemented here. This server focuses on basic event CRUD operations with reminders and attendee management.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- ✅ Create calendar events with title, description, start/end times, location, and attendees
|
|
15
|
+
- ✅ Update existing calendar events
|
|
16
|
+
- ✅ List upcoming calendar events
|
|
17
|
+
- ✅ Custom event reminders (popup/email at any interval)
|
|
18
|
+
- ✅ Service account authentication with domain-wide delegation
|
|
19
|
+
- ✅ Automatic email notifications to attendees
|
|
20
|
+
- ✅ TypeScript implementation with full type safety
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
- Node.js v18 or later
|
|
25
|
+
- Google Workspace account with admin access (for domain-wide delegation)
|
|
26
|
+
- Google Cloud Console project with Calendar API enabled
|
|
27
|
+
- Service account with Calendar API access and domain-wide delegation
|
|
28
|
+
- Service account JSON key file
|
|
29
|
+
|
|
30
|
+
## Setup
|
|
31
|
+
|
|
32
|
+
### 1. Google Cloud Console Setup
|
|
33
|
+
|
|
34
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
35
|
+
2. Create a new project or select existing one
|
|
36
|
+
3. Enable the Google Calendar API:
|
|
37
|
+
- Navigate to "APIs & Services" > "Library"
|
|
38
|
+
- Search for "Google Calendar API"
|
|
39
|
+
- Click "Enable"
|
|
40
|
+
|
|
41
|
+
### 2. Create Service Account
|
|
42
|
+
|
|
43
|
+
1. Go to "APIs & Services" > "Credentials"
|
|
44
|
+
2. Click "Create Credentials" > "Service Account"
|
|
45
|
+
3. Fill in service account details:
|
|
46
|
+
- Name: `calendar-mcp` (or your choice)
|
|
47
|
+
- ID: `calendar-mcp@your-project.iam.gserviceaccount.com`
|
|
48
|
+
4. Click "Create and Continue"
|
|
49
|
+
5. Grant appropriate roles (optional)
|
|
50
|
+
6. Click "Done"
|
|
51
|
+
|
|
52
|
+
### 3. Create Service Account Key
|
|
53
|
+
|
|
54
|
+
1. Click on the newly created service account
|
|
55
|
+
2. Go to the "Keys" tab
|
|
56
|
+
3. Click "Add Key" > "Create new key"
|
|
57
|
+
4. Select "JSON" and click "Create"
|
|
58
|
+
5. Save the downloaded JSON file as `~/calendar-mcp-server/service-account-key.json`
|
|
59
|
+
6. **Note the `client_id` from the JSON file** - you'll need this for domain-wide delegation
|
|
60
|
+
|
|
61
|
+
### 4. Enable Domain-Wide Delegation (REQUIRED for attendee invitations)
|
|
62
|
+
|
|
63
|
+
**This step is critical for sending calendar invitations to attendees.**
|
|
64
|
+
|
|
65
|
+
1. **In Google Admin Console:**
|
|
66
|
+
- Go to [Google Admin Console](https://admin.google.com/)
|
|
67
|
+
- Navigate to: **Security** → **Access and data control** → **API Controls**
|
|
68
|
+
- Click **Manage Domain Wide Delegation**
|
|
69
|
+
- Click **Add new**
|
|
70
|
+
|
|
71
|
+
2. **Configure delegation:**
|
|
72
|
+
- **Client ID:** Paste the `client_id` from your service account JSON key
|
|
73
|
+
- **OAuth Scopes:** `https://www.googleapis.com/auth/calendar`
|
|
74
|
+
- Click **Authorize**
|
|
75
|
+
|
|
76
|
+
3. **Verify setup:**
|
|
77
|
+
- The service account should now appear in the Domain-Wide Delegation list
|
|
78
|
+
- Status should show "Authorized"
|
|
79
|
+
|
|
80
|
+
**Without domain-wide delegation:** Events can be created but attendee invitations will fail with error:
|
|
81
|
+
```
|
|
82
|
+
Service accounts cannot invite attendees without Domain-Wide Delegation of Authority
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 5. Install Dependencies
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
cd ~/calendar-mcp-server
|
|
89
|
+
npm install
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 6. Build the Project
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx tsc
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
100
|
+
### Environment Variables
|
|
101
|
+
|
|
102
|
+
The server requires three environment variables:
|
|
103
|
+
|
|
104
|
+
- **`GOOGLE_APPLICATION_CREDENTIALS`**: Path to your service account JSON key file
|
|
105
|
+
- **`GOOGLE_CALENDAR_ID`**: Calendar ID to use (e.g., email address or "primary")
|
|
106
|
+
- **`GOOGLE_CALENDAR_SUBJECT`**: Email address to impersonate for domain-wide delegation
|
|
107
|
+
|
|
108
|
+
### MCP Settings
|
|
109
|
+
|
|
110
|
+
Add to your MCP settings file (`.vscode-server/data/User/globalStorage/kilocode.kilo-code/settings/mcp_settings.json`):
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"mcpServers": {
|
|
115
|
+
"@prmichaelsen/google-calendar-mcp": {
|
|
116
|
+
"command": "node",
|
|
117
|
+
"args": ["/path/to/calendar-mcp-server/build/index.js"],
|
|
118
|
+
"env": {
|
|
119
|
+
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/calendar-mcp-server/service-account-key.json",
|
|
120
|
+
"GOOGLE_CALENDAR_ID": "your-email@your-domain.com",
|
|
121
|
+
"GOOGLE_CALENDAR_SUBJECT": "your-email@your-domain.com"
|
|
122
|
+
},
|
|
123
|
+
"alwaysAllow": [
|
|
124
|
+
"create_calendar_event",
|
|
125
|
+
"list_calendar_events",
|
|
126
|
+
"update_calendar_event",
|
|
127
|
+
"send_email",
|
|
128
|
+
"list_emails",
|
|
129
|
+
"read_email"
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Note:** Replace paths and email addresses with your actual values.
|
|
137
|
+
|
|
138
|
+
## Available Tools
|
|
139
|
+
|
|
140
|
+
### create_calendar_event
|
|
141
|
+
|
|
142
|
+
Create a new calendar event with optional reminders and attendees.
|
|
143
|
+
|
|
144
|
+
**Parameters:**
|
|
145
|
+
- `summary` (required): Event title
|
|
146
|
+
- `start_time` (required): Start time in ISO 8601 format
|
|
147
|
+
- `end_time` (required): End time in ISO 8601 format
|
|
148
|
+
- `description` (optional): Event description
|
|
149
|
+
- `location` (optional): Event location
|
|
150
|
+
- `attendees` (optional): Array of attendee email addresses
|
|
151
|
+
- `send_notifications` (optional): Send email notifications (default: true)
|
|
152
|
+
- `reminders` (optional): Array of reminder objects with `method` ("email" or "popup") and `minutes`
|
|
153
|
+
|
|
154
|
+
**Example:**
|
|
155
|
+
```typescript
|
|
156
|
+
{
|
|
157
|
+
"summary": "Team Meeting",
|
|
158
|
+
"description": "Weekly team sync",
|
|
159
|
+
"start_time": "2024-12-25T10:00:00-08:00",
|
|
160
|
+
"end_time": "2024-12-25T11:00:00-08:00",
|
|
161
|
+
"location": "Conference Room A",
|
|
162
|
+
"attendees": ["alice@example.com", "bob@example.com"],
|
|
163
|
+
"reminders": [
|
|
164
|
+
{
|
|
165
|
+
"method": "popup",
|
|
166
|
+
"minutes": 10
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"method": "email",
|
|
170
|
+
"minutes": 1440
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Common Reminder Times:**
|
|
177
|
+
- 10 minutes before: `{method: "popup", minutes: 10}`
|
|
178
|
+
- 1 hour before: `{method: "popup", minutes: 60}`
|
|
179
|
+
- 1 day before: `{method: "email", minutes: 1440}`
|
|
180
|
+
- 2 days before: `{method: "email", minutes: 2880}`
|
|
181
|
+
- 1 week before: `{method: "email", minutes: 10080}`
|
|
182
|
+
|
|
183
|
+
### list_calendar_events
|
|
184
|
+
|
|
185
|
+
List upcoming calendar events with their IDs.
|
|
186
|
+
|
|
187
|
+
**Parameters:**
|
|
188
|
+
- `max_results` (optional): Maximum number of events to return (default: 10)
|
|
189
|
+
- `time_min` (optional): Lower bound for event start time in ISO 8601 format (default: now)
|
|
190
|
+
- `time_max` (optional): Upper bound for event start time in ISO 8601 format
|
|
191
|
+
|
|
192
|
+
**Example:**
|
|
193
|
+
```typescript
|
|
194
|
+
{
|
|
195
|
+
"max_results": 20,
|
|
196
|
+
"time_min": "2024-12-01T00:00:00Z",
|
|
197
|
+
"time_max": "2024-12-31T23:59:59Z"
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### update_calendar_event
|
|
202
|
+
|
|
203
|
+
Update an existing calendar event by its ID.
|
|
204
|
+
|
|
205
|
+
**Parameters:**
|
|
206
|
+
- `event_id` (required): Event ID to update
|
|
207
|
+
- `summary` (optional): New event title
|
|
208
|
+
- `description` (optional): New event description
|
|
209
|
+
- `start_time` (optional): New start time in ISO 8601 format
|
|
210
|
+
- `end_time` (optional): New end time in ISO 8601 format
|
|
211
|
+
- `location` (optional): New event location
|
|
212
|
+
- `attendees` (optional): New array of attendee email addresses
|
|
213
|
+
- `send_notifications` (optional): Send update notifications (default: true)
|
|
214
|
+
- `reminders` (optional): New reminder configuration
|
|
215
|
+
|
|
216
|
+
**Example:**
|
|
217
|
+
```typescript
|
|
218
|
+
{
|
|
219
|
+
"event_id": "abc123xyz",
|
|
220
|
+
"summary": "Updated Team Meeting",
|
|
221
|
+
"attendees": ["alice@example.com", "charlie@example.com"],
|
|
222
|
+
"reminders": [
|
|
223
|
+
{
|
|
224
|
+
"method": "popup",
|
|
225
|
+
"minutes": 30
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Using as a Library
|
|
232
|
+
|
|
233
|
+
This package can be used as a base for multi-tenant MCP servers:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { createGoogleCalendarServer } from '@prmichaelsen/google-calendar-mcp/factory';
|
|
237
|
+
|
|
238
|
+
const server = createGoogleCalendarServer(
|
|
239
|
+
'user@workspace.com', // User to impersonate
|
|
240
|
+
'user-123', // User ID for tracking
|
|
241
|
+
{
|
|
242
|
+
serviceAccountKeyPath: '/path/to/key.json',
|
|
243
|
+
calendarId: 'primary'
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
// Connect to transport (stdio, SSE, etc.)
|
|
248
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
249
|
+
const transport = new StdioServerTransport();
|
|
250
|
+
await server.connect(transport);
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Factory Options
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
interface GoogleCalendarServerOptions {
|
|
257
|
+
serviceAccountKeyPath: string; // Required: Path to service account JSON key
|
|
258
|
+
calendarId?: string; // Optional: Calendar ID (defaults to "primary")
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Multi-Tenant Integration
|
|
263
|
+
|
|
264
|
+
For multi-tenant deployments with Platform JWT authentication, see:
|
|
265
|
+
- [Multi-Tenancy Design](agent/design/multi-tenancy-design.md)
|
|
266
|
+
- [MCP Auth Integration Plan](agent/design/mcp-auth-integration-plan.md)
|
|
267
|
+
|
|
268
|
+
The factory pattern enables wrapping this server with `@prmichaelsen/mcp-auth` for per-user authentication and authorization.
|
|
269
|
+
|
|
270
|
+
## Tool Names
|
|
271
|
+
|
|
272
|
+
**v2.0 Breaking Change**: All tools now have a `google_` prefix for multi-tenant compatibility:
|
|
273
|
+
|
|
274
|
+
- `google_create_calendar_event` (was `create_calendar_event`)
|
|
275
|
+
- `google_list_calendar_events` (was `list_calendar_events`)
|
|
276
|
+
- `google_update_calendar_event` (was `update_calendar_event`)
|
|
277
|
+
- `google_send_email` (was `send_email`)
|
|
278
|
+
- `google_list_emails` (was `list_emails`)
|
|
279
|
+
- `google_read_email` (was `read_email`)
|
|
280
|
+
|
|
281
|
+
**Note**: If you're using the standalone server (not as a library), update your MCP settings to use the new tool names.
|
|
282
|
+
|
|
283
|
+
## Development
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Build
|
|
287
|
+
cd ~/calendar-mcp-server
|
|
288
|
+
npx tsc
|
|
289
|
+
|
|
290
|
+
# The compiled server will be at build/index.js
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Troubleshooting
|
|
294
|
+
|
|
295
|
+
### "Error: GOOGLE_CALENDAR_SUBJECT environment variable is required"
|
|
296
|
+
|
|
297
|
+
- Ensure `GOOGLE_CALENDAR_SUBJECT` is set in your MCP settings
|
|
298
|
+
- This should be the email address you want to impersonate (e.g., your Google Workspace email)
|
|
299
|
+
|
|
300
|
+
### "Service accounts cannot invite attendees without Domain-Wide Delegation"
|
|
301
|
+
|
|
302
|
+
- Follow step 4 above to enable domain-wide delegation in Google Admin Console
|
|
303
|
+
- Ensure the OAuth scope `https://www.googleapis.com/auth/calendar` is authorized
|
|
304
|
+
- Verify the service account's `client_id` is correctly entered in Admin Console
|
|
305
|
+
|
|
306
|
+
### "The user must be signed up for Google Calendar"
|
|
307
|
+
|
|
308
|
+
- The email specified in `GOOGLE_CALENDAR_SUBJECT` needs to visit [calendar.google.com](https://calendar.google.com) once to activate Google Calendar
|
|
309
|
+
- This is a one-time setup requirement
|
|
310
|
+
|
|
311
|
+
### "Failed to create calendar event: Forbidden"
|
|
312
|
+
|
|
313
|
+
- Verify domain-wide delegation is properly configured
|
|
314
|
+
- Ensure Calendar API is enabled in Google Cloud Console
|
|
315
|
+
- Check that the service account has the calendar scope authorized
|
|
316
|
+
|
|
317
|
+
## Architecture
|
|
318
|
+
|
|
319
|
+
**Domain-Wide Delegation Flow:**
|
|
320
|
+
1. Service account (`calendar-mcp@your-project.iam.gserviceaccount.com`) impersonates user
|
|
321
|
+
2. User email specified in `GOOGLE_CALENDAR_SUBJECT` environment variable
|
|
322
|
+
3. Calendar operations performed as that user
|
|
323
|
+
4. Attendee invitations sent from that user's calendar
|
|
324
|
+
|
|
325
|
+
**Benefits:**
|
|
326
|
+
- No OAuth2 browser flow required
|
|
327
|
+
- Automated calendar management
|
|
328
|
+
- Ability to send attendee invitations
|
|
329
|
+
- Suitable for server-side/bot applications
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
MIT
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createGoogleCalendarServer } from "./server-factory.js";
|
|
4
|
+
// Environment variables
|
|
5
|
+
const GOOGLE_APPLICATION_CREDENTIALS = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
6
|
+
const GOOGLE_CALENDAR_ID = process.env.GOOGLE_CALENDAR_ID || "primary";
|
|
7
|
+
const GOOGLE_CALENDAR_SUBJECT = process.env.GOOGLE_CALENDAR_SUBJECT;
|
|
8
|
+
// Validate environment variables
|
|
9
|
+
if (!GOOGLE_APPLICATION_CREDENTIALS) {
|
|
10
|
+
console.error("Error: GOOGLE_APPLICATION_CREDENTIALS environment variable is required");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
if (!GOOGLE_CALENDAR_SUBJECT) {
|
|
14
|
+
console.error("Error: GOOGLE_CALENDAR_SUBJECT environment variable is required for domain-wide delegation");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
// Create server using factory
|
|
18
|
+
const server = createGoogleCalendarServer(GOOGLE_CALENDAR_SUBJECT, "single-user", // userId for single-user mode
|
|
19
|
+
{
|
|
20
|
+
serviceAccountKeyPath: GOOGLE_APPLICATION_CREDENTIALS,
|
|
21
|
+
calendarId: GOOGLE_CALENDAR_ID,
|
|
22
|
+
});
|
|
23
|
+
// Start server
|
|
24
|
+
async function runServer() {
|
|
25
|
+
const transport = new StdioServerTransport();
|
|
26
|
+
await server.connect(transport);
|
|
27
|
+
console.error("Calendar MCP Server running on stdio");
|
|
28
|
+
}
|
|
29
|
+
runServer().catch((error) => {
|
|
30
|
+
console.error("Fatal error running server:", error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,wBAAwB;AACxB,MAAM,8BAA8B,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC;AAClF,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS,CAAC;AACvE,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;AAEpE,iCAAiC;AACjC,IAAI,CAAC,8BAA8B,EAAE,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;IACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,CAAC,uBAAuB,EAAE,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,4FAA4F,CAAC,CAAC;IAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,8BAA8B;AAC9B,MAAM,MAAM,GAAG,0BAA0B,CACvC,uBAAuB,EACvB,aAAa,EAAE,8BAA8B;AAC7C;IACE,qBAAqB,EAAE,8BAA8B;IACrD,UAAU,EAAE,kBAAkB;CAC/B,CACF,CAAC;AAEF,eAAe;AACf,KAAK,UAAU,SAAS;IACtB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC1B,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server factory for Google Calendar MCP Server
|
|
3
|
+
* Creates per-user server instances for multi-tenant deployments
|
|
4
|
+
*/
|
|
5
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
6
|
+
export interface GoogleCalendarServerOptions {
|
|
7
|
+
serviceAccountKeyPath: string;
|
|
8
|
+
calendarId?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create a Google Calendar MCP server instance for a specific user
|
|
12
|
+
* @param userEmail - Email address to impersonate (must be in Google Workspace domain)
|
|
13
|
+
* @param userId - Platform user ID for tracking/logging
|
|
14
|
+
* @param options - Server configuration options
|
|
15
|
+
* @returns Configured MCP Server instance
|
|
16
|
+
*/
|
|
17
|
+
export declare function createGoogleCalendarServer(userEmail: string, userId: string, options: GoogleCalendarServerOptions): Server;
|
|
18
|
+
//# sourceMappingURL=server-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-factory.d.ts","sourceRoot":"","sources":["../src/server-factory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAkBnE,MAAM,WAAW,2BAA2B;IAC1C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,2BAA2B,GACnC,MAAM,CA6TR"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server factory for Google Calendar MCP Server
|
|
3
|
+
* Creates per-user server instances for multi-tenant deployments
|
|
4
|
+
*/
|
|
5
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
6
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { google } from "googleapis";
|
|
8
|
+
import { createCalendarEvent, listCalendarEvents, updateCalendarEvent, } from "./tools/calendar-tools.js";
|
|
9
|
+
import { sendEmail, listEmails, readEmail, } from "./tools/email-tools.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create a Google Calendar MCP server instance for a specific user
|
|
12
|
+
* @param userEmail - Email address to impersonate (must be in Google Workspace domain)
|
|
13
|
+
* @param userId - Platform user ID for tracking/logging
|
|
14
|
+
* @param options - Server configuration options
|
|
15
|
+
* @returns Configured MCP Server instance
|
|
16
|
+
*/
|
|
17
|
+
export function createGoogleCalendarServer(userEmail, userId, options) {
|
|
18
|
+
// Initialize service account auth with user impersonation
|
|
19
|
+
const auth = new google.auth.GoogleAuth({
|
|
20
|
+
keyFile: options.serviceAccountKeyPath,
|
|
21
|
+
scopes: [
|
|
22
|
+
"https://www.googleapis.com/auth/calendar",
|
|
23
|
+
"https://www.googleapis.com/auth/gmail.send",
|
|
24
|
+
"https://www.googleapis.com/auth/gmail.readonly",
|
|
25
|
+
"https://www.googleapis.com/auth/gmail.modify",
|
|
26
|
+
],
|
|
27
|
+
clientOptions: {
|
|
28
|
+
subject: userEmail, // Impersonate this user
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const calendar = google.calendar({ version: "v3", auth });
|
|
32
|
+
const gmail = google.gmail({ version: "v1", auth });
|
|
33
|
+
const calendarId = options.calendarId || "primary";
|
|
34
|
+
// Create MCP server
|
|
35
|
+
const server = new Server({
|
|
36
|
+
name: "google-calendar-mcp-server",
|
|
37
|
+
version: "2.0.0",
|
|
38
|
+
}, {
|
|
39
|
+
capabilities: {
|
|
40
|
+
tools: {},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
// Define tools with google_ prefix (required by mcp-auth pattern)
|
|
44
|
+
const tools = [
|
|
45
|
+
{
|
|
46
|
+
name: "google_create_calendar_event",
|
|
47
|
+
description: "Create a new event in Google Calendar with specified details including title, description, start/end times, and optional attendees",
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: "object",
|
|
50
|
+
properties: {
|
|
51
|
+
summary: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "Event title/summary",
|
|
54
|
+
},
|
|
55
|
+
description: {
|
|
56
|
+
type: "string",
|
|
57
|
+
description: "Event description (optional)",
|
|
58
|
+
},
|
|
59
|
+
start_time: {
|
|
60
|
+
type: "string",
|
|
61
|
+
description: "Start time in ISO 8601 format (e.g., 2024-12-25T10:00:00-08:00)",
|
|
62
|
+
},
|
|
63
|
+
end_time: {
|
|
64
|
+
type: "string",
|
|
65
|
+
description: "End time in ISO 8601 format (e.g., 2024-12-25T11:00:00-08:00)",
|
|
66
|
+
},
|
|
67
|
+
attendees: {
|
|
68
|
+
type: "array",
|
|
69
|
+
items: { type: "string" },
|
|
70
|
+
description: "List of attendee email addresses (optional)",
|
|
71
|
+
},
|
|
72
|
+
location: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Event location (optional)",
|
|
75
|
+
},
|
|
76
|
+
send_notifications: {
|
|
77
|
+
type: "boolean",
|
|
78
|
+
description: "Send email notifications to attendees (default: true)",
|
|
79
|
+
default: true,
|
|
80
|
+
},
|
|
81
|
+
reminders: {
|
|
82
|
+
type: "array",
|
|
83
|
+
items: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
method: {
|
|
87
|
+
type: "string",
|
|
88
|
+
enum: ["email", "popup"],
|
|
89
|
+
description: "Reminder method: 'email' or 'popup'",
|
|
90
|
+
},
|
|
91
|
+
minutes: {
|
|
92
|
+
type: "number",
|
|
93
|
+
description: "Minutes before event to send reminder (e.g., 10, 1440 for 1 day)",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
required: ["method", "minutes"],
|
|
97
|
+
},
|
|
98
|
+
description: "Event reminders (optional). Example: [{method: 'popup', minutes: 10}, {method: 'email', minutes: 1440}]",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
required: ["summary", "start_time", "end_time"],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "google_list_calendar_events",
|
|
106
|
+
description: "List upcoming events from Google Calendar within a specified time range",
|
|
107
|
+
inputSchema: {
|
|
108
|
+
type: "object",
|
|
109
|
+
properties: {
|
|
110
|
+
max_results: {
|
|
111
|
+
type: "number",
|
|
112
|
+
description: "Maximum number of events to return (default: 10)",
|
|
113
|
+
default: 10,
|
|
114
|
+
},
|
|
115
|
+
time_min: {
|
|
116
|
+
type: "string",
|
|
117
|
+
description: "Lower bound for event start time in ISO 8601 format (default: now)",
|
|
118
|
+
},
|
|
119
|
+
time_max: {
|
|
120
|
+
type: "string",
|
|
121
|
+
description: "Upper bound for event start time in ISO 8601 format (optional)",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "google_update_calendar_event",
|
|
128
|
+
description: "Update an existing calendar event by event ID. Can modify title, description, times, location, and attendees.",
|
|
129
|
+
inputSchema: {
|
|
130
|
+
type: "object",
|
|
131
|
+
properties: {
|
|
132
|
+
event_id: {
|
|
133
|
+
type: "string",
|
|
134
|
+
description: "Event ID to update (required)",
|
|
135
|
+
},
|
|
136
|
+
summary: {
|
|
137
|
+
type: "string",
|
|
138
|
+
description: "Event title/summary (optional)",
|
|
139
|
+
},
|
|
140
|
+
description: {
|
|
141
|
+
type: "string",
|
|
142
|
+
description: "Event description (optional)",
|
|
143
|
+
},
|
|
144
|
+
start_time: {
|
|
145
|
+
type: "string",
|
|
146
|
+
description: "Start time in ISO 8601 format (optional)",
|
|
147
|
+
},
|
|
148
|
+
end_time: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "End time in ISO 8601 format (optional)",
|
|
151
|
+
},
|
|
152
|
+
attendees: {
|
|
153
|
+
type: "array",
|
|
154
|
+
items: { type: "string" },
|
|
155
|
+
description: "List of attendee email addresses (optional)",
|
|
156
|
+
},
|
|
157
|
+
location: {
|
|
158
|
+
type: "string",
|
|
159
|
+
description: "Event location (optional)",
|
|
160
|
+
},
|
|
161
|
+
send_notifications: {
|
|
162
|
+
type: "boolean",
|
|
163
|
+
description: "Send email notifications to attendees about the update (default: true)",
|
|
164
|
+
default: true,
|
|
165
|
+
},
|
|
166
|
+
reminders: {
|
|
167
|
+
type: "array",
|
|
168
|
+
items: {
|
|
169
|
+
type: "object",
|
|
170
|
+
properties: {
|
|
171
|
+
method: {
|
|
172
|
+
type: "string",
|
|
173
|
+
enum: ["email", "popup"],
|
|
174
|
+
description: "Reminder method: 'email' or 'popup'",
|
|
175
|
+
},
|
|
176
|
+
minutes: {
|
|
177
|
+
type: "number",
|
|
178
|
+
description: "Minutes before event to send reminder",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
required: ["method", "minutes"],
|
|
182
|
+
},
|
|
183
|
+
description: "Event reminders (optional)",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
required: ["event_id"],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "google_send_email",
|
|
191
|
+
description: "Send an email from the configured Gmail account. Supports plain text and HTML emails with optional attachments.",
|
|
192
|
+
inputSchema: {
|
|
193
|
+
type: "object",
|
|
194
|
+
properties: {
|
|
195
|
+
to: {
|
|
196
|
+
type: "array",
|
|
197
|
+
items: { type: "string" },
|
|
198
|
+
description: "Recipient email addresses",
|
|
199
|
+
},
|
|
200
|
+
subject: {
|
|
201
|
+
type: "string",
|
|
202
|
+
description: "Email subject",
|
|
203
|
+
},
|
|
204
|
+
body: {
|
|
205
|
+
type: "string",
|
|
206
|
+
description: "Email body (plain text or HTML)",
|
|
207
|
+
},
|
|
208
|
+
cc: {
|
|
209
|
+
type: "array",
|
|
210
|
+
items: { type: "string" },
|
|
211
|
+
description: "CC email addresses (optional)",
|
|
212
|
+
},
|
|
213
|
+
bcc: {
|
|
214
|
+
type: "array",
|
|
215
|
+
items: { type: "string" },
|
|
216
|
+
description: "BCC email addresses (optional)",
|
|
217
|
+
},
|
|
218
|
+
is_html: {
|
|
219
|
+
type: "boolean",
|
|
220
|
+
description: "Whether body is HTML (default: false)",
|
|
221
|
+
default: false,
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
required: ["to", "subject", "body"],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
name: "google_list_emails",
|
|
229
|
+
description: "List emails from Gmail inbox with optional search query. Returns email metadata including ID, subject, sender, and snippet.",
|
|
230
|
+
inputSchema: {
|
|
231
|
+
type: "object",
|
|
232
|
+
properties: {
|
|
233
|
+
query: {
|
|
234
|
+
type: "string",
|
|
235
|
+
description: "Gmail search query (e.g., 'from:alice@example.com', 'subject:meeting', 'is:unread')",
|
|
236
|
+
},
|
|
237
|
+
max_results: {
|
|
238
|
+
type: "number",
|
|
239
|
+
description: "Maximum number of emails to return (default: 10, max: 100)",
|
|
240
|
+
default: 10,
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: "google_read_email",
|
|
247
|
+
description: "Read the full content of an email by its ID. Returns subject, sender, recipients, body, and metadata.",
|
|
248
|
+
inputSchema: {
|
|
249
|
+
type: "object",
|
|
250
|
+
properties: {
|
|
251
|
+
email_id: {
|
|
252
|
+
type: "string",
|
|
253
|
+
description: "Email ID to read (from list_emails)",
|
|
254
|
+
},
|
|
255
|
+
mark_as_read: {
|
|
256
|
+
type: "boolean",
|
|
257
|
+
description: "Mark email as read after fetching (default: false)",
|
|
258
|
+
default: false,
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
required: ["email_id"],
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
];
|
|
265
|
+
// Register tools
|
|
266
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
267
|
+
return { tools };
|
|
268
|
+
});
|
|
269
|
+
// Handle tool calls
|
|
270
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
271
|
+
try {
|
|
272
|
+
const { name, arguments: args } = request.params;
|
|
273
|
+
if (!args) {
|
|
274
|
+
throw new Error("No arguments provided");
|
|
275
|
+
}
|
|
276
|
+
let result;
|
|
277
|
+
switch (name) {
|
|
278
|
+
case "google_create_calendar_event":
|
|
279
|
+
result = await createCalendarEvent(calendar, calendarId, args);
|
|
280
|
+
break;
|
|
281
|
+
case "google_list_calendar_events":
|
|
282
|
+
result = await listCalendarEvents(calendar, calendarId, args);
|
|
283
|
+
break;
|
|
284
|
+
case "google_update_calendar_event":
|
|
285
|
+
result = await updateCalendarEvent(calendar, calendarId, args);
|
|
286
|
+
break;
|
|
287
|
+
case "google_send_email":
|
|
288
|
+
result = await sendEmail(gmail, args);
|
|
289
|
+
break;
|
|
290
|
+
case "google_list_emails":
|
|
291
|
+
result = await listEmails(gmail, args);
|
|
292
|
+
break;
|
|
293
|
+
case "google_read_email":
|
|
294
|
+
result = await readEmail(gmail, args);
|
|
295
|
+
break;
|
|
296
|
+
default:
|
|
297
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
content: [{ type: "text", text: result }],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
return {
|
|
305
|
+
content: [
|
|
306
|
+
{
|
|
307
|
+
type: "text",
|
|
308
|
+
text: `Error: ${error.message}`,
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
isError: true,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
return server;
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=server-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-factory.js","sourceRoot":"","sources":["../src/server-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar tool implementations for Google Calendar MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export declare function createCalendarEvent(calendar: any, calendarId: string, args: any): Promise<string>;
|
|
5
|
+
export declare function listCalendarEvents(calendar: any, calendarId: string, args: any): Promise<string>;
|
|
6
|
+
export declare function updateCalendarEvent(calendar: any, calendarId: string, args: any): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=calendar-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-tools.d.ts","sourceRoot":"","sources":["../../src/tools/calendar-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,MAAM,CAAC,CAqCjB;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,MAAM,CAAC,CAgDjB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar tool implementations for Google Calendar MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export async function createCalendarEvent(calendar, calendarId, args) {
|
|
5
|
+
try {
|
|
6
|
+
const event = {
|
|
7
|
+
summary: args.summary,
|
|
8
|
+
description: args.description,
|
|
9
|
+
location: args.location,
|
|
10
|
+
start: {
|
|
11
|
+
dateTime: args.start_time,
|
|
12
|
+
},
|
|
13
|
+
end: {
|
|
14
|
+
dateTime: args.end_time,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
if (args.attendees && Array.isArray(args.attendees)) {
|
|
18
|
+
event.attendees = args.attendees.map((email) => ({ email }));
|
|
19
|
+
}
|
|
20
|
+
if (args.reminders && Array.isArray(args.reminders)) {
|
|
21
|
+
event.reminders = {
|
|
22
|
+
useDefault: false,
|
|
23
|
+
overrides: args.reminders,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const sendUpdates = args.send_notifications !== false ? "all" : "none";
|
|
27
|
+
const response = await calendar.events.insert({
|
|
28
|
+
calendarId: calendarId,
|
|
29
|
+
requestBody: event,
|
|
30
|
+
sendUpdates,
|
|
31
|
+
});
|
|
32
|
+
return `Event created successfully: ${response.data.htmlLink}\nEvent ID: ${response.data.id}`;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw new Error(`Failed to create calendar event: ${error.message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function listCalendarEvents(calendar, calendarId, args) {
|
|
39
|
+
try {
|
|
40
|
+
const response = await calendar.events.list({
|
|
41
|
+
calendarId: calendarId,
|
|
42
|
+
timeMin: args.time_min || new Date().toISOString(),
|
|
43
|
+
timeMax: args.time_max,
|
|
44
|
+
maxResults: args.max_results || 10,
|
|
45
|
+
singleEvents: true,
|
|
46
|
+
orderBy: "startTime",
|
|
47
|
+
});
|
|
48
|
+
const events = response.data.items;
|
|
49
|
+
if (!events || events.length === 0) {
|
|
50
|
+
return "No upcoming events found.";
|
|
51
|
+
}
|
|
52
|
+
const eventList = events.map((event) => {
|
|
53
|
+
const start = event.start?.dateTime || event.start?.date;
|
|
54
|
+
return `- ${event.summary} (${start})${event.location ? ` at ${event.location}` : ""} [ID: ${event.id}]`;
|
|
55
|
+
});
|
|
56
|
+
return `Upcoming events:\n${eventList.join("\n")}`;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new Error(`Failed to list calendar events: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function updateCalendarEvent(calendar, calendarId, args) {
|
|
63
|
+
try {
|
|
64
|
+
// First, get the existing event
|
|
65
|
+
const existingEvent = await calendar.events.get({
|
|
66
|
+
calendarId: calendarId,
|
|
67
|
+
eventId: args.event_id,
|
|
68
|
+
});
|
|
69
|
+
// Build update object with only provided fields
|
|
70
|
+
const updates = {};
|
|
71
|
+
if (args.summary)
|
|
72
|
+
updates.summary = args.summary;
|
|
73
|
+
if (args.description)
|
|
74
|
+
updates.description = args.description;
|
|
75
|
+
if (args.location)
|
|
76
|
+
updates.location = args.location;
|
|
77
|
+
if (args.start_time) {
|
|
78
|
+
updates.start = { dateTime: args.start_time };
|
|
79
|
+
}
|
|
80
|
+
if (args.end_time) {
|
|
81
|
+
updates.end = { dateTime: args.end_time };
|
|
82
|
+
}
|
|
83
|
+
if (args.attendees && Array.isArray(args.attendees)) {
|
|
84
|
+
updates.attendees = args.attendees.map((email) => ({ email }));
|
|
85
|
+
}
|
|
86
|
+
if (args.reminders && Array.isArray(args.reminders)) {
|
|
87
|
+
updates.reminders = {
|
|
88
|
+
useDefault: false,
|
|
89
|
+
overrides: args.reminders,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Merge with existing event data
|
|
93
|
+
const updatedEvent = {
|
|
94
|
+
...existingEvent.data,
|
|
95
|
+
...updates,
|
|
96
|
+
};
|
|
97
|
+
const sendUpdates = args.send_notifications !== false ? "all" : "none";
|
|
98
|
+
const response = await calendar.events.update({
|
|
99
|
+
calendarId: calendarId,
|
|
100
|
+
eventId: args.event_id,
|
|
101
|
+
requestBody: updatedEvent,
|
|
102
|
+
sendUpdates,
|
|
103
|
+
});
|
|
104
|
+
return `Event updated successfully: ${response.data.htmlLink}\nEvent ID: ${response.data.id}`;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
throw new Error(`Failed to update calendar event: ${error.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=calendar-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-tools.js","sourceRoot":"","sources":["../../src/tools/calendar-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email tool implementations for Gmail MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export declare function sendEmail(gmail: any, args: any): Promise<string>;
|
|
5
|
+
export declare function listEmails(gmail: any, args: any): Promise<string>;
|
|
6
|
+
export declare function readEmail(gmail: any, args: any): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=email-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-tools.d.ts","sourceRoot":"","sources":["../../src/tools/email-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAsB,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAmEtE;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCvE;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CtE"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email tool implementations for Gmail MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export async function sendEmail(gmail, args) {
|
|
5
|
+
try {
|
|
6
|
+
const to = Array.isArray(args.to) ? args.to.join(", ") : args.to;
|
|
7
|
+
const cc = args.cc && Array.isArray(args.cc) ? args.cc.join(", ") : "";
|
|
8
|
+
const bcc = args.bcc && Array.isArray(args.bcc) ? args.bcc.join(", ") : "";
|
|
9
|
+
let message;
|
|
10
|
+
if (args.is_html) {
|
|
11
|
+
// For HTML emails, create a multipart/alternative message with both plain text and HTML
|
|
12
|
+
const boundary = "===============" + Date.now() + "==";
|
|
13
|
+
const plainText = args.body.replace(/<[^>]*>/g, ''); // Strip HTML tags for plain text version
|
|
14
|
+
// Build MIME multipart message - blank lines are critical!
|
|
15
|
+
const parts = [];
|
|
16
|
+
parts.push(`To: ${to}`);
|
|
17
|
+
if (cc)
|
|
18
|
+
parts.push(`Cc: ${cc}`);
|
|
19
|
+
if (bcc)
|
|
20
|
+
parts.push(`Bcc: ${bcc}`);
|
|
21
|
+
parts.push(`Subject: ${args.subject}`);
|
|
22
|
+
parts.push(`MIME-Version: 1.0`);
|
|
23
|
+
parts.push(`Content-Type: multipart/alternative; boundary="${boundary}"`);
|
|
24
|
+
parts.push(``); // CRITICAL blank line after headers
|
|
25
|
+
parts.push(`--${boundary}`);
|
|
26
|
+
parts.push(`Content-Type: text/plain; charset=utf-8`);
|
|
27
|
+
parts.push(`Content-Transfer-Encoding: 7bit`);
|
|
28
|
+
parts.push(``); // CRITICAL blank line before content
|
|
29
|
+
parts.push(plainText);
|
|
30
|
+
parts.push(``); // blank line after content
|
|
31
|
+
parts.push(`--${boundary}`);
|
|
32
|
+
parts.push(`Content-Type: text/html; charset=utf-8`);
|
|
33
|
+
parts.push(`Content-Transfer-Encoding: 7bit`);
|
|
34
|
+
parts.push(``); // CRITICAL blank line before content
|
|
35
|
+
parts.push(args.body);
|
|
36
|
+
parts.push(``); // blank line after content
|
|
37
|
+
parts.push(`--${boundary}--`);
|
|
38
|
+
const messageParts = parts;
|
|
39
|
+
message = messageParts.join("\r\n");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// For plain text emails, use simple format
|
|
43
|
+
const messageParts = [
|
|
44
|
+
`To: ${to}`,
|
|
45
|
+
cc ? `Cc: ${cc}` : "",
|
|
46
|
+
bcc ? `Bcc: ${bcc}` : "",
|
|
47
|
+
`Subject: ${args.subject}`,
|
|
48
|
+
`Content-Type: text/plain; charset=utf-8`,
|
|
49
|
+
"",
|
|
50
|
+
args.body,
|
|
51
|
+
].filter(Boolean);
|
|
52
|
+
message = messageParts.join("\r\n");
|
|
53
|
+
}
|
|
54
|
+
const encodedMessage = Buffer.from(message).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
55
|
+
const response = await gmail.users.messages.send({
|
|
56
|
+
userId: "me",
|
|
57
|
+
requestBody: {
|
|
58
|
+
raw: encodedMessage,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
return `Email sent successfully!\nMessage ID: ${response.data.id}\nTo: ${to}${cc ? `\nCC: ${cc}` : ""}`;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
throw new Error(`Failed to send email: ${error.message}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export async function listEmails(gmail, args) {
|
|
68
|
+
try {
|
|
69
|
+
const response = await gmail.users.messages.list({
|
|
70
|
+
userId: "me",
|
|
71
|
+
q: args.query || "",
|
|
72
|
+
maxResults: Math.min(args.max_results || 10, 100),
|
|
73
|
+
});
|
|
74
|
+
const messages = response.data.messages;
|
|
75
|
+
if (!messages || messages.length === 0) {
|
|
76
|
+
return "No emails found.";
|
|
77
|
+
}
|
|
78
|
+
// Fetch details for each message
|
|
79
|
+
const emailDetails = await Promise.all(messages.map(async (msg) => {
|
|
80
|
+
const details = await gmail.users.messages.get({
|
|
81
|
+
userId: "me",
|
|
82
|
+
id: msg.id,
|
|
83
|
+
format: "metadata",
|
|
84
|
+
metadataHeaders: ["From", "Subject", "Date"],
|
|
85
|
+
});
|
|
86
|
+
const headers = details.data.payload?.headers || [];
|
|
87
|
+
const from = headers.find((h) => h.name === "From")?.value || "Unknown";
|
|
88
|
+
const subject = headers.find((h) => h.name === "Subject")?.value || "(No subject)";
|
|
89
|
+
const date = headers.find((h) => h.name === "Date")?.value || "";
|
|
90
|
+
return `- ${subject}\n From: ${from}\n Date: ${date}\n ID: ${msg.id}`;
|
|
91
|
+
}));
|
|
92
|
+
return `Emails:\n${emailDetails.join("\n\n")}`;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
throw new Error(`Failed to list emails: ${error.message}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export async function readEmail(gmail, args) {
|
|
99
|
+
try {
|
|
100
|
+
const response = await gmail.users.messages.get({
|
|
101
|
+
userId: "me",
|
|
102
|
+
id: args.email_id,
|
|
103
|
+
format: "full",
|
|
104
|
+
});
|
|
105
|
+
const headers = response.data.payload?.headers || [];
|
|
106
|
+
const from = headers.find((h) => h.name === "From")?.value || "Unknown";
|
|
107
|
+
const to = headers.find((h) => h.name === "To")?.value || "";
|
|
108
|
+
const cc = headers.find((h) => h.name === "Cc")?.value || "";
|
|
109
|
+
const bcc = headers.find((h) => h.name === "Bcc")?.value || "";
|
|
110
|
+
const subject = headers.find((h) => h.name === "Subject")?.value || "(No subject)";
|
|
111
|
+
const date = headers.find((h) => h.name === "Date")?.value || "";
|
|
112
|
+
// Extract email body
|
|
113
|
+
let body = "";
|
|
114
|
+
if (response.data.payload?.parts) {
|
|
115
|
+
const textPart = response.data.payload.parts.find((part) => part.mimeType === "text/plain");
|
|
116
|
+
if (textPart?.body?.data) {
|
|
117
|
+
body = Buffer.from(textPart.body.data, "base64").toString("utf-8");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if (response.data.payload?.body?.data) {
|
|
121
|
+
body = Buffer.from(response.data.payload.body.data, "base64").toString("utf-8");
|
|
122
|
+
}
|
|
123
|
+
// Mark as read if requested
|
|
124
|
+
if (args.mark_as_read) {
|
|
125
|
+
await gmail.users.messages.modify({
|
|
126
|
+
userId: "me",
|
|
127
|
+
id: args.email_id,
|
|
128
|
+
requestBody: {
|
|
129
|
+
removeLabelIds: ["UNREAD"],
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const ccLine = cc ? `\nCC: ${cc}` : "";
|
|
134
|
+
const bccLine = bcc ? `\nBCC: ${bcc}` : "";
|
|
135
|
+
return `From: ${from}\nTo: ${to}${ccLine}${bccLine}\nSubject: ${subject}\nDate: ${date}\n\n${body}`;
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new Error(`Failed to read email: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=email-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-tools.js","sourceRoot":"","sources":["../../src/tools/email-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prmichaelsen/google-calendar-mcp",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Google Calendar and Gmail MCP Server with Service Account Authentication",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "build/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./build/index.js",
|
|
9
|
+
"./factory": "./build/server-factory.js",
|
|
10
|
+
"./tools/calendar": "./build/tools/calendar-tools.js",
|
|
11
|
+
"./tools/email": "./build/tools/email-tools.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"build/**/*",
|
|
15
|
+
"README.md",
|
|
16
|
+
"CHANGELOG.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"start": "node build/index.js",
|
|
21
|
+
"dev": "tsc && node build/index.js"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mcp",
|
|
25
|
+
"google-calendar",
|
|
26
|
+
"gmail",
|
|
27
|
+
"service-account",
|
|
28
|
+
"model-context-protocol",
|
|
29
|
+
"multi-tenant",
|
|
30
|
+
"factory"
|
|
31
|
+
],
|
|
32
|
+
"author": "prmichaelsen",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/prmichaelsen/calendar-mcp-server.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/prmichaelsen/calendar-mcp-server/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/prmichaelsen/calendar-mcp-server#readme",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
44
|
+
"googleapis": "^144.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"typescript": "^5.6.0"
|
|
49
|
+
}
|
|
50
|
+
}
|