gogcli-mcp-calendar 2.25.0 → 2.27.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 +125 -43
- package/manifest.json +1 -1
- package/mint.yaml +107 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -31000,9 +31000,82 @@ var StdioServerTransport = class {
|
|
|
31000
31000
|
}
|
|
31001
31001
|
};
|
|
31002
31002
|
|
|
31003
|
+
// ../../node_modules/@chrischall/mcp-utils/dist/errors/index.js
|
|
31004
|
+
var McpToolError = class extends Error {
|
|
31005
|
+
/** Actionable remediation text, when one applies. */
|
|
31006
|
+
hint;
|
|
31007
|
+
constructor(message, opts) {
|
|
31008
|
+
super(message, opts?.cause !== void 0 ? { cause: opts.cause } : void 0);
|
|
31009
|
+
this.name = "McpToolError";
|
|
31010
|
+
if (opts?.hint !== void 0)
|
|
31011
|
+
this.hint = opts.hint;
|
|
31012
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
31013
|
+
}
|
|
31014
|
+
};
|
|
31015
|
+
var BEARER_RE = /(bearer\s+)[A-Za-z0-9._~+/=-]{8,}/gi;
|
|
31016
|
+
var JWT_RE = /\b[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{8,}\b/g;
|
|
31017
|
+
var BASIC_AUTH_RE = /(authorization\s*:\s*basic\s+)[A-Za-z0-9+/=_-]{6,}/gi;
|
|
31018
|
+
var SET_COOKIE_RE = /(\bset-cookie\s*:\s*)([^=;,\s]+)=[^;,\s]*/gi;
|
|
31019
|
+
var COOKIE_HEADER_RE = /((?<!set-)\bcookie\s*:\s*)((?:[^=;,\s]+=[^;,\s]*)(?:;\s*[^=;,\s]+=[^;,\s]*)*)/gi;
|
|
31020
|
+
var API_KEY_RE = new RegExp([
|
|
31021
|
+
"sk-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])",
|
|
31022
|
+
// OpenAI / Anthropic (incl. sk-ant-…)
|
|
31023
|
+
"gh[pousr]_[A-Za-z0-9]{36,}\\b",
|
|
31024
|
+
// GitHub ghp_/gho_/ghu_/ghs_/ghr_
|
|
31025
|
+
"xox[baprs]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])",
|
|
31026
|
+
// Slack
|
|
31027
|
+
"AIza[0-9A-Za-z_-]{35}(?![0-9A-Za-z_-])",
|
|
31028
|
+
// Google API key (39 chars total)
|
|
31029
|
+
"AKIA[0-9A-Z]{16}\\b",
|
|
31030
|
+
// AWS access key id (20 chars total)
|
|
31031
|
+
"whsec_[A-Za-z0-9]{16,}\\b"
|
|
31032
|
+
// webhook signing secret (Stripe-style)
|
|
31033
|
+
].map((p) => `\\b${p}`).join("|"), "g");
|
|
31034
|
+
var QUERY_SECRET_RE = /([?&](?:access_token|refresh_token|client_secret|api_?key|signature|token|key|sig)=)[^&#\s"'<>`]+/gi;
|
|
31035
|
+
var AWS_SIGV4_RE = /([?&]X-Amz-(?:Signature|Security-Token|Credential)=)[^&#\s"'<>`]+/gi;
|
|
31036
|
+
var JSON_SECRET_KEYS = "access_token|refresh_token|client_secret|api_?key|password|passwd|secret|token";
|
|
31037
|
+
var JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")[^"]*(")`, "gi");
|
|
31038
|
+
var JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')[^']*(')`, "gi");
|
|
31039
|
+
function redactSecrets(text) {
|
|
31040
|
+
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]");
|
|
31041
|
+
}
|
|
31042
|
+
|
|
31043
|
+
// ../../node_modules/@chrischall/mcp-utils/dist/response/index.js
|
|
31044
|
+
function rawTextResult(text) {
|
|
31045
|
+
return { content: [{ type: "text", text }] };
|
|
31046
|
+
}
|
|
31047
|
+
function errorResult(message) {
|
|
31048
|
+
return {
|
|
31049
|
+
content: [{ type: "text", text: redactSecrets(message) }],
|
|
31050
|
+
isError: true
|
|
31051
|
+
};
|
|
31052
|
+
}
|
|
31053
|
+
|
|
31003
31054
|
// ../../node_modules/@chrischall/mcp-utils/dist/server/index.js
|
|
31055
|
+
function hintResultOrRethrow(err) {
|
|
31056
|
+
if (err instanceof McpToolError && err.hint) {
|
|
31057
|
+
return errorResult(`${err.message}
|
|
31058
|
+
|
|
31059
|
+
Hint: ${err.hint}`);
|
|
31060
|
+
}
|
|
31061
|
+
throw err;
|
|
31062
|
+
}
|
|
31063
|
+
function surfaceToolHints(server) {
|
|
31064
|
+
const register = server.registerTool.bind(server);
|
|
31065
|
+
server.registerTool = (name, config2, cb) => register(name, config2, (...args) => {
|
|
31066
|
+
let result;
|
|
31067
|
+
try {
|
|
31068
|
+
result = cb(...args);
|
|
31069
|
+
} catch (err) {
|
|
31070
|
+
return hintResultOrRethrow(err);
|
|
31071
|
+
}
|
|
31072
|
+
return result instanceof Promise ? result.catch(hintResultOrRethrow) : result;
|
|
31073
|
+
});
|
|
31074
|
+
}
|
|
31004
31075
|
async function createMcpServer(opts) {
|
|
31005
31076
|
const server = new McpServer({ name: opts.name, version: opts.version });
|
|
31077
|
+
if (opts.surfaceHints !== false)
|
|
31078
|
+
surfaceToolHints(server);
|
|
31006
31079
|
if (opts.banner !== void 0) {
|
|
31007
31080
|
console.error(opts.banner);
|
|
31008
31081
|
}
|
|
@@ -31047,46 +31120,6 @@ async function runMcp(opts) {
|
|
|
31047
31120
|
return server;
|
|
31048
31121
|
}
|
|
31049
31122
|
|
|
31050
|
-
// ../../node_modules/@chrischall/mcp-utils/dist/errors/index.js
|
|
31051
|
-
var BEARER_RE = /(bearer\s+)[A-Za-z0-9._~+/=-]{8,}/gi;
|
|
31052
|
-
var JWT_RE = /\b[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{8,}\b/g;
|
|
31053
|
-
var BASIC_AUTH_RE = /(authorization\s*:\s*basic\s+)[A-Za-z0-9+/=_-]{6,}/gi;
|
|
31054
|
-
var SET_COOKIE_RE = /(\bset-cookie\s*:\s*)([^=;,\s]+)=[^;,\s]*/gi;
|
|
31055
|
-
var COOKIE_HEADER_RE = /((?<!set-)\bcookie\s*:\s*)((?:[^=;,\s]+=[^;,\s]*)(?:;\s*[^=;,\s]+=[^;,\s]*)*)/gi;
|
|
31056
|
-
var API_KEY_RE = new RegExp([
|
|
31057
|
-
"sk-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])",
|
|
31058
|
-
// OpenAI / Anthropic (incl. sk-ant-…)
|
|
31059
|
-
"gh[pousr]_[A-Za-z0-9]{36,}\\b",
|
|
31060
|
-
// GitHub ghp_/gho_/ghu_/ghs_/ghr_
|
|
31061
|
-
"xox[baprs]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])",
|
|
31062
|
-
// Slack
|
|
31063
|
-
"AIza[0-9A-Za-z_-]{35}(?![0-9A-Za-z_-])",
|
|
31064
|
-
// Google API key (39 chars total)
|
|
31065
|
-
"AKIA[0-9A-Z]{16}\\b",
|
|
31066
|
-
// AWS access key id (20 chars total)
|
|
31067
|
-
"whsec_[A-Za-z0-9]{16,}\\b"
|
|
31068
|
-
// webhook signing secret (Stripe-style)
|
|
31069
|
-
].map((p) => `\\b${p}`).join("|"), "g");
|
|
31070
|
-
var QUERY_SECRET_RE = /([?&](?:access_token|refresh_token|client_secret|api_?key|signature|token|key|sig)=)[^&#\s"'<>`]+/gi;
|
|
31071
|
-
var AWS_SIGV4_RE = /([?&]X-Amz-(?:Signature|Security-Token|Credential)=)[^&#\s"'<>`]+/gi;
|
|
31072
|
-
var JSON_SECRET_KEYS = "access_token|refresh_token|client_secret|api_?key|password|passwd|secret|token";
|
|
31073
|
-
var JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")[^"]*(")`, "gi");
|
|
31074
|
-
var JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')[^']*(')`, "gi");
|
|
31075
|
-
function redactSecrets(text) {
|
|
31076
|
-
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]");
|
|
31077
|
-
}
|
|
31078
|
-
|
|
31079
|
-
// ../../node_modules/@chrischall/mcp-utils/dist/response/index.js
|
|
31080
|
-
function rawTextResult(text) {
|
|
31081
|
-
return { content: [{ type: "text", text }] };
|
|
31082
|
-
}
|
|
31083
|
-
function errorResult(message) {
|
|
31084
|
-
return {
|
|
31085
|
-
content: [{ type: "text", text: redactSecrets(message) }],
|
|
31086
|
-
isError: true
|
|
31087
|
-
};
|
|
31088
|
-
}
|
|
31089
|
-
|
|
31090
31123
|
// ../../node_modules/@chrischall/mcp-utils/dist/config/index.js
|
|
31091
31124
|
var PLACEHOLDER_RE = /^\$\{[^}]*\}$/;
|
|
31092
31125
|
function readEnvVar(key, opts = {}) {
|
|
@@ -31912,6 +31945,29 @@ function authToolsFor(defaultServices) {
|
|
|
31912
31945
|
}
|
|
31913
31946
|
|
|
31914
31947
|
// ../gogcli-mcp/src/tools/calendar.ts
|
|
31948
|
+
var reminderParams = {
|
|
31949
|
+
reminders: external_exports.array(external_exports.string()).max(5).optional().describe(
|
|
31950
|
+
`Reminders as method:duration, e.g. ["popup:30m", "email:1d"]. Method is popup or email; duration accepts m/h/d (max 40320 minutes = 4 weeks). Google allows at most 5. These REPLACE the event's reminders \u2014 on update, pass an EMPTY array to drop custom reminders and go back to the calendar's defaults. Cannot be combined with noReminders.`
|
|
31951
|
+
),
|
|
31952
|
+
noReminders: external_exports.boolean().optional().describe(
|
|
31953
|
+
"Give the event no reminders at all, overriding the calendar's defaults. Different from an empty reminders array, which RESTORES those defaults. Cannot be combined with reminders."
|
|
31954
|
+
)
|
|
31955
|
+
};
|
|
31956
|
+
function pushReminderFlags(args, p) {
|
|
31957
|
+
if (p.noReminders) {
|
|
31958
|
+
if (p.reminders !== void 0) {
|
|
31959
|
+
throw new Error("reminders and noReminders are mutually exclusive: pass reminders to set custom ones, noReminders for none, or an empty reminders array to restore the calendar defaults.");
|
|
31960
|
+
}
|
|
31961
|
+
args.push("--no-reminders");
|
|
31962
|
+
return;
|
|
31963
|
+
}
|
|
31964
|
+
if (p.reminders === void 0) return;
|
|
31965
|
+
if (p.reminders.length === 0) {
|
|
31966
|
+
args.push("--reminder=");
|
|
31967
|
+
return;
|
|
31968
|
+
}
|
|
31969
|
+
for (const reminder of p.reminders) args.push(`--reminder=${reminder}`);
|
|
31970
|
+
}
|
|
31915
31971
|
function registerCalendarTools(server) {
|
|
31916
31972
|
server.registerTool("gog_calendar_events", {
|
|
31917
31973
|
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.',
|
|
@@ -31981,9 +32037,10 @@ function registerCalendarTools(server) {
|
|
|
31981
32037
|
allDay: external_exports.boolean().optional().describe("All-day event (use date-only in from/to)"),
|
|
31982
32038
|
timezone: external_exports.string().optional().describe("IANA timezone metadata applied to from/to (e.g. America/New_York). Sets both start and end timezone unless start/end timezone are overridden."),
|
|
31983
32039
|
withZoom: external_exports.boolean().optional().describe("Create a Zoom video conference for this event (requires Zoom S2S OAuth setup)"),
|
|
32040
|
+
...reminderParams,
|
|
31984
32041
|
account: accountParam
|
|
31985
32042
|
}
|
|
31986
|
-
}, async ({ calendarId, summary, from, to, description, location, attendees, allDay, timezone, withZoom, account }) => {
|
|
32043
|
+
}, async ({ calendarId, summary, from, to, description, location, attendees, allDay, timezone, withZoom, reminders, noReminders, account }) => {
|
|
31987
32044
|
const args = ["calendar", "create", calendarId, `--summary=${summary}`, `--from=${from}`, `--to=${to}`];
|
|
31988
32045
|
if (description) args.push(`--description=${description}`);
|
|
31989
32046
|
if (location) args.push(`--location=${location}`);
|
|
@@ -31991,6 +32048,7 @@ function registerCalendarTools(server) {
|
|
|
31991
32048
|
if (allDay) args.push("--all-day");
|
|
31992
32049
|
if (timezone) args.push(`--timezone=${timezone}`);
|
|
31993
32050
|
if (withZoom) args.push("--with-zoom");
|
|
32051
|
+
pushReminderFlags(args, { reminders, noReminders });
|
|
31994
32052
|
return runOrDiagnose(args, { account });
|
|
31995
32053
|
});
|
|
31996
32054
|
server.registerTool("gog_calendar_update", {
|
|
@@ -32011,9 +32069,10 @@ function registerCalendarTools(server) {
|
|
|
32011
32069
|
regenerateZoom: external_exports.boolean().optional().describe("Replace the event's existing Zoom video conference"),
|
|
32012
32070
|
removeZoom: external_exports.boolean().optional().describe("Remove the event's Zoom video conference"),
|
|
32013
32071
|
removeMeet: external_exports.boolean().optional().describe("Remove the event's Google Meet video conference (clears conference data only)"),
|
|
32072
|
+
...reminderParams,
|
|
32014
32073
|
account: accountParam
|
|
32015
32074
|
}
|
|
32016
|
-
}, async ({ calendarId, eventId, summary, from, to, description, location, attendees, addAttendees, attachments, withZoom, regenerateZoom, removeZoom, removeMeet, account }) => {
|
|
32075
|
+
}, async ({ calendarId, eventId, summary, from, to, description, location, attendees, addAttendees, attachments, withZoom, regenerateZoom, removeZoom, removeMeet, reminders, noReminders, account }) => {
|
|
32017
32076
|
const args = ["calendar", "update", calendarId, eventId];
|
|
32018
32077
|
if (summary !== void 0) args.push(`--summary=${summary}`);
|
|
32019
32078
|
if (from !== void 0) args.push(`--from=${from}`);
|
|
@@ -32027,6 +32086,7 @@ function registerCalendarTools(server) {
|
|
|
32027
32086
|
if (regenerateZoom) args.push("--regenerate-zoom");
|
|
32028
32087
|
if (removeZoom) args.push("--remove-zoom");
|
|
32029
32088
|
if (removeMeet) args.push("--remove-meet");
|
|
32089
|
+
pushReminderFlags(args, { reminders, noReminders });
|
|
32030
32090
|
return runOrDiagnose(args, { account });
|
|
32031
32091
|
});
|
|
32032
32092
|
server.registerTool("gog_calendar_delete", {
|
|
@@ -32078,6 +32138,28 @@ var attachInlineParam = external_exports.array(inlineAttachmentSchema).optional(
|
|
|
32078
32138
|
`Attachments supplied as BYTES rather than as server-side paths \u2014 use this whenever you hold a file and the gog server does not, which is always the case on the hosted connector and on any remote deployment. Each entry is {filename, contentBase64} (${INLINE_ATTACHMENT_LIMITS_TEXT}). Can be combined with \`attach\`: the two name disjoint files (paths read on the server vs. bytes sent with the call), and both end up as ordinary attachments on the message.`
|
|
32079
32139
|
);
|
|
32080
32140
|
|
|
32141
|
+
// ../gogcli-mcp/src/tools/gmail.ts
|
|
32142
|
+
var replySchema = {
|
|
32143
|
+
messageId: external_exports.string().describe("Gmail message ID to reply to \u2014 the short hex `id` from gog_gmail_get / _search (or gog_gmail_messages_search, gogcli-mcp-gmail only). NOT the threadId, NOT the RFC822 `<\u2026@host>` Message-Id header."),
|
|
32144
|
+
body: external_exports.string().optional().describe("Reply body (plain text; required unless bodyHtml or bodyHtmlFile is set). Any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Note gog strips trailing newlines from a file-delivered body."),
|
|
32145
|
+
bodyHtml: external_exports.string().optional().describe("Reply body (HTML; optional). Pass the HTML itself at any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Mutually exclusive with bodyHtmlFile."),
|
|
32146
|
+
bodyHtmlFile: external_exports.string().optional().describe(`Path to an HTML file that ALREADY EXISTS on the gog server for the reply body. gog also accepts "-" for stdin, but this server never writes to gog's stdin, so "-" would hang until the call times out. Mutually exclusive with bodyHtml \u2014 supplying both is rejected. You rarely need this: bodyHtml handles large bodies on its own.`),
|
|
32147
|
+
to: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to To (repeatable). Added on top of the recipients inherited from the original message."),
|
|
32148
|
+
cc: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to Cc (repeatable)"),
|
|
32149
|
+
bcc: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to Bcc (repeatable)"),
|
|
32150
|
+
remove: external_exports.array(external_exports.string()).optional().describe("Remove these recipients from all fields (repeatable) \u2014 e.g. to drop someone from a reply-all."),
|
|
32151
|
+
subject: external_exports.string().optional().describe('Override reply subject (default: "Re: <original>"). A changed subject starts a NEW Gmail thread.'),
|
|
32152
|
+
noQuote: external_exports.boolean().optional().describe("Do not include the original message quoted below the reply (default: the original is quoted)"),
|
|
32153
|
+
attach: external_exports.array(external_exports.string()).optional().describe(`File paths to attach (repeatable), resolved ON THE GOG SERVER's filesystem \u2014 NOT this client's. Only usable when gog runs on the same machine you do (local stdio); on the hosted connector or any GOG_RUNNER_URL backend these paths do not exist and the call fails with "no such file or directory" \u2014 use attachInline there. Read on the server, base64-encoded with a MIME type inferred from the extension.`),
|
|
32154
|
+
attachInline: attachInlineParam,
|
|
32155
|
+
from: external_exports.string().optional().describe("Send from this email address (must be a verified send-as alias)"),
|
|
32156
|
+
autoFromAddressedAlias: external_exports.boolean().optional().describe("When from is omitted, send from the verified send-as alias the original message was addressed TO, instead of the account's primary address \u2014 so a reply to mail sent to an alias goes back out from that alias. Ignored when from is set."),
|
|
32157
|
+
signature: external_exports.boolean().optional().describe("Append the Gmail signature from the active send-as address"),
|
|
32158
|
+
signatureFrom: external_exports.string().optional().describe("Append the Gmail signature from this send-as email address"),
|
|
32159
|
+
signatureFile: external_exports.string().optional().describe("Append a local signature file (plain text or HTML), read on the gog server"),
|
|
32160
|
+
account: accountParam
|
|
32161
|
+
};
|
|
32162
|
+
|
|
32081
32163
|
// ../gogcli-mcp/src/tools/sheets.ts
|
|
32082
32164
|
var cellValueParam = external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean(), external_exports.null()]);
|
|
32083
32165
|
var dryRunParam = external_exports.boolean().optional().describe(
|
|
@@ -32088,7 +32170,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
|
|
|
32088
32170
|
);
|
|
32089
32171
|
|
|
32090
32172
|
// ../gogcli-mcp/src/server.ts
|
|
32091
|
-
var VERSION = true ? "2.
|
|
32173
|
+
var VERSION = true ? "2.27.0" : "0.0.0";
|
|
32092
32174
|
|
|
32093
32175
|
// ../gogcli-mcp/src/auth-log.ts
|
|
32094
32176
|
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.27.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/mint.yaml
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
name: Google Calendar (gogcli)
|
|
3
|
+
slug: gogcli-mcp-calendar
|
|
4
|
+
summary: >-
|
|
5
|
+
Extended Google Calendar + Meet MCP server via gogcli — auth + Calendar
|
|
6
|
+
events + Meet space management
|
|
7
|
+
command:
|
|
8
|
+
# This package publishes a single bin; naming it keeps the install
|
|
9
|
+
# unambiguous alongside its eight sibling packages.
|
|
10
|
+
bin: gogcli-mcp-calendar
|
|
11
|
+
env:
|
|
12
|
+
- name: GOG_CLIENT_ID
|
|
13
|
+
required: false
|
|
14
|
+
help: >-
|
|
15
|
+
Google OAuth client id. NOTE: on the local-spawn path the child `gog`
|
|
16
|
+
receives a sanitized env — runner.ts drops GOG_ACCESS_TOKEN and every
|
|
17
|
+
*_TOKEN / *_SECRET / *_API_KEY / *_PRIVATE_KEY variable — so the CLI
|
|
18
|
+
authenticates from its own stored credentials under $HOME (see
|
|
19
|
+
state.dataDir), not from these variables being passed through.
|
|
20
|
+
- name: GOG_CLIENT_SECRET
|
|
21
|
+
secret: true
|
|
22
|
+
required: false
|
|
23
|
+
help: >-
|
|
24
|
+
Google OAuth client secret. Stripped from the spawned CLI's environment
|
|
25
|
+
by runner.ts's *_SECRET rule — see GOG_CLIENT_ID.
|
|
26
|
+
- name: GOG_REFRESH_TOKEN
|
|
27
|
+
secret: true
|
|
28
|
+
required: false
|
|
29
|
+
help: >-
|
|
30
|
+
Google OAuth refresh token. Stripped from the spawned CLI's environment
|
|
31
|
+
by runner.ts's *_TOKEN rule — see GOG_CLIENT_ID. A hosted deployment must
|
|
32
|
+
therefore carry gog's authorised-account state in its persisted data dir,
|
|
33
|
+
or drive a remote runner via GOG_RUNNER_URL.
|
|
34
|
+
- name: GOG_ACCESS_TOKEN
|
|
35
|
+
secret: true
|
|
36
|
+
required: false
|
|
37
|
+
help: >-
|
|
38
|
+
Deliberately removed from the spawned CLI's environment by runner.ts, so
|
|
39
|
+
that a stale directly-passed token cannot shadow gog's stored refresh
|
|
40
|
+
credential. Leave unset.
|
|
41
|
+
- name: GOG_ACCOUNT
|
|
42
|
+
required: false
|
|
43
|
+
help: >-
|
|
44
|
+
Which configured Google account to act as, when more than one is
|
|
45
|
+
authorised. Defaults to the single/most recent account.
|
|
46
|
+
- name: GOG_READONLY
|
|
47
|
+
required: false
|
|
48
|
+
help: >-
|
|
49
|
+
Set to 1 to refuse every mutating operation. Recommended when the
|
|
50
|
+
connector is shared or you only need reads.
|
|
51
|
+
- name: GOG_PATH
|
|
52
|
+
required: false
|
|
53
|
+
help: >-
|
|
54
|
+
Path to the `gog` binary. Leave unset when the dependency below supplies
|
|
55
|
+
it; set it only to point at a binary you manage yourself.
|
|
56
|
+
- name: GOG_RUNNER_URL
|
|
57
|
+
required: false
|
|
58
|
+
help: >-
|
|
59
|
+
URL of a remote gog runner to execute against instead of spawning the
|
|
60
|
+
local binary. If you set this, add its host to egress.allow.
|
|
61
|
+
- name: GOG_RUNNER_KEY
|
|
62
|
+
secret: true
|
|
63
|
+
required: false
|
|
64
|
+
help: >-
|
|
65
|
+
Shared key authenticating calls to GOG_RUNNER_URL. Required whenever that
|
|
66
|
+
is set.
|
|
67
|
+
- name: GOG_TIMEZONE
|
|
68
|
+
required: false
|
|
69
|
+
help: >-
|
|
70
|
+
The IANA zone gog itself formats its naive timestamps in. The wrapper
|
|
71
|
+
reads it (naiveSourceTimeZone) to re-attach the correct offset, so it
|
|
72
|
+
should match gog's own configuration. Falls back to DISPLAY_TZ, then to
|
|
73
|
+
America/New_York.
|
|
74
|
+
- name: DISPLAY_TZ
|
|
75
|
+
required: false
|
|
76
|
+
help: >-
|
|
77
|
+
The IANA zone every rendered *Display field uses (displayTimeZone,
|
|
78
|
+
default America/New_York). It does not read GOG_TIMEZONE — the fallback
|
|
79
|
+
runs the other way, so this is also what GOG_TIMEZONE falls back to. An
|
|
80
|
+
invalid value degrades to the default rather than throwing.
|
|
81
|
+
dependencies:
|
|
82
|
+
# Every tool shells out to the `gog` CLI; without it the server starts and
|
|
83
|
+
# then fails on the first call. This tag must track
|
|
84
|
+
# packages/gogcli-mcp/src/runner.ts's MIN_GOG_VERSION (the floor the tools
|
|
85
|
+
# assume) and the fly-gog-runner/Dockerfile GOG_VERSION build arg. See
|
|
86
|
+
# CLAUDE.md "Required gog version" — bumping the floor means bumping these
|
|
87
|
+
# nine pins too.
|
|
88
|
+
- kind: github-release
|
|
89
|
+
repo: openclaw/gogcli
|
|
90
|
+
tag: v0.38.1
|
|
91
|
+
asset: "gogcli_*_linux_amd64.tar.gz"
|
|
92
|
+
bin: [gog]
|
|
93
|
+
state:
|
|
94
|
+
dataDir: true
|
|
95
|
+
reason: >-
|
|
96
|
+
`gog` keeps its authorised-account state and token cache under $HOME.
|
|
97
|
+
Without a persistent data dir every cold start has no account configured and
|
|
98
|
+
every tool call fails until the credentials are re-supplied.
|
|
99
|
+
egress:
|
|
100
|
+
allow:
|
|
101
|
+
# Google OAuth token exchange and the Google REST APIs the CLI calls.
|
|
102
|
+
- oauth2.googleapis.com
|
|
103
|
+
- www.googleapis.com
|
|
104
|
+
- googleapis.com
|
|
105
|
+
#
|
|
106
|
+
# NOTE: if you set GOG_RUNNER_URL to run against a remote gog runner, add
|
|
107
|
+
# that host here too — it is supplied at runtime and cannot be declared.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-calendar",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.27.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.15.0",
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
29
29
|
"zod": "^4.4.3"
|
|
30
30
|
},
|