gogcli-mcp-calendar 2.30.0 → 3.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/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-calendar",
5
5
  "display_name": "gogcli (Calendar)",
6
- "version": "2.30.0",
6
+ "version": "3.0.0",
7
7
  "description": "Extended Google Calendar for Claude via gogcli — auth + Calendar events + Meet space management",
8
8
  "author": {
9
9
  "name": "Chris Hall",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-calendar",
3
- "version": "2.30.0",
3
+ "version": "3.0.0",
4
4
  "mcpName": "io.github.chrischall/gogcli-mcp-calendar",
5
5
  "description": "Extended Google Calendar + Meet MCP server via gogcli — auth + Calendar events + Meet space management",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -24,8 +24,8 @@
24
24
  "test:coverage": "vitest run --coverage"
25
25
  },
26
26
  "dependencies": {
27
- "@chrischall/mcp-utils": "^0.23.3",
28
- "@modelcontextprotocol/sdk": "^1.30.0",
27
+ "@chrischall/mcp-utils": "^0.28.0",
28
+ "@modelcontextprotocol/server": "^2.0.0",
29
29
  "zod": "^4.6.1"
30
30
  },
31
31
  "license": "MIT",
@@ -1,4 +1,4 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { McpServer } from '@modelcontextprotocol/server';
2
2
  import { z } from 'zod';
3
3
  import { accountParam, runOrDiagnose, pageTokenParam, pageAliasParam, resolvePageToken} from '../../../gogcli-mcp/src/lib.js';
4
4
 
