@pipeworx/mcp-google_calendar 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pipeworx
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # mcp-google_calendar
2
+
3
+ Google Calendar MCP Pack
4
+
5
+ Part of the [Pipeworx](https://pipeworx.io) open MCP gateway.
6
+
7
+ ## Tools
8
+
9
+ | Tool | Description |
10
+ |------|-------------|
11
+ | `gcal_list_events` | List events from a Google Calendar. Optionally filter by time range. Returns event summaries, times, attendees, and locations. |
12
+ | `gcal_get_event` | Get a specific Google Calendar event by ID. Returns full event details including summary, description, start/end times, attendees, location, and conferencing info. |
13
+ | `gcal_create_event` | Create a new event on a Google Calendar. Specify summary, start/end times, and optional description, location, and attendees. |
14
+ | `gcal_list_calendars` | List all calendars accessible by the authenticated user. Returns calendar IDs, summaries, time zones, and access roles. |
15
+ | `gcal_search_events` | Search for events across a calendar using a text query. Matches against event summary, description, location, and attendees. |
16
+
17
+ ## Quick Start
18
+
19
+ Add to your MCP client config:
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "google_calendar": {
25
+ "url": "https://gateway.pipeworx.io/google_calendar/mcp"
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ Or use the CLI:
32
+
33
+ ```bash
34
+ npx pipeworx use google_calendar
35
+ ```
36
+
37
+ ## License
38
+
39
+ MIT
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@pipeworx/mcp-google_calendar",
3
+ "version": "0.1.0",
4
+ "description": "Google Calendar MCP Pack",
5
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "types": "src/index.ts",
8
+ "keywords": ["mcp", "mcp-server", "model-context-protocol", "pipeworx", "google_calendar"],
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/pipeworx-io/mcp-google_calendar"
13
+ },
14
+ "scripts": {
15
+ "typecheck": "tsc --noEmit"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "^5.7.0"
19
+ }
20
+ }
package/server.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.pipeworx-io/google_calendar",
4
+ "title": "google_calendar",
5
+ "description": "Google Calendar MCP Pack",
6
+ "version": "0.1.0",
7
+ "websiteUrl": "https://pipeworx.io/packs/google_calendar",
8
+ "repository": {
9
+ "url": "https://github.com/pipeworx-io/mcp-google_calendar",
10
+ "source": "github"
11
+ },
12
+ "remotes": [
13
+ {
14
+ "type": "streamable-http",
15
+ "url": "https://gateway.pipeworx.io/google_calendar/mcp"
16
+ }
17
+ ]
18
+ }
package/src/index.ts ADDED
@@ -0,0 +1,196 @@
1
+ interface McpToolDefinition {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: 'object';
6
+ properties: Record<string, unknown>;
7
+ required?: string[];
8
+ };
9
+ }
10
+
11
+ interface McpToolExport {
12
+ tools: McpToolDefinition[];
13
+ callTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
14
+ }
15
+
16
+ /**
17
+ * Google Calendar MCP Pack
18
+ *
19
+ * Requires OAuth connection — gateway injects credentials via _context.google_calendar.
20
+ * Tools: list events, get event, create event, list calendars, search events.
21
+ */
22
+
23
+
24
+ interface CalendarContext {
25
+ google_calendar?: { accessToken: string };
26
+ }
27
+
28
+ const API = 'https://www.googleapis.com/calendar/v3';
29
+
30
+ async function gFetch(ctx: CalendarContext, url: string, options: RequestInit = {}) {
31
+ if (!ctx.google_calendar) {
32
+ return { error: 'connection_required', message: 'Connect your Google account at https://pipeworx.io/account' };
33
+ }
34
+ const res = await fetch(url, {
35
+ ...options,
36
+ headers: {
37
+ Authorization: `Bearer ${ctx.google_calendar.accessToken}`,
38
+ 'Content-Type': 'application/json',
39
+ ...(options.headers ?? {}),
40
+ },
41
+ });
42
+ if (!res.ok) {
43
+ const text = await res.text();
44
+ throw new Error(`Google Calendar API error (${res.status}): ${text}`);
45
+ }
46
+ return res.json();
47
+ }
48
+
49
+ const tools: McpToolExport['tools'] = [
50
+ {
51
+ name: 'gcal_list_events',
52
+ description: 'List events from a Google Calendar. Optionally filter by time range. Returns event summaries, times, attendees, and locations.',
53
+ inputSchema: {
54
+ type: 'object' as const,
55
+ properties: {
56
+ calendar_id: { type: 'string', description: 'Calendar ID (default: "primary" for the user\'s main calendar)' },
57
+ time_min: { type: 'string', description: 'Lower bound (inclusive) for event start time as RFC3339 timestamp (e.g., "2024-01-01T00:00:00Z")' },
58
+ time_max: { type: 'string', description: 'Upper bound (exclusive) for event end time as RFC3339 timestamp' },
59
+ max_results: { type: 'number', description: 'Maximum number of events to return (default 10, max 250)' },
60
+ order_by: { type: 'string', enum: ['startTime', 'updated'], description: 'Sort order (default: startTime). startTime requires singleEvents=true.' },
61
+ },
62
+ required: [],
63
+ },
64
+ },
65
+ {
66
+ name: 'gcal_get_event',
67
+ description: 'Get a specific Google Calendar event by ID. Returns full event details including summary, description, start/end times, attendees, location, and conferencing info.',
68
+ inputSchema: {
69
+ type: 'object' as const,
70
+ properties: {
71
+ calendar_id: { type: 'string', description: 'Calendar ID (default: "primary")' },
72
+ event_id: { type: 'string', description: 'The ID of the event to retrieve' },
73
+ },
74
+ required: ['event_id'],
75
+ },
76
+ },
77
+ {
78
+ name: 'gcal_create_event',
79
+ description: 'Create a new event on a Google Calendar. Specify summary, start/end times, and optional description, location, and attendees.',
80
+ inputSchema: {
81
+ type: 'object' as const,
82
+ properties: {
83
+ calendar_id: { type: 'string', description: 'Calendar ID (default: "primary")' },
84
+ summary: { type: 'string', description: 'Title of the event' },
85
+ start: { type: 'string', description: 'Start time as RFC3339 timestamp (e.g., "2024-06-15T10:00:00-07:00") or date for all-day events ("2024-06-15")' },
86
+ end: { type: 'string', description: 'End time as RFC3339 timestamp or date for all-day events' },
87
+ description: { type: 'string', description: 'Description or notes for the event' },
88
+ location: { type: 'string', description: 'Location of the event' },
89
+ attendees: {
90
+ type: 'array',
91
+ description: 'List of attendee email addresses',
92
+ items: { type: 'string' },
93
+ },
94
+ time_zone: { type: 'string', description: 'Time zone (e.g., "America/Los_Angeles"). Defaults to calendar\'s time zone.' },
95
+ },
96
+ required: ['summary', 'start', 'end'],
97
+ },
98
+ },
99
+ {
100
+ name: 'gcal_list_calendars',
101
+ description: 'List all calendars accessible by the authenticated user. Returns calendar IDs, summaries, time zones, and access roles.',
102
+ inputSchema: {
103
+ type: 'object' as const,
104
+ properties: {},
105
+ required: [],
106
+ },
107
+ },
108
+ {
109
+ name: 'gcal_search_events',
110
+ description: 'Search for events across a calendar using a text query. Matches against event summary, description, location, and attendees.',
111
+ inputSchema: {
112
+ type: 'object' as const,
113
+ properties: {
114
+ calendar_id: { type: 'string', description: 'Calendar ID (default: "primary")' },
115
+ query: { type: 'string', description: 'Free-text search query to match against event fields' },
116
+ time_min: { type: 'string', description: 'Lower bound for event start time as RFC3339 timestamp' },
117
+ time_max: { type: 'string', description: 'Upper bound for event end time as RFC3339 timestamp' },
118
+ max_results: { type: 'number', description: 'Maximum number of events to return (default 10, max 250)' },
119
+ },
120
+ required: ['query'],
121
+ },
122
+ },
123
+ ];
124
+
125
+ async function callTool(name: string, args: Record<string, unknown>): Promise<unknown> {
126
+ const context = (args._context ?? {}) as CalendarContext;
127
+ delete args._context;
128
+
129
+ switch (name) {
130
+ case 'gcal_list_events': {
131
+ const calendarId = (args.calendar_id as string) ?? 'primary';
132
+ const maxResults = Math.min(250, Math.max(1, (args.max_results as number) ?? 10));
133
+ const params = new URLSearchParams({
134
+ maxResults: String(maxResults),
135
+ singleEvents: 'true',
136
+ orderBy: (args.order_by as string) ?? 'startTime',
137
+ });
138
+ if (args.time_min) params.set('timeMin', args.time_min as string);
139
+ if (args.time_max) params.set('timeMax', args.time_max as string);
140
+ return gFetch(context, `${API}/calendars/${encodeURIComponent(calendarId)}/events?${params}`);
141
+ }
142
+ case 'gcal_get_event': {
143
+ const calendarId = (args.calendar_id as string) ?? 'primary';
144
+ const eventId = args.event_id as string;
145
+ return gFetch(context, `${API}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`);
146
+ }
147
+ case 'gcal_create_event': {
148
+ const calendarId = (args.calendar_id as string) ?? 'primary';
149
+ const { summary, start, end, description, location, attendees, time_zone } = args as {
150
+ summary: string; start: string; end: string; description?: string; location?: string;
151
+ attendees?: string[]; time_zone?: string;
152
+ };
153
+
154
+ const isAllDay = !start.includes('T');
155
+ const event: Record<string, unknown> = { summary };
156
+
157
+ if (isAllDay) {
158
+ event.start = { date: start };
159
+ event.end = { date: end };
160
+ } else {
161
+ event.start = { dateTime: start, timeZone: time_zone };
162
+ event.end = { dateTime: end, timeZone: time_zone };
163
+ }
164
+
165
+ if (description) event.description = description;
166
+ if (location) event.location = location;
167
+ if (attendees?.length) event.attendees = attendees.map((email) => ({ email }));
168
+
169
+ return gFetch(context, `${API}/calendars/${encodeURIComponent(calendarId)}/events`, {
170
+ method: 'POST',
171
+ body: JSON.stringify(event),
172
+ });
173
+ }
174
+ case 'gcal_list_calendars': {
175
+ return gFetch(context, `${API}/users/me/calendarList`);
176
+ }
177
+ case 'gcal_search_events': {
178
+ const calendarId = (args.calendar_id as string) ?? 'primary';
179
+ const query = args.query as string;
180
+ const maxResults = Math.min(250, Math.max(1, (args.max_results as number) ?? 10));
181
+ const params = new URLSearchParams({
182
+ q: query,
183
+ maxResults: String(maxResults),
184
+ singleEvents: 'true',
185
+ orderBy: 'startTime',
186
+ });
187
+ if (args.time_min) params.set('timeMin', args.time_min as string);
188
+ if (args.time_max) params.set('timeMax', args.time_max as string);
189
+ return gFetch(context, `${API}/calendars/${encodeURIComponent(calendarId)}/events?${params}`);
190
+ }
191
+ default:
192
+ throw new Error(`Unknown tool: ${name}`);
193
+ }
194
+ }
195
+
196
+ export default { tools, callTool, meter: { credits: 10 }, provider: 'google_calendar' } satisfies McpToolExport;
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "outDir": "dist",
10
+ "rootDir": "src",
11
+ "declaration": true
12
+ },
13
+ "include": ["src"]
14
+ }