gogcli-mcp-calendar 2.28.0 → 2.29.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/dist/index.js +116 -9
- package/manifest.json +2 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -31323,6 +31323,77 @@ function redactSecrets(text) {
|
|
|
31323
31323
|
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
31324
31324
|
}
|
|
31325
31325
|
|
|
31326
|
+
// ../../node_modules/@chrischall/mcp-utils/dist/response/view.js
|
|
31327
|
+
var VIEWS = ["compact", "full", "raw"];
|
|
31328
|
+
var DEFAULT_VIEW = "compact";
|
|
31329
|
+
var BLURB = {
|
|
31330
|
+
compact: '"compact" (default) drops fields the response already carries elsewhere',
|
|
31331
|
+
full: '"full" returns every field this server understands',
|
|
31332
|
+
raw: '"raw" returns the upstream payload unprojected'
|
|
31333
|
+
};
|
|
31334
|
+
function viewParam(honoured, opts = {}) {
|
|
31335
|
+
if (honoured.length < 2) {
|
|
31336
|
+
throw new Error("viewParam needs at least two rungs: a parameter offering one value decides nothing");
|
|
31337
|
+
}
|
|
31338
|
+
if (!honoured.includes("compact")) {
|
|
31339
|
+
throw new Error('viewParam must offer "compact": a tool with no cheap rung has nothing to default to');
|
|
31340
|
+
}
|
|
31341
|
+
const ordered = VIEWS.filter((v) => honoured.includes(v));
|
|
31342
|
+
const sentence = `Response shape: ${ordered.map((v) => BLURB[v]).join("; ")}.`;
|
|
31343
|
+
return external_exports.enum(Object.fromEntries(ordered.map((v) => [v, v]))).optional().describe(opts.note ? `${sentence} ${opts.note}` : sentence);
|
|
31344
|
+
}
|
|
31345
|
+
function resolveView(value, honoured) {
|
|
31346
|
+
return value !== void 0 && honoured.includes(value) ? value : DEFAULT_VIEW;
|
|
31347
|
+
}
|
|
31348
|
+
function minifiedResult(data) {
|
|
31349
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
31350
|
+
}
|
|
31351
|
+
|
|
31352
|
+
// ../../node_modules/@chrischall/mcp-utils/dist/response/media.js
|
|
31353
|
+
var MEDIA_NOUN = "(?:avatar|tall_avatar|cover_photo|cover_image|picture|photo|thumbnail|thumb|image|icon|banner|profile_pic(?:ture)?|logo)";
|
|
31354
|
+
var MEDIA_KEY = new RegExp(`^${MEDIA_NOUN}s?(?:(?:link|uri|url)s?)?$`, "i");
|
|
31355
|
+
var MEDIA_URL = /^https?:\/\/[^\s]+?\.(png|jpe?g|gif|webp|svg|avif|bmp|ico)([?#]|$)/i;
|
|
31356
|
+
function stripMediaUrls(value, opts = {}) {
|
|
31357
|
+
const keep = new Set((opts.keep ?? []).map((k) => k.toLowerCase()));
|
|
31358
|
+
const drop = (opts.drop ?? []).map((rule) => typeof rule === "string" ? rule.toLowerCase() : new RegExp(rule.source, rule.flags));
|
|
31359
|
+
return walk(value, keep, drop);
|
|
31360
|
+
}
|
|
31361
|
+
function alsoDrop(key, drop) {
|
|
31362
|
+
const lower = key.toLowerCase();
|
|
31363
|
+
for (const rule of drop) {
|
|
31364
|
+
if (typeof rule === "string") {
|
|
31365
|
+
if (rule === lower)
|
|
31366
|
+
return true;
|
|
31367
|
+
continue;
|
|
31368
|
+
}
|
|
31369
|
+
rule.lastIndex = 0;
|
|
31370
|
+
if (rule.test(key))
|
|
31371
|
+
return true;
|
|
31372
|
+
}
|
|
31373
|
+
return false;
|
|
31374
|
+
}
|
|
31375
|
+
function walk(value, keep, drop) {
|
|
31376
|
+
if (Array.isArray(value))
|
|
31377
|
+
return value.map((v) => walk(v, keep, drop));
|
|
31378
|
+
if (value === null || typeof value !== "object")
|
|
31379
|
+
return value;
|
|
31380
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
|
|
31381
|
+
return value;
|
|
31382
|
+
const out = {};
|
|
31383
|
+
for (const [key, v] of Object.entries(value)) {
|
|
31384
|
+
if (keep.has(key.toLowerCase())) {
|
|
31385
|
+
out[key] = v;
|
|
31386
|
+
continue;
|
|
31387
|
+
}
|
|
31388
|
+
if (MEDIA_KEY.test(key) || alsoDrop(key, drop))
|
|
31389
|
+
continue;
|
|
31390
|
+
if (typeof v === "string" && MEDIA_URL.test(v))
|
|
31391
|
+
continue;
|
|
31392
|
+
out[key] = walk(v, keep, drop);
|
|
31393
|
+
}
|
|
31394
|
+
return out;
|
|
31395
|
+
}
|
|
31396
|
+
|
|
31326
31397
|
// ../../node_modules/@chrischall/mcp-utils/dist/response/index.js
|
|
31327
31398
|
function rawTextResult(text) {
|
|
31328
31399
|
return { content: [{ type: "text", text }] };
|
|
@@ -31842,11 +31913,11 @@ function parseTimestampValue(key, value, assumeNaiveIn) {
|
|
|
31842
31913
|
}
|
|
31843
31914
|
return null;
|
|
31844
31915
|
}
|
|
31845
|
-
function
|
|
31916
|
+
function walk2(node, tz, naiveTz) {
|
|
31846
31917
|
let changed = false;
|
|
31847
31918
|
if (Array.isArray(node)) {
|
|
31848
31919
|
for (const item of node) {
|
|
31849
|
-
if (
|
|
31920
|
+
if (walk2(item, tz, naiveTz)) changed = true;
|
|
31850
31921
|
}
|
|
31851
31922
|
return changed;
|
|
31852
31923
|
}
|
|
@@ -31855,7 +31926,7 @@ function walk(node, tz, naiveTz) {
|
|
|
31855
31926
|
for (const key of Object.keys(obj)) {
|
|
31856
31927
|
const value = obj[key];
|
|
31857
31928
|
if (value !== null && typeof value === "object") {
|
|
31858
|
-
if (
|
|
31929
|
+
if (walk2(value, tz, naiveTz)) changed = true;
|
|
31859
31930
|
continue;
|
|
31860
31931
|
}
|
|
31861
31932
|
if (ZONE_NAME_KEYS.has(key) || !TIMESTAMP_KEYS.has(key)) continue;
|
|
@@ -31881,7 +31952,7 @@ function normalizeTimestamps(text, tz = displayTimeZone(), naiveTz = naiveSource
|
|
|
31881
31952
|
} catch {
|
|
31882
31953
|
return text;
|
|
31883
31954
|
}
|
|
31884
|
-
if (!
|
|
31955
|
+
if (!walk2(parsed, tz, naiveTz)) return text;
|
|
31885
31956
|
return JSON.stringify(parsed, null, detectIndent(text));
|
|
31886
31957
|
}
|
|
31887
31958
|
|
|
@@ -32046,10 +32117,38 @@ ${accounts || "(none)"}${hint}`);
|
|
|
32046
32117
|
return errorResult(`${errText}${hint}`);
|
|
32047
32118
|
}
|
|
32048
32119
|
}
|
|
32120
|
+
function minifiedOrRawText(text, stripMedia = false) {
|
|
32121
|
+
const trimmed = text.trim();
|
|
32122
|
+
if (trimmed === "" || !/^[[{]/.test(trimmed)) return rawTextResult(text);
|
|
32123
|
+
try {
|
|
32124
|
+
const parsed = JSON.parse(trimmed);
|
|
32125
|
+
return minifiedResult(stripMedia ? stripMediaUrls(parsed) : parsed);
|
|
32126
|
+
} catch {
|
|
32127
|
+
return rawTextResult(text);
|
|
32128
|
+
}
|
|
32129
|
+
}
|
|
32130
|
+
function isRejectedFieldMask(err) {
|
|
32131
|
+
return /invalidParameter|invalid field selection/i.test(String(err));
|
|
32132
|
+
}
|
|
32133
|
+
async function runProjected(args, options) {
|
|
32134
|
+
const { fieldsMask } = options;
|
|
32135
|
+
if (!fieldsMask) return run(args, options);
|
|
32136
|
+
try {
|
|
32137
|
+
return await run([...args, `--fields=${fieldsMask}`], options);
|
|
32138
|
+
} catch (err) {
|
|
32139
|
+
if (!isRejectedFieldMask(err)) throw err;
|
|
32140
|
+
process.stderr.write(
|
|
32141
|
+
`gogcli-mcp: Google rejected the compact field mask (${fieldsMask}); retrying unprojected
|
|
32142
|
+
`
|
|
32143
|
+
);
|
|
32144
|
+
return run(args, options);
|
|
32145
|
+
}
|
|
32146
|
+
}
|
|
32049
32147
|
async function runOrDiagnose(args, options) {
|
|
32050
32148
|
try {
|
|
32051
|
-
const raw = await
|
|
32052
|
-
|
|
32149
|
+
const raw = await runProjected(args, options);
|
|
32150
|
+
if (options.lossless) return rawTextResult(raw);
|
|
32151
|
+
return minifiedOrRawText(stripConsumedPageToken(normalizeTimestamps(raw)), options.stripMedia);
|
|
32053
32152
|
} catch (err) {
|
|
32054
32153
|
return diagnose(err);
|
|
32055
32154
|
}
|
|
@@ -32251,6 +32350,7 @@ function pushReminderFlags(args, p) {
|
|
|
32251
32350
|
}
|
|
32252
32351
|
for (const reminder of p.reminders) args.push(`--reminder=${reminder}`);
|
|
32253
32352
|
}
|
|
32353
|
+
var CALENDAR_EVENTS_COMPACT_FIELDS = "nextPageToken,items(id,summary,start,end,location,status,htmlLink)";
|
|
32254
32354
|
function registerCalendarTools(server) {
|
|
32255
32355
|
server.registerTool("gog_calendar_events", {
|
|
32256
32356
|
description: 'List calendar events. Describe the window ONE way and one way only (gog >= 0.36.0 rejects the rest as ambiguous rather than silently discarding a flag): today on its own; or from + to; or from + days; or days on its own (a window of that many days starting today). today cannot be combined with from, to or days, and days cannot be combined with to. gog returns only 10 events by default, so a wide date range is USUALLY INCOMPLETE: raise max, or page with pageToken until the response carries no nextPageToken. A response carrying "truncated": true is an incomplete view \u2014 never conclude an event does not exist from one.',
|
|
@@ -32273,9 +32373,12 @@ function registerCalendarTools(server) {
|
|
|
32273
32373
|
all: external_exports.boolean().optional().describe('Fetch events from ALL CALENDARS. NOTE: unlike the gmail search tools, this does NOT mean "all pages" \u2014 it widens the calendar set, not the page window. Use pageToken to reach later pages.'),
|
|
32274
32374
|
eventTypes: external_exports.array(external_exports.enum(["default", "birthday", "focus-time", "from-gmail", "out-of-office", "working-location"])).optional().describe("Filter to specific event types (repeatable)"),
|
|
32275
32375
|
timezone: external_exports.string().optional().describe(`Display timezone for event times (IANA name, e.g. America/New_York, or "local" for the system timezone). Default: each event's timezone, then its calendar's timezone.`),
|
|
32376
|
+
view: viewParam(["compact", "full"], {
|
|
32377
|
+
note: "compact (the default) drops description and attendees \u2014 together two thirds of a listing's bytes \u2014 plus etag/iCalUID/kind. Ask for full when you need a body or a guest list."
|
|
32378
|
+
}),
|
|
32276
32379
|
account: accountParam
|
|
32277
32380
|
}
|
|
32278
|
-
}, async ({ calendarId, from, to, days, today, query, max, pageToken, page, all, eventTypes, timezone, account }) => {
|
|
32381
|
+
}, async ({ calendarId, from, to, days, today, query, max, pageToken, page, all, eventTypes, timezone, view, account }) => {
|
|
32279
32382
|
const args = ["calendar", "events"];
|
|
32280
32383
|
if (calendarId) args.push(calendarId);
|
|
32281
32384
|
if (from) args.push(`--from=${from}`);
|
|
@@ -32289,7 +32392,11 @@ function registerCalendarTools(server) {
|
|
|
32289
32392
|
if (all) args.push("--all");
|
|
32290
32393
|
if (eventTypes) for (const t of eventTypes) args.push(`--event-types=${t}`);
|
|
32291
32394
|
if (timezone) args.push(`--timezone=${timezone}`);
|
|
32292
|
-
const
|
|
32395
|
+
const rung = resolveView(view, ["compact", "full"]);
|
|
32396
|
+
const result = await runOrDiagnose(args, {
|
|
32397
|
+
account,
|
|
32398
|
+
fieldsMask: rung === "compact" ? CALENDAR_EVENTS_COMPACT_FIELDS : void 0
|
|
32399
|
+
});
|
|
32293
32400
|
return annotateTruncatedList(result, "events");
|
|
32294
32401
|
});
|
|
32295
32402
|
server.registerTool("gog_calendar_get", {
|
|
@@ -32453,7 +32560,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
|
|
|
32453
32560
|
);
|
|
32454
32561
|
|
|
32455
32562
|
// ../gogcli-mcp/src/server.ts
|
|
32456
|
-
var VERSION = true ? "2.
|
|
32563
|
+
var VERSION = true ? "2.29.0" : "0.0.0";
|
|
32457
32564
|
|
|
32458
32565
|
// ../gogcli-mcp/src/auth-log.ts
|
|
32459
32566
|
var FAILURES = /* @__PURE__ */ new Set([
|
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.
|
|
6
|
+
"version": "2.29.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",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"name": "gog_calendar_events",
|
|
91
|
-
"description": "List calendar events;
|
|
91
|
+
"description": "List calendar events; compact by default (view=full for descriptions and attendees), paginated and flags a truncated range"
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"name": "gog_calendar_get",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-calendar",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.29.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,7 +24,7 @@
|
|
|
24
24
|
"test:coverage": "vitest run --coverage"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@chrischall/mcp-utils": "^0.
|
|
27
|
+
"@chrischall/mcp-utils": "^0.23.0",
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
29
29
|
"zod": "^4.4.3"
|
|
30
30
|
},
|