@@ -9,11 +9,11 @@ const meetAccess = z.enum(['open', 'trusted', 'restricted']);
9
9
  export function registerExtraCalendarTools(server: McpServer): void {
10
10
  server.registerTool('gog_meet_create', {
11
11
  description: 'Create a Google Meet space and return its meeting code.',
12
- inputSchema: {
12
+ inputSchema: z.object({
13
13
  access: meetAccess.optional().describe('Access type (default: trusted)'),
14
14
  open: z.boolean().optional().describe('Open the meeting in a browser after creation'),
15
15
  account: accountParam,
16
- },
16
+ }),
17
17
  }, async ({ access, open, account }) => {
18
18
  const args = ['meet', 'create'];
19
19
  if (access) args.push(`--access=${access}`);
@@ -24,10 +24,10 @@ export function registerExtraCalendarTools(server: McpServer): void {
24
24
  server.registerTool('gog_meet_get', {
25
25
  description: 'Get a Google Meet space by its meeting code.',
26
26
  annotations: { readOnlyHint: true },
27
- inputSchema: {
27
+ inputSchema: z.object({
28
28
  meetingCode: z.string().describe('Meeting code (e.g. abc-defg-hij)'),
29
29
  account: accountParam,
30
- },
30
+ }),
31
31
  }, async ({ meetingCode, account }) => {
32
32
  return runOrDiagnose(['meet', 'get', meetingCode], { account });
33
33
  });
@@ -35,11 +35,11 @@ export function registerExtraCalendarTools(server: McpServer): void {
35
35
  server.registerTool('gog_meet_update', {
36
36
  description: 'Update a Google Meet space configuration.',
37
37
  annotations: { destructiveHint: true },
38
- inputSchema: {
38
+ inputSchema: z.object({
39
39
  meetingCode: z.string().describe('Meeting code'),
40
40
  access: meetAccess.optional().describe('Access type'),
41
41
  account: accountParam,
42
- },
42
+ }),
43
43
  }, async ({ meetingCode, access, account }) => {
44
44
  const args = ['meet', 'update', meetingCode];
45
45
  if (access) args.push(`--access=${access}`);
@@ -49,10 +49,10 @@ export function registerExtraCalendarTools(server: McpServer): void {
49
49
  server.registerTool('gog_meet_end', {
50
50
  description: 'End the active conference in a Google Meet space.',
51
51
  annotations: { destructiveHint: true },
52
- inputSchema: {
52
+ inputSchema: z.object({
53
53
  meetingCode: z.string().describe('Meeting code'),
54
54
  account: accountParam,
55
- },
55
+ }),
56
56
  }, async ({ meetingCode, account }) => {
57
57
  return runOrDiagnose(['meet', 'end', meetingCode, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
58
58
  });
@@ -60,14 +60,14 @@ export function registerExtraCalendarTools(server: McpServer): void {
60
60
  server.registerTool('gog_meet_history', {
61
61
  description: 'List past calls (conferences) in a Google Meet space.',
62
62
  annotations: { readOnlyHint: true },
63
- inputSchema: {
63
+ inputSchema: z.object({
64
64
  meetingCode: z.string().describe('Meeting code'),
65
65
  max: z.number().optional().describe('Max results (default: 20)'),
66
66
  pageToken: pageTokenParam,
67
67
  page: pageAliasParam,
68
68
  all: z.boolean().optional().describe('Fetch all pages'),
69
69
  account: accountParam,
70
- },
70
+ }),
71
71
  }, async ({ meetingCode, max, pageToken, page, all, account }) => {
72
72
  const args = ['meet', 'history', meetingCode];
73
73
  if (max !== undefined) args.push(`--max=${max}`);
@@ -83,13 +83,13 @@ export function registerExtraCalendarTools(server: McpServer): void {
83
83
  server.registerTool('gog_zoom_auth_setup', {
84
84
  description: 'Store Zoom Server-to-Server (S2S) OAuth credentials so calendar events can be attached to Zoom meetings via the --with-zoom flag on gog_calendar_create / gog_calendar_update. Credentials are saved in gogcli\'s keyring under the given alias.',
85
85
  annotations: { destructiveHint: true },
86
- inputSchema: {
86
+ inputSchema: z.object({
87
87
  accountId: z.string().describe('Zoom S2S OAuth account ID'),
88
88
  clientId: z.string().describe('Zoom S2S OAuth client ID'),
89
89
  clientSecret: z.string().describe('Zoom S2S OAuth client secret'),
90
90
  alias: z.string().optional().describe('Zoom credential alias (default: "default")'),
91
91
  skipValidate: z.boolean().optional().describe('Store credentials without calling Zoom /users/me to validate'),
92
- },
92
+ }),
93
93
  }, async ({ accountId, clientId, clientSecret, alias, skipValidate }) => {
94
94
  const args = ['zoom', 'auth', 'setup'];
95
95
  if (alias) args.push(`--alias=${alias}`);
@@ -103,9 +103,9 @@ export function registerExtraCalendarTools(server: McpServer): void {
103
103
  server.registerTool('gog_zoom_auth_doctor', {
104
104
  description: 'Validate stored Zoom S2S OAuth credentials by calling Zoom /users/me.',
105
105
  annotations: { readOnlyHint: true },
106
- inputSchema: {
106
+ inputSchema: z.object({
107
107
  alias: z.string().optional().describe('Zoom credential alias to check (default: "default")'),
108
- },
108
+ }),
109
109
  }, async ({ alias }) => {
110
110
  const args = ['zoom', 'auth', 'doctor'];
111
111
  if (alias) args.push(`--alias=${alias}`);
@@ -117,13 +117,13 @@ export function registerExtraCalendarTools(server: McpServer): void {
117
117
  server.registerTool('gog_calendar_calendars', {
118
118
  description: 'List the calendars in your calendar list (id, summary, access role, primary flag).',
119
119
  annotations: { readOnlyHint: true },
120
- inputSchema: {
120
+ inputSchema: z.object({
121
121
  max: z.number().optional().describe('Max results (default: 100)'),
122
122
  pageToken: pageTokenParam,
123
123
  page: pageAliasParam,
124
124
  all: z.boolean().optional().describe('Fetch all pages'),
125
125
  account: accountParam,
126
- },
126
+ }),
127
127
  }, async ({ max, pageToken, page, all, account }) => {
128
128
  const args = ['calendar', 'calendars'];
129
129
  if (max !== undefined) args.push(`--max=${max}`);
@@ -138,7 +138,7 @@ export function registerExtraCalendarTools(server: McpServer): void {
138
138
  + 'Describe the window ONE way only (gog >= 0.36.0 rejects the rest as ambiguous instead of discarding a flag): one of today / tomorrow / week on its own, '
139
139
  + 'or from + to, or from + days, or days on its own. The fixed presets cannot be combined with from, to or days, and days cannot be combined with to.',
140
140
  annotations: { readOnlyHint: true },
141
- inputSchema: {
141
+ inputSchema: z.object({
142
142
  query: z.string().describe('Search query'),
143
143
  from: z.string().optional().describe('Start time (RFC3339, date, or relative: now, today, tomorrow, monday)'),
144
144
  to: z.string().optional().describe('End time (RFC3339, date, or relative: now, today, tomorrow, monday). Mutually exclusive with days.'),
@@ -153,7 +153,7 @@ export function registerExtraCalendarTools(server: McpServer): void {
153
153
  calendar: z.string().optional().describe('Calendar ID (default: primary)'),
154
154
  max: z.number().optional().describe('Max results (default: 25)'),
155
155
  account: accountParam,
156
- },
156
+ }),
157
157
  }, async ({ query, from, to, today, tomorrow, week, days, weekStart, calendar, max, account }) => {
158
158
  const args = ['calendar', 'search', query];
159
159
  if (from) args.push(`--from=${from}`);
@@ -171,14 +171,14 @@ export function registerExtraCalendarTools(server: McpServer): void {
171
171
  server.registerTool('gog_calendar_changed', {
172
172
  description: 'List most recently changed events (including cancellations/deletions) across one or more calendars, ordered by last-modification time. Requires gog >= 0.31.1.',
173
173
  annotations: { readOnlyHint: true },
174
- inputSchema: {
174
+ inputSchema: z.object({
175
175
  calendarId: z.string().optional().describe('Calendar ID (default: primary)'),
176
176
  calendarIds: z.string().optional().describe('Comma-separated calendar IDs, names, or indices'),
177
177
  since: z.string().optional().describe('Lower bound for last-modification time (RFC3339, date, or Go duration like 24h, 168h; default: 720h / 30 days). Google rejects windows too far in the past (410 updatedMinTooLongAgo) — retry with a shorter duration if that happens'),
178
178
  max: z.number().optional().describe('Max results (default: 10)'),
179
179
  all: z.boolean().optional().describe('Fetch from all calendars'),
180
180
  account: accountParam,
181
- },
181
+ }),
182
182
  }, async ({ calendarId, calendarIds, since, max, all, account }) => {
183
183
  const args = ['calendar', 'changed'];
184
184
  if (calendarId) args.push(calendarId);
@@ -192,13 +192,13 @@ export function registerExtraCalendarTools(server: McpServer): void {
192
192
  server.registerTool('gog_calendar_freebusy', {
193
193
  description: 'Query free/busy intervals for one or more calendars over a time window.',
194
194
  annotations: { readOnlyHint: true },
195
- inputSchema: {
195
+ inputSchema: z.object({
196
196
  from: z.string().describe('Start time (RFC3339, required)'),
197
197
  to: z.string().describe('End time (RFC3339, required)'),
198
198
  calendarIds: z.string().optional().describe('Comma-separated calendar IDs, names, or indices'),
199
199
  all: z.boolean().optional().describe('Query all calendars'),
200
200
  account: accountParam,
201
- },
201
+ }),
202
202
  }, async ({ from, to, calendarIds, all, account }) => {
203
203
  const args = ['calendar', 'freebusy'];
204
204
  if (calendarIds) args.push(calendarIds);
@@ -211,9 +211,9 @@ export function registerExtraCalendarTools(server: McpServer): void {
211
211
  server.registerTool('gog_calendar_colors', {
212
212
  description: 'Show the available calendar and event color palette (color IDs to hex values).',
213
213
  annotations: { readOnlyHint: true },
214
- inputSchema: {
214
+ inputSchema: z.object({
215
215
  account: accountParam,
216
- },
216
+ }),
217
217
  }, async ({ account }) => {
218
218
  return runOrDiagnose(['calendar', 'colors'], { account });
219
219
  });
@@ -221,14 +221,14 @@ export function registerExtraCalendarTools(server: McpServer): void {
221
221
  server.registerTool('gog_calendar_acl', {
222
222
  description: 'List the access control list (sharing rules) for a calendar.',
223
223
  annotations: { readOnlyHint: true },
224
- inputSchema: {
224
+ inputSchema: z.object({
225
225
  calendarId: z.string().describe('Calendar ID'),
226
226
  max: z.number().optional().describe('Max results (default: 100)'),
227
227
  pageToken: pageTokenParam,
228
228
  page: pageAliasParam,
229
229
  all: z.boolean().optional().describe('Fetch all pages'),
230
230
  account: accountParam,
231
- },
231
+ }),
232
232
  }, async ({ calendarId, max, pageToken, page, all, account }) => {
233
233
  const args = ['calendar', 'acl', calendarId];
234
234
  if (max !== undefined) args.push(`--max=${max}`);
@@ -240,13 +240,13 @@ export function registerExtraCalendarTools(server: McpServer): void {
240
240
 
241
241
  server.registerTool('gog_calendar_move', {
242
242
  description: 'Move an event from one calendar to another; the destination calendar becomes the organizer.',
243
- inputSchema: {
243
+ inputSchema: z.object({
244
244
  calendarId: z.string().describe('Source calendar ID'),
245
245
  eventId: z.string().describe('Event ID'),
246
246
  destinationCalendarId: z.string().describe('Destination calendar ID that becomes the event organizer'),
247
247
  sendUpdates: z.enum(['all', 'externalOnly', 'none']).optional().describe('Notification mode (default: none)'),
248
248
  account: accountParam,
249
- },
249
+ }),
250
250
  }, async ({ calendarId, eventId, destinationCalendarId, sendUpdates, account }) => {
251
251
  const args = ['calendar', 'move', calendarId, eventId, destinationCalendarId];
252
252
  if (sendUpdates) args.push(`--send-updates=${sendUpdates}`);
@@ -255,7 +255,7 @@ export function registerExtraCalendarTools(server: McpServer): void {
255
255
 
256
256
  server.registerTool('gog_calendar_out_of_office', {
257
257
  description: 'Create an Out of Office event that auto-declines invitations during the block.',
258
- inputSchema: {
258
+ inputSchema: z.object({
259
259
  from: z.string().describe('Start date or datetime (RFC3339 or YYYY-MM-DD)'),
260
260
  to: z.string().describe('End date or datetime (RFC3339 or YYYY-MM-DD)'),
261
261
  calendarId: z.string().optional().describe('Calendar ID (default: primary)'),
@@ -264,7 +264,7 @@ export function registerExtraCalendarTools(server: McpServer): void {
264
264
  declineMessage: z.string().optional().describe('Message for declined invitations'),
265
265
  allDay: z.boolean().optional().describe('Create as an all-day event'),
266
266
  account: accountParam,
267
- },
267
+ }),
268
268
  }, async ({ from, to, calendarId, summary, autoDecline, declineMessage, allDay, account }) => {
269
269
  const args = ['calendar', 'out-of-office'];
270
270
  if (calendarId) args.push(calendarId);
@@ -280,10 +280,10 @@ export function registerExtraCalendarTools(server: McpServer): void {
280
280
  server.registerTool('gog_calendar_unsubscribe', {
281
281
  description: 'Remove a calendar from your calendar list (the underlying calendar is not deleted — you can re-subscribe). For deleting a secondary calendar you own, use gog_calendar_delete_calendar.',
282
282
  annotations: { destructiveHint: true },
283
- inputSchema: {
283
+ inputSchema: z.object({
284
284
  calendarId: z.string().describe('Calendar ID or alias to remove from your calendar list'),
285
285
  account: accountParam,
286
- },
286
+ }),
287
287
  }, async ({ calendarId, account }) => {
288
288
  return runOrDiagnose(['calendar', 'unsubscribe', calendarId], { account });
289
289
  });
@@ -291,10 +291,10 @@ export function registerExtraCalendarTools(server: McpServer): void {
291
291
  server.registerTool('gog_calendar_delete_calendar', {
292
292
  description: 'Permanently delete an owned secondary calendar and all its events. Cannot delete your primary calendar. To merely remove a calendar you do not own from your list, use gog_calendar_unsubscribe.',
293
293
  annotations: { destructiveHint: true },
294
- inputSchema: {
294
+ inputSchema: z.object({
295
295
  calendarId: z.string().describe('Owned secondary calendar ID or alias'),
296
296
  account: accountParam,
297
- },
297
+ }),
298
298
  }, async ({ calendarId, account }) => {
299
299
  return runOrDiagnose(['calendar', 'delete-calendar', calendarId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
300
300
  });
@@ -302,7 +302,7 @@ export function registerExtraCalendarTools(server: McpServer): void {
302
302
  server.registerTool('gog_meet_participants', {
303
303
  description: 'List participants from the latest (or a specific) Meet call.',
304
304
  annotations: { readOnlyHint: true },
305
- inputSchema: {
305
+ inputSchema: z.object({
306
306
  meetingCode: z.string().describe('Meeting code'),
307
307
  conference: z.string().optional().describe('Specific conference ID (default: most recent)'),
308
308
  max: z.number().optional().describe('Max results (default: 50)'),
@@ -310,7 +310,7 @@ export function registerExtraCalendarTools(server: McpServer): void {
310
310
  page: pageAliasParam,
311
311
  all: z.boolean().optional().describe('Fetch all pages'),
312
312
  account: accountParam,
313
- },
313
+ }),
314
314
  }, async ({ meetingCode, conference, max, pageToken, page, all, account }) => {
315
315
  const args = ['meet', 'participants', meetingCode];
316
316
  if (conference) args.push(`--conference=${conference}`);