gogcli-mcp 2.0.8 → 2.0.9
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +226 -155
- package/dist/lib.js +235 -155
- package/manifest.json +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
- package/src/lib.ts +10 -1
- package/src/runner.ts +36 -5
- package/src/tools/auth.ts +6 -10
- package/src/tools/calendar.ts +2 -12
- package/src/tools/classroom.ts +5 -11
- package/src/tools/contacts.ts +2 -12
- package/src/tools/docs.ts +2 -12
- package/src/tools/drive.ts +2 -12
- package/src/tools/gmail.ts +2 -12
- package/src/tools/sheets.ts +2 -12
- package/src/tools/slides.ts +2 -12
- package/src/tools/tasks.ts +2 -12
- package/src/tools/utils.ts +80 -0
- package/tests/helpers/{extras-harness.ts → test-harness.ts} +4 -8
- package/tests/runner.test.ts +59 -0
- package/tests/tools/auth.test.ts +2 -13
- package/tests/tools/calendar.test.ts +2 -13
- package/tests/tools/classroom.test.ts +2 -13
- package/tests/tools/contacts.test.ts +2 -13
- package/tests/tools/docs.test.ts +2 -13
- package/tests/tools/drive.test.ts +2 -13
- package/tests/tools/gmail.test.ts +2 -13
- package/tests/tools/sheets.test.ts +2 -13
- package/tests/tools/slides.test.ts +2 -13
- package/tests/tools/tasks.test.ts +2 -13
- package/tests/tools/utils.test.ts +35 -1
package/dist/lib.js
CHANGED
|
@@ -3104,6 +3104,9 @@ var require_utils = __commonJS({
|
|
|
3104
3104
|
"use strict";
|
|
3105
3105
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3106
3106
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
3107
|
+
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3108
|
+
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3109
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
|
|
3107
3110
|
function stringArrayToHexStripped(input) {
|
|
3108
3111
|
let acc = "";
|
|
3109
3112
|
let code = 0;
|
|
@@ -3296,27 +3299,77 @@ var require_utils = __commonJS({
|
|
|
3296
3299
|
}
|
|
3297
3300
|
return output.join("");
|
|
3298
3301
|
}
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3302
|
+
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
|
|
3303
|
+
var HOST_DELIM_RE = /[@/?#:]/g;
|
|
3304
|
+
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
|
|
3305
|
+
function reescapeHostDelimiters(host, isIP) {
|
|
3306
|
+
const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
|
|
3307
|
+
re.lastIndex = 0;
|
|
3308
|
+
return host.replace(re, (ch) => HOST_DELIMS[ch]);
|
|
3309
|
+
}
|
|
3310
|
+
function normalizePercentEncoding(input, decodeUnreserved = false) {
|
|
3311
|
+
if (input.indexOf("%") === -1) {
|
|
3312
|
+
return input;
|
|
3309
3313
|
}
|
|
3310
|
-
|
|
3311
|
-
|
|
3314
|
+
let output = "";
|
|
3315
|
+
for (let i = 0; i < input.length; i++) {
|
|
3316
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
3317
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3318
|
+
if (isHexPair(hex3)) {
|
|
3319
|
+
const normalizedHex = hex3.toUpperCase();
|
|
3320
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3321
|
+
if (decodeUnreserved && isUnreserved(decoded)) {
|
|
3322
|
+
output += decoded;
|
|
3323
|
+
} else {
|
|
3324
|
+
output += "%" + normalizedHex;
|
|
3325
|
+
}
|
|
3326
|
+
i += 2;
|
|
3327
|
+
continue;
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
output += input[i];
|
|
3312
3331
|
}
|
|
3313
|
-
|
|
3314
|
-
|
|
3332
|
+
return output;
|
|
3333
|
+
}
|
|
3334
|
+
function normalizePathEncoding(input) {
|
|
3335
|
+
let output = "";
|
|
3336
|
+
for (let i = 0; i < input.length; i++) {
|
|
3337
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
3338
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3339
|
+
if (isHexPair(hex3)) {
|
|
3340
|
+
const normalizedHex = hex3.toUpperCase();
|
|
3341
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3342
|
+
if (decoded !== "." && isUnreserved(decoded)) {
|
|
3343
|
+
output += decoded;
|
|
3344
|
+
} else {
|
|
3345
|
+
output += "%" + normalizedHex;
|
|
3346
|
+
}
|
|
3347
|
+
i += 2;
|
|
3348
|
+
continue;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
if (isPathCharacter(input[i])) {
|
|
3352
|
+
output += input[i];
|
|
3353
|
+
} else {
|
|
3354
|
+
output += escape(input[i]);
|
|
3355
|
+
}
|
|
3315
3356
|
}
|
|
3316
|
-
|
|
3317
|
-
|
|
3357
|
+
return output;
|
|
3358
|
+
}
|
|
3359
|
+
function escapePreservingEscapes(input) {
|
|
3360
|
+
let output = "";
|
|
3361
|
+
for (let i = 0; i < input.length; i++) {
|
|
3362
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
3363
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3364
|
+
if (isHexPair(hex3)) {
|
|
3365
|
+
output += "%" + hex3.toUpperCase();
|
|
3366
|
+
i += 2;
|
|
3367
|
+
continue;
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
output += escape(input[i]);
|
|
3318
3371
|
}
|
|
3319
|
-
return
|
|
3372
|
+
return output;
|
|
3320
3373
|
}
|
|
3321
3374
|
function recomposeAuthority(component) {
|
|
3322
3375
|
const uriTokens = [];
|
|
@@ -3331,7 +3384,7 @@ var require_utils = __commonJS({
|
|
|
3331
3384
|
if (ipV6res.isIPV6 === true) {
|
|
3332
3385
|
host = `[${ipV6res.escapedHost}]`;
|
|
3333
3386
|
} else {
|
|
3334
|
-
host =
|
|
3387
|
+
host = reescapeHostDelimiters(host, false);
|
|
3335
3388
|
}
|
|
3336
3389
|
}
|
|
3337
3390
|
uriTokens.push(host);
|
|
@@ -3345,7 +3398,10 @@ var require_utils = __commonJS({
|
|
|
3345
3398
|
module.exports = {
|
|
3346
3399
|
nonSimpleDomain,
|
|
3347
3400
|
recomposeAuthority,
|
|
3348
|
-
|
|
3401
|
+
reescapeHostDelimiters,
|
|
3402
|
+
normalizePercentEncoding,
|
|
3403
|
+
normalizePathEncoding,
|
|
3404
|
+
escapePreservingEscapes,
|
|
3349
3405
|
removeDotSegments,
|
|
3350
3406
|
isIPv4,
|
|
3351
3407
|
isUUID,
|
|
@@ -3569,12 +3625,12 @@ var require_schemes = __commonJS({
|
|
|
3569
3625
|
var require_fast_uri = __commonJS({
|
|
3570
3626
|
"../../node_modules/fast-uri/index.js"(exports, module) {
|
|
3571
3627
|
"use strict";
|
|
3572
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority,
|
|
3628
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3573
3629
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
3574
3630
|
function normalize(uri, options) {
|
|
3575
3631
|
if (typeof uri === "string") {
|
|
3576
3632
|
uri = /** @type {T} */
|
|
3577
|
-
|
|
3633
|
+
normalizeString(uri, options);
|
|
3578
3634
|
} else if (typeof uri === "object") {
|
|
3579
3635
|
uri = /** @type {T} */
|
|
3580
3636
|
parse3(serialize(uri, options), options);
|
|
@@ -3641,19 +3697,9 @@ var require_fast_uri = __commonJS({
|
|
|
3641
3697
|
return target;
|
|
3642
3698
|
}
|
|
3643
3699
|
function equal(uriA, uriB, options) {
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
} else if (typeof uriA === "object") {
|
|
3648
|
-
uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
|
|
3649
|
-
}
|
|
3650
|
-
if (typeof uriB === "string") {
|
|
3651
|
-
uriB = unescape(uriB);
|
|
3652
|
-
uriB = serialize(normalizeComponentEncoding(parse3(uriB, options), true), { ...options, skipEscape: true });
|
|
3653
|
-
} else if (typeof uriB === "object") {
|
|
3654
|
-
uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
|
|
3655
|
-
}
|
|
3656
|
-
return uriA.toLowerCase() === uriB.toLowerCase();
|
|
3700
|
+
const normalizedA = normalizeComparableURI(uriA, options);
|
|
3701
|
+
const normalizedB = normalizeComparableURI(uriB, options);
|
|
3702
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
|
|
3657
3703
|
}
|
|
3658
3704
|
function serialize(cmpts, opts) {
|
|
3659
3705
|
const component = {
|
|
@@ -3678,12 +3724,12 @@ var require_fast_uri = __commonJS({
|
|
|
3678
3724
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
3679
3725
|
if (component.path !== void 0) {
|
|
3680
3726
|
if (!options.skipEscape) {
|
|
3681
|
-
component.path =
|
|
3727
|
+
component.path = escapePreservingEscapes(component.path);
|
|
3682
3728
|
if (component.scheme !== void 0) {
|
|
3683
3729
|
component.path = component.path.split("%3A").join(":");
|
|
3684
3730
|
}
|
|
3685
3731
|
} else {
|
|
3686
|
-
component.path =
|
|
3732
|
+
component.path = normalizePercentEncoding(component.path);
|
|
3687
3733
|
}
|
|
3688
3734
|
}
|
|
3689
3735
|
if (options.reference !== "suffix" && component.scheme) {
|
|
@@ -3718,7 +3764,16 @@ var require_fast_uri = __commonJS({
|
|
|
3718
3764
|
return uriTokens.join("");
|
|
3719
3765
|
}
|
|
3720
3766
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
3721
|
-
function
|
|
3767
|
+
function getParseError(parsed, matches) {
|
|
3768
|
+
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
3769
|
+
return 'URI path must start with "/" when authority is present.';
|
|
3770
|
+
}
|
|
3771
|
+
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
|
|
3772
|
+
return "URI port is malformed.";
|
|
3773
|
+
}
|
|
3774
|
+
return void 0;
|
|
3775
|
+
}
|
|
3776
|
+
function parseWithStatus(uri, opts) {
|
|
3722
3777
|
const options = Object.assign({}, opts);
|
|
3723
3778
|
const parsed = {
|
|
3724
3779
|
scheme: void 0,
|
|
@@ -3729,6 +3784,7 @@ var require_fast_uri = __commonJS({
|
|
|
3729
3784
|
query: void 0,
|
|
3730
3785
|
fragment: void 0
|
|
3731
3786
|
};
|
|
3787
|
+
let malformedAuthorityOrPort = false;
|
|
3732
3788
|
let isIP = false;
|
|
3733
3789
|
if (options.reference === "suffix") {
|
|
3734
3790
|
if (options.scheme) {
|
|
@@ -3749,6 +3805,11 @@ var require_fast_uri = __commonJS({
|
|
|
3749
3805
|
if (isNaN(parsed.port)) {
|
|
3750
3806
|
parsed.port = matches[5];
|
|
3751
3807
|
}
|
|
3808
|
+
const parseError = getParseError(parsed, matches);
|
|
3809
|
+
if (parseError !== void 0) {
|
|
3810
|
+
parsed.error = parsed.error || parseError;
|
|
3811
|
+
malformedAuthorityOrPort = true;
|
|
3812
|
+
}
|
|
3752
3813
|
if (parsed.host) {
|
|
3753
3814
|
const ipv4result = isIPv4(parsed.host);
|
|
3754
3815
|
if (ipv4result === false) {
|
|
@@ -3787,14 +3848,18 @@ var require_fast_uri = __commonJS({
|
|
|
3787
3848
|
parsed.scheme = unescape(parsed.scheme);
|
|
3788
3849
|
}
|
|
3789
3850
|
if (parsed.host !== void 0) {
|
|
3790
|
-
parsed.host = unescape(parsed.host);
|
|
3851
|
+
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
3791
3852
|
}
|
|
3792
3853
|
}
|
|
3793
3854
|
if (parsed.path) {
|
|
3794
|
-
parsed.path =
|
|
3855
|
+
parsed.path = normalizePathEncoding(parsed.path);
|
|
3795
3856
|
}
|
|
3796
3857
|
if (parsed.fragment) {
|
|
3797
|
-
|
|
3858
|
+
try {
|
|
3859
|
+
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
3860
|
+
} catch {
|
|
3861
|
+
parsed.error = parsed.error || "URI malformed";
|
|
3862
|
+
}
|
|
3798
3863
|
}
|
|
3799
3864
|
}
|
|
3800
3865
|
if (schemeHandler && schemeHandler.parse) {
|
|
@@ -3803,7 +3868,29 @@ var require_fast_uri = __commonJS({
|
|
|
3803
3868
|
} else {
|
|
3804
3869
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
3805
3870
|
}
|
|
3806
|
-
return parsed;
|
|
3871
|
+
return { parsed, malformedAuthorityOrPort };
|
|
3872
|
+
}
|
|
3873
|
+
function parse3(uri, opts) {
|
|
3874
|
+
return parseWithStatus(uri, opts).parsed;
|
|
3875
|
+
}
|
|
3876
|
+
function normalizeString(uri, opts) {
|
|
3877
|
+
return normalizeStringWithStatus(uri, opts).normalized;
|
|
3878
|
+
}
|
|
3879
|
+
function normalizeStringWithStatus(uri, opts) {
|
|
3880
|
+
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
3881
|
+
return {
|
|
3882
|
+
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
3883
|
+
malformedAuthorityOrPort
|
|
3884
|
+
};
|
|
3885
|
+
}
|
|
3886
|
+
function normalizeComparableURI(uri, opts) {
|
|
3887
|
+
if (typeof uri === "string") {
|
|
3888
|
+
const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
|
|
3889
|
+
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
3890
|
+
}
|
|
3891
|
+
if (typeof uri === "object") {
|
|
3892
|
+
return serialize(uri, opts);
|
|
3893
|
+
}
|
|
3807
3894
|
}
|
|
3808
3895
|
var fastUri = {
|
|
3809
3896
|
SCHEMES,
|
|
@@ -13515,14 +13602,14 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
13515
13602
|
return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
13516
13603
|
};
|
|
13517
13604
|
doc.write(`const input = payload.value;`);
|
|
13518
|
-
const
|
|
13605
|
+
const ids2 = /* @__PURE__ */ Object.create(null);
|
|
13519
13606
|
let counter = 0;
|
|
13520
13607
|
for (const key of normalized.keys) {
|
|
13521
|
-
|
|
13608
|
+
ids2[key] = `key_${counter++}`;
|
|
13522
13609
|
}
|
|
13523
13610
|
doc.write(`const newResult = {};`);
|
|
13524
13611
|
for (const key of normalized.keys) {
|
|
13525
|
-
const id =
|
|
13612
|
+
const id = ids2[key];
|
|
13526
13613
|
const k = esc(key);
|
|
13527
13614
|
const schema = shape[key];
|
|
13528
13615
|
const isOptionalIn = schema?._zod?.optin === "optional";
|
|
@@ -30777,6 +30864,32 @@ function envOrUndefined(key) {
|
|
|
30777
30864
|
if (!value || value.startsWith("${")) return void 0;
|
|
30778
30865
|
return value;
|
|
30779
30866
|
}
|
|
30867
|
+
function sanitizedEnv() {
|
|
30868
|
+
const result = {};
|
|
30869
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
30870
|
+
if (key === "GOG_ACCESS_TOKEN") continue;
|
|
30871
|
+
if (key === "GOOGLE_APPLICATION_CREDENTIALS") continue;
|
|
30872
|
+
if (/(_TOKEN|_SECRET|_API_KEY|_PRIVATE_KEY)$/.test(key)) continue;
|
|
30873
|
+
result[key] = value;
|
|
30874
|
+
}
|
|
30875
|
+
return result;
|
|
30876
|
+
}
|
|
30877
|
+
var TOKEN_PATTERNS = [
|
|
30878
|
+
/Bearer\s+[A-Za-z0-9._\-+/=]+/gi,
|
|
30879
|
+
/ya29\.[A-Za-z0-9._\-]+/g,
|
|
30880
|
+
// OAuth2 access tokens
|
|
30881
|
+
/1\/\/[A-Za-z0-9._\-]+/g,
|
|
30882
|
+
// OAuth2 refresh tokens
|
|
30883
|
+
/AIza[A-Za-z0-9_\-]{35}/g
|
|
30884
|
+
// Google API keys
|
|
30885
|
+
];
|
|
30886
|
+
function redactSecrets(text) {
|
|
30887
|
+
let redacted = text;
|
|
30888
|
+
for (const re of TOKEN_PATTERNS) {
|
|
30889
|
+
redacted = redacted.replace(re, "[REDACTED]");
|
|
30890
|
+
}
|
|
30891
|
+
return redacted;
|
|
30892
|
+
}
|
|
30780
30893
|
function augmentedPath() {
|
|
30781
30894
|
const home = process.env.HOME;
|
|
30782
30895
|
const candidates = [
|
|
@@ -30819,8 +30932,7 @@ async function run(args, options = {}) {
|
|
|
30819
30932
|
fullArgs.push(...args);
|
|
30820
30933
|
const effectiveTimeout = timeout ?? TIMEOUT_MS;
|
|
30821
30934
|
return new Promise((resolve, reject) => {
|
|
30822
|
-
const
|
|
30823
|
-
const childEnv = { ...cleanEnv, PATH: augmentedPath() };
|
|
30935
|
+
const childEnv = { ...sanitizedEnv(), PATH: augmentedPath() };
|
|
30824
30936
|
const child = spawner(envOrUndefined("GOG_PATH") ?? "gog", fullArgs, { env: childEnv });
|
|
30825
30937
|
const stdoutChunks = [];
|
|
30826
30938
|
const stderrChunks = [];
|
|
@@ -30849,7 +30961,7 @@ async function run(args, options = {}) {
|
|
|
30849
30961
|
resolve(stdout);
|
|
30850
30962
|
}
|
|
30851
30963
|
} else {
|
|
30852
|
-
reject(new Error(stderr || `gog exited with code ${code}`));
|
|
30964
|
+
reject(new Error(redactSecrets(stderr || `gog exited with code ${code}`)));
|
|
30853
30965
|
}
|
|
30854
30966
|
});
|
|
30855
30967
|
child.on("error", (err) => {
|
|
@@ -30871,6 +30983,60 @@ async function run(args, options = {}) {
|
|
|
30871
30983
|
var accountParam = external_exports.string().optional().describe(
|
|
30872
30984
|
"Google account email to use (overrides GOG_ACCOUNT env var)"
|
|
30873
30985
|
);
|
|
30986
|
+
var ids = {
|
|
30987
|
+
course: external_exports.string().describe("Course ID"),
|
|
30988
|
+
coursework: external_exports.string().describe("Coursework ID"),
|
|
30989
|
+
submission: external_exports.string().describe("Submission ID"),
|
|
30990
|
+
announcement: external_exports.string().describe("Announcement ID"),
|
|
30991
|
+
topic: external_exports.string().describe("Topic ID"),
|
|
30992
|
+
invitation: external_exports.string().describe("Invitation ID"),
|
|
30993
|
+
spreadsheet: external_exports.string().describe("Spreadsheet ID (from the URL)"),
|
|
30994
|
+
doc: external_exports.string().describe("Doc ID (from the URL)"),
|
|
30995
|
+
presentation: external_exports.string().describe("Presentation ID"),
|
|
30996
|
+
slide: external_exports.string().describe("Slide ID"),
|
|
30997
|
+
file: external_exports.string().describe("File ID"),
|
|
30998
|
+
message: external_exports.string().describe("Message ID"),
|
|
30999
|
+
thread: external_exports.string().describe("Thread ID"),
|
|
31000
|
+
draft: external_exports.string().describe("Draft ID"),
|
|
31001
|
+
label: external_exports.string().describe("Label ID or name"),
|
|
31002
|
+
attachment: external_exports.string().describe("Attachment ID"),
|
|
31003
|
+
comment: external_exports.string().describe("Comment ID"),
|
|
31004
|
+
meetingCode: external_exports.string().describe("Meeting code (e.g. abc-defg-hij)"),
|
|
31005
|
+
permission: external_exports.string().describe("Permission ID"),
|
|
31006
|
+
user: external_exports.string().describe("User ID"),
|
|
31007
|
+
// People API uses fully-qualified resource names ("people/c123") not bare IDs.
|
|
31008
|
+
person: external_exports.string().describe("Person resource name (people/...) or email")
|
|
31009
|
+
};
|
|
31010
|
+
var paginationParams = {
|
|
31011
|
+
max: external_exports.number().int().optional().describe("Max results"),
|
|
31012
|
+
page: external_exports.string().optional().describe("Page token"),
|
|
31013
|
+
all: external_exports.boolean().optional().describe("Fetch all pages")
|
|
31014
|
+
};
|
|
31015
|
+
function pushPaginationFlags(args, p) {
|
|
31016
|
+
if (p.max !== void 0) args.push(`--max=${p.max}`);
|
|
31017
|
+
if (p.page) args.push(`--page=${p.page}`);
|
|
31018
|
+
if (p.all) args.push("--all");
|
|
31019
|
+
}
|
|
31020
|
+
function registerRunTool(server, options) {
|
|
31021
|
+
const { service, examples, omitAccount = false, note } = options;
|
|
31022
|
+
const baseDescription = `Run any gog ${service} subcommand not covered by the other tools. Run \`gog ${service} --help\` for the full list of subcommands, or \`gog ${service} <subcommand> --help\` for flags on a specific subcommand.`;
|
|
31023
|
+
const description = note ? `${baseDescription} ${note}` : baseDescription;
|
|
31024
|
+
const inputSchema = {
|
|
31025
|
+
subcommand: external_exports.string().describe(`The gog ${service} subcommand to run, e.g. ${examples}`),
|
|
31026
|
+
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags")
|
|
31027
|
+
};
|
|
31028
|
+
if (!omitAccount) {
|
|
31029
|
+
inputSchema.account = accountParam;
|
|
31030
|
+
}
|
|
31031
|
+
server.registerTool(`gog_${service}_run`, {
|
|
31032
|
+
description,
|
|
31033
|
+
annotations: { destructiveHint: true },
|
|
31034
|
+
inputSchema
|
|
31035
|
+
}, async (rawArgs) => {
|
|
31036
|
+
const { subcommand, args, account } = rawArgs;
|
|
31037
|
+
return runOrDiagnose([service, subcommand, ...args], { account });
|
|
31038
|
+
});
|
|
31039
|
+
}
|
|
30874
31040
|
function toText(output) {
|
|
30875
31041
|
return { content: [{ type: "text", text: output }] };
|
|
30876
31042
|
}
|
|
@@ -30956,15 +31122,11 @@ function registerAuthTools(server) {
|
|
|
30956
31122
|
return toError(err);
|
|
30957
31123
|
}
|
|
30958
31124
|
});
|
|
30959
|
-
server
|
|
30960
|
-
|
|
30961
|
-
|
|
30962
|
-
|
|
30963
|
-
|
|
30964
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags")
|
|
30965
|
-
}
|
|
30966
|
-
}, async ({ subcommand, args }) => {
|
|
30967
|
-
return runOrDiagnose(["auth", subcommand, ...args], {});
|
|
31125
|
+
registerRunTool(server, {
|
|
31126
|
+
service: "auth",
|
|
31127
|
+
examples: '"remove", "alias", "tokens"',
|
|
31128
|
+
omitAccount: true,
|
|
31129
|
+
note: "For browser-based authorization, use gog_auth_add instead."
|
|
30968
31130
|
});
|
|
30969
31131
|
}
|
|
30970
31132
|
|
|
@@ -31075,17 +31237,7 @@ function registerCalendarTools(server) {
|
|
|
31075
31237
|
if (comment) args.push(`--comment=${comment}`);
|
|
31076
31238
|
return runOrDiagnose(args, { account });
|
|
31077
31239
|
});
|
|
31078
|
-
server
|
|
31079
|
-
description: "Run any gog calendar subcommand not covered by the other tools. Run `gog calendar --help` for the full list of subcommands, or `gog calendar <subcommand> --help` for flags on a specific subcommand.",
|
|
31080
|
-
annotations: { destructiveHint: true },
|
|
31081
|
-
inputSchema: {
|
|
31082
|
-
subcommand: external_exports.string().describe('The gog calendar subcommand to run, e.g. "calendars", "freebusy"'),
|
|
31083
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31084
|
-
account: accountParam
|
|
31085
|
-
}
|
|
31086
|
-
}, async ({ subcommand, args, account }) => {
|
|
31087
|
-
return runOrDiagnose(["calendar", subcommand, ...args], { account });
|
|
31088
|
-
});
|
|
31240
|
+
registerRunTool(server, { service: "calendar", examples: '"calendars", "freebusy"' });
|
|
31089
31241
|
}
|
|
31090
31242
|
|
|
31091
31243
|
// src/tools/classroom.ts
|
|
@@ -31450,16 +31602,10 @@ function registerClassroomTools(server) {
|
|
|
31450
31602
|
if (userId) args.push(userId);
|
|
31451
31603
|
return runOrDiagnose(args, { account });
|
|
31452
31604
|
});
|
|
31453
|
-
server
|
|
31454
|
-
|
|
31455
|
-
|
|
31456
|
-
|
|
31457
|
-
subcommand: external_exports.string().describe('The gog classroom subcommand to run, e.g. "guardians", "materials", "guardian-invitations"'),
|
|
31458
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31459
|
-
account: accountParam
|
|
31460
|
-
}
|
|
31461
|
-
}, async ({ subcommand, args, account }) => {
|
|
31462
|
-
return runOrDiagnose(["classroom", subcommand, ...args], { account });
|
|
31605
|
+
registerRunTool(server, {
|
|
31606
|
+
service: "classroom",
|
|
31607
|
+
examples: '"guardians", "materials", "guardian-invitations"',
|
|
31608
|
+
note: "Covers anything not wrapped by the dedicated tools (guardians, guardian-invitations, materials, coursework assignees, announcement assignees, etc.)."
|
|
31463
31609
|
});
|
|
31464
31610
|
}
|
|
31465
31611
|
|
|
@@ -31515,17 +31661,7 @@ function registerContactsTools(server) {
|
|
|
31515
31661
|
if (title) args.push(`--title=${title}`);
|
|
31516
31662
|
return runOrDiagnose(args, { account });
|
|
31517
31663
|
});
|
|
31518
|
-
server
|
|
31519
|
-
description: "Run any gog contacts subcommand not covered by the other tools. Run `gog contacts --help` for the full list of subcommands, or `gog contacts <subcommand> --help` for flags on a specific subcommand.",
|
|
31520
|
-
annotations: { destructiveHint: true },
|
|
31521
|
-
inputSchema: {
|
|
31522
|
-
subcommand: external_exports.string().describe('The gog contacts subcommand to run, e.g. "update", "delete", "directory"'),
|
|
31523
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31524
|
-
account: accountParam
|
|
31525
|
-
}
|
|
31526
|
-
}, async ({ subcommand, args, account }) => {
|
|
31527
|
-
return runOrDiagnose(["contacts", subcommand, ...args], { account });
|
|
31528
|
-
});
|
|
31664
|
+
registerRunTool(server, { service: "contacts", examples: '"update", "delete", "directory"' });
|
|
31529
31665
|
}
|
|
31530
31666
|
|
|
31531
31667
|
// src/tools/docs.ts
|
|
@@ -31595,17 +31731,7 @@ function registerDocsTools(server) {
|
|
|
31595
31731
|
}, async ({ docId, account }) => {
|
|
31596
31732
|
return runOrDiagnose(["docs", "structure", docId], { account });
|
|
31597
31733
|
});
|
|
31598
|
-
server
|
|
31599
|
-
description: "Run any gog docs subcommand not covered by the other tools. Run `gog docs --help` for the full list of subcommands, or `gog docs <subcommand> --help` for flags on a specific subcommand.",
|
|
31600
|
-
annotations: { destructiveHint: true },
|
|
31601
|
-
inputSchema: {
|
|
31602
|
-
subcommand: external_exports.string().describe('The gog docs subcommand to run, e.g. "copy", "clear", "insert", "sed", "export"'),
|
|
31603
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31604
|
-
account: accountParam
|
|
31605
|
-
}
|
|
31606
|
-
}, async ({ subcommand, args, account }) => {
|
|
31607
|
-
return runOrDiagnose(["docs", subcommand, ...args], { account });
|
|
31608
|
-
});
|
|
31734
|
+
registerRunTool(server, { service: "docs", examples: '"copy", "clear", "insert", "sed", "export"' });
|
|
31609
31735
|
}
|
|
31610
31736
|
|
|
31611
31737
|
// src/tools/drive.ts
|
|
@@ -31713,17 +31839,7 @@ function registerDriveTools(server) {
|
|
|
31713
31839
|
if (role) args.push(`--role=${role}`);
|
|
31714
31840
|
return runOrDiagnose(args, { account });
|
|
31715
31841
|
});
|
|
31716
|
-
server
|
|
31717
|
-
description: "Run any gog drive subcommand not covered by the other tools. Run `gog drive --help` for the full list of subcommands, or `gog drive <subcommand> --help` for flags on a specific subcommand.",
|
|
31718
|
-
annotations: { destructiveHint: true },
|
|
31719
|
-
inputSchema: {
|
|
31720
|
-
subcommand: external_exports.string().describe('The gog drive subcommand to run, e.g. "copy", "upload", "download", "permissions"'),
|
|
31721
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31722
|
-
account: accountParam
|
|
31723
|
-
}
|
|
31724
|
-
}, async ({ subcommand, args, account }) => {
|
|
31725
|
-
return runOrDiagnose(["drive", subcommand, ...args], { account });
|
|
31726
|
-
});
|
|
31842
|
+
registerRunTool(server, { service: "drive", examples: '"copy", "upload", "download", "permissions"' });
|
|
31727
31843
|
}
|
|
31728
31844
|
|
|
31729
31845
|
// src/tools/gmail.ts
|
|
@@ -31775,17 +31891,7 @@ function registerGmailTools(server) {
|
|
|
31775
31891
|
if (threadId) args.push(`--thread-id=${threadId}`);
|
|
31776
31892
|
return runOrDiagnose(args, { account });
|
|
31777
31893
|
});
|
|
31778
|
-
server
|
|
31779
|
-
description: "Run any gog gmail subcommand not covered by the other tools. Run `gog gmail --help` for the full list of subcommands, or `gog gmail <subcommand> --help` for flags on a specific subcommand.",
|
|
31780
|
-
annotations: { destructiveHint: true },
|
|
31781
|
-
inputSchema: {
|
|
31782
|
-
subcommand: external_exports.string().describe('The gog gmail subcommand to run, e.g. "archive", "mark-read", "labels"'),
|
|
31783
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31784
|
-
account: accountParam
|
|
31785
|
-
}
|
|
31786
|
-
}, async ({ subcommand, args, account }) => {
|
|
31787
|
-
return runOrDiagnose(["gmail", subcommand, ...args], { account });
|
|
31788
|
-
});
|
|
31894
|
+
registerRunTool(server, { service: "gmail", examples: '"archive", "mark-read", "labels"' });
|
|
31789
31895
|
}
|
|
31790
31896
|
|
|
31791
31897
|
// src/tools/sheets.ts
|
|
@@ -31874,17 +31980,7 @@ function registerSheetsTools(server) {
|
|
|
31874
31980
|
}, async ({ spreadsheetId, find, replace, account }) => {
|
|
31875
31981
|
return runOrDiagnose(["sheets", "find-replace", spreadsheetId, find, replace], { account });
|
|
31876
31982
|
});
|
|
31877
|
-
server
|
|
31878
|
-
description: "Run any gog sheets subcommand not covered by the other tools. Run `gog sheets --help` for the full list of subcommands, or `gog sheets <subcommand> --help` for flags on a specific subcommand.",
|
|
31879
|
-
annotations: { destructiveHint: true },
|
|
31880
|
-
inputSchema: {
|
|
31881
|
-
subcommand: external_exports.string().describe('The gog sheets subcommand to run, e.g. "freeze", "add-tab", "rename-tab"'),
|
|
31882
|
-
args: external_exports.array(external_exports.string()).describe('Additional positional args and flags, e.g. ["<spreadsheetId>", "--rows=1"]'),
|
|
31883
|
-
account: accountParam
|
|
31884
|
-
}
|
|
31885
|
-
}, async ({ subcommand, args, account }) => {
|
|
31886
|
-
return runOrDiagnose(["sheets", subcommand, ...args], { account });
|
|
31887
|
-
});
|
|
31983
|
+
registerRunTool(server, { service: "sheets", examples: '"freeze", "add-tab", "rename-tab"' });
|
|
31888
31984
|
}
|
|
31889
31985
|
|
|
31890
31986
|
// src/tools/slides.ts
|
|
@@ -31962,17 +32058,7 @@ function registerSlidesTools(server) {
|
|
|
31962
32058
|
}, async ({ presentationId, slideId, account }) => {
|
|
31963
32059
|
return runOrDiagnose(["slides", "read-slide", presentationId, slideId], { account });
|
|
31964
32060
|
});
|
|
31965
|
-
server
|
|
31966
|
-
description: "Run any gog slides subcommand not covered by the other tools. Run `gog slides --help` for the full list of subcommands, or `gog slides <subcommand> --help` for flags on a specific subcommand.",
|
|
31967
|
-
annotations: { destructiveHint: true },
|
|
31968
|
-
inputSchema: {
|
|
31969
|
-
subcommand: external_exports.string().describe("The gog slides subcommand to run"),
|
|
31970
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
31971
|
-
account: accountParam
|
|
31972
|
-
}
|
|
31973
|
-
}, async ({ subcommand, args, account }) => {
|
|
31974
|
-
return runOrDiagnose(["slides", subcommand, ...args], { account });
|
|
31975
|
-
});
|
|
32061
|
+
registerRunTool(server, { service: "slides", examples: '"add-slide", "delete-slide", "update-notes"' });
|
|
31976
32062
|
}
|
|
31977
32063
|
|
|
31978
32064
|
// src/tools/tasks.ts
|
|
@@ -32045,21 +32131,11 @@ function registerTasksTools(server) {
|
|
|
32045
32131
|
}, async ({ tasklistId, taskId, account }) => {
|
|
32046
32132
|
return runOrDiagnose(["tasks", "delete", tasklistId, taskId], { account });
|
|
32047
32133
|
});
|
|
32048
|
-
server
|
|
32049
|
-
description: "Run any gog tasks subcommand not covered by the other tools. Run `gog tasks --help` for the full list of subcommands, or `gog tasks <subcommand> --help` for flags on a specific subcommand.",
|
|
32050
|
-
annotations: { destructiveHint: true },
|
|
32051
|
-
inputSchema: {
|
|
32052
|
-
subcommand: external_exports.string().describe('The gog tasks subcommand to run, e.g. "update", "undo", "clear"'),
|
|
32053
|
-
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
32054
|
-
account: accountParam
|
|
32055
|
-
}
|
|
32056
|
-
}, async ({ subcommand, args, account }) => {
|
|
32057
|
-
return runOrDiagnose(["tasks", subcommand, ...args], { account });
|
|
32058
|
-
});
|
|
32134
|
+
registerRunTool(server, { service: "tasks", examples: '"update", "undo", "clear"' });
|
|
32059
32135
|
}
|
|
32060
32136
|
|
|
32061
32137
|
// src/server.ts
|
|
32062
|
-
var VERSION = true ? "2.0.
|
|
32138
|
+
var VERSION = true ? "2.0.9" : "0.0.0";
|
|
32063
32139
|
function createServer(options) {
|
|
32064
32140
|
return new McpServer({
|
|
32065
32141
|
name: options?.name ?? "gogcli",
|
|
@@ -32085,6 +32161,9 @@ export {
|
|
|
32085
32161
|
accountParam,
|
|
32086
32162
|
createBaseServer,
|
|
32087
32163
|
createServer,
|
|
32164
|
+
ids,
|
|
32165
|
+
paginationParams,
|
|
32166
|
+
pushPaginationFlags,
|
|
32088
32167
|
registerAuthTools,
|
|
32089
32168
|
registerCalendarTools,
|
|
32090
32169
|
registerClassroomTools,
|
|
@@ -32092,6 +32171,7 @@ export {
|
|
|
32092
32171
|
registerDocsTools,
|
|
32093
32172
|
registerDriveTools,
|
|
32094
32173
|
registerGmailTools,
|
|
32174
|
+
registerRunTool,
|
|
32095
32175
|
registerSheetsTools,
|
|
32096
32176
|
registerSlidesTools,
|
|
32097
32177
|
registerTasksTools,
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp",
|
|
5
5
|
"display_name": "gogcli",
|
|
6
|
-
"version": "2.0.
|
|
6
|
+
"version": "2.0.9",
|
|
7
7
|
"description": "Google Sheets (and more) for Claude via gogcli — read, write, and manage spreadsheets",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp",
|
|
5
5
|
"description": "MCP server wrapping gogcli for Google service access",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^25.6.2",
|
|
49
|
-
"@vitest/coverage-v8": "^4.1.
|
|
49
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
50
50
|
"esbuild": "^0.28.0",
|
|
51
51
|
"typescript": "^6.0.2",
|
|
52
|
-
"vitest": "^4.1.
|
|
52
|
+
"vitest": "^4.1.6"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/gogcli-mcp"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.0.
|
|
10
|
+
"version": "2.0.9",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp",
|
|
15
|
-
"version": "2.0.
|
|
15
|
+
"version": "2.0.9",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|