gogcli-mcp-drive 2.23.1 → 2.24.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +104 -48
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/tools/drive-extra.ts +35 -17
- package/tests/tools/drive-extra.test.ts +16 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Extended Google Drive for Claude via gogcli — auth + full Drive support (upload, download, permissions, comments, shared drives)",
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.24.0"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "gogcli (Drive)",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Extended Google Drive for Claude via gogcli — auth + full Drive support (upload, download, permissions, comments, shared drives)",
|
|
18
|
-
"version": "2.
|
|
18
|
+
"version": "2.24.0",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-drive",
|
|
3
3
|
"displayName": "gogcli (Drive)",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.24.0",
|
|
5
5
|
"description": "Extended Google Drive for Claude via gogcli — auth + full Drive support (upload, download, permissions, comments, shared drives)",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/dist/index.js
CHANGED
|
@@ -31552,6 +31552,26 @@ function normalizeTimestamps(text, tz = displayTimeZone(), naiveTz = naiveSource
|
|
|
31552
31552
|
return JSON.stringify(parsed, null, detectIndent(text));
|
|
31553
31553
|
}
|
|
31554
31554
|
|
|
31555
|
+
// ../gogcli-mcp/src/pagination.ts
|
|
31556
|
+
function detectIndent2(text) {
|
|
31557
|
+
const match = /\n(\s+)\S/.exec(text);
|
|
31558
|
+
return match ? match[1].replace(/\t/g, " ").length : 0;
|
|
31559
|
+
}
|
|
31560
|
+
function stripConsumedPageToken(text) {
|
|
31561
|
+
const trimmed = text.trim();
|
|
31562
|
+
if (trimmed === "" || !trimmed.startsWith("{")) return text;
|
|
31563
|
+
let parsed;
|
|
31564
|
+
try {
|
|
31565
|
+
parsed = JSON.parse(trimmed);
|
|
31566
|
+
} catch {
|
|
31567
|
+
return text;
|
|
31568
|
+
}
|
|
31569
|
+
const obj = parsed;
|
|
31570
|
+
if (obj.nextPageToken !== "") return text;
|
|
31571
|
+
delete obj.nextPageToken;
|
|
31572
|
+
return JSON.stringify(obj, null, detectIndent2(text));
|
|
31573
|
+
}
|
|
31574
|
+
|
|
31555
31575
|
// ../gogcli-mcp/src/tools/utils.ts
|
|
31556
31576
|
var accountParam = external_exports.string().optional().describe(
|
|
31557
31577
|
"Google account email to use, e.g. you@gmail.com \u2014 must be the full address, not a bare username. Overrides the GOG_ACCOUNT env var. Omit to use the single configured account."
|
|
@@ -31580,14 +31600,25 @@ var ids = {
|
|
|
31580
31600
|
// People API uses fully-qualified resource names ("people/c123") not bare IDs.
|
|
31581
31601
|
person: external_exports.string().describe("Person resource name (people/...) or email")
|
|
31582
31602
|
};
|
|
31603
|
+
var pageTokenParam = external_exports.string().optional().describe(
|
|
31604
|
+
"Cursor for the NEXT page. Pass back the nextPageToken from a previous response verbatim, keeping the query and max identical: call once, then call again with pageToken=<that value>. A response with NO nextPageToken is the last page."
|
|
31605
|
+
);
|
|
31606
|
+
var pageAliasParam = external_exports.string().optional().describe(
|
|
31607
|
+
"Deprecated alias for pageToken, accepted so existing callers keep working. Use pageToken \u2014 it matches the nextPageToken field in the response."
|
|
31608
|
+
);
|
|
31609
|
+
function resolvePageToken(p) {
|
|
31610
|
+
return p.pageToken ?? p.page;
|
|
31611
|
+
}
|
|
31583
31612
|
var paginationParams = {
|
|
31584
31613
|
max: external_exports.number().int().optional().describe("Max results"),
|
|
31585
|
-
|
|
31614
|
+
pageToken: pageTokenParam,
|
|
31615
|
+
page: pageAliasParam,
|
|
31586
31616
|
all: external_exports.boolean().optional().describe("Fetch all pages")
|
|
31587
31617
|
};
|
|
31588
31618
|
function pushPaginationFlags(args, p) {
|
|
31589
31619
|
if (p.max !== void 0) args.push(`--max=${p.max}`);
|
|
31590
|
-
|
|
31620
|
+
const token = resolvePageToken(p);
|
|
31621
|
+
if (token) args.push(`--page=${token}`);
|
|
31591
31622
|
if (p.all) args.push("--all");
|
|
31592
31623
|
}
|
|
31593
31624
|
function registerRunTool(server, options) {
|
|
@@ -31662,7 +31693,7 @@ ${accounts || "(none)"}${hint}`);
|
|
|
31662
31693
|
async function runOrDiagnose(args, options) {
|
|
31663
31694
|
try {
|
|
31664
31695
|
const raw = await run(args, options);
|
|
31665
|
-
return rawTextResult(options.lossless ? raw : normalizeTimestamps(raw));
|
|
31696
|
+
return rawTextResult(options.lossless ? raw : stripConsumedPageToken(normalizeTimestamps(raw)));
|
|
31666
31697
|
} catch (err) {
|
|
31667
31698
|
return diagnose(err);
|
|
31668
31699
|
}
|
|
@@ -31712,6 +31743,7 @@ function formatAuthHealth(raw, now) {
|
|
|
31712
31743
|
// ../gogcli-mcp/src/tools/auth.ts
|
|
31713
31744
|
function registerAuthToolsWith(server, defaultServices) {
|
|
31714
31745
|
const servicesDescribe = `Services to authorize: "all" or comma-separated list (e.g. "sheets,gmail,calendar"). Default: "${defaultServices}". Prefer the narrowest set you need \u2014 requesting a service whose Google API is not enabled on the OAuth client's project makes Google reject the WHOLE request with invalid_scope.`;
|
|
31746
|
+
const extraScopesDescribe = "Additional raw OAuth scope URIs to request, comma-separated, on top of the ones `services` implies. Use for scopes no service covers \u2014 e.g. https://www.googleapis.com/auth/bigquery.readonly, required before gog_sheets_datasource_* can read BigQuery-backed Connected Sheets. Leave unset otherwise: an extra scope whose API is not enabled on the OAuth client project makes Google reject the WHOLE authorization with invalid_scope.";
|
|
31715
31747
|
server.registerTool("gog_auth_list", {
|
|
31716
31748
|
description: "List the Google accounts stored in gogcli, with their scopes. This reads local configuration only \u2014 it does not contact Google and does NOT tell you whether an account still works: a signed-out account whose refresh token expired or was revoked is listed here exactly like a healthy one, scopes and all. Use gog_auth_health to check whether an account can actually authenticate.",
|
|
31717
31749
|
annotations: { readOnlyHint: true },
|
|
@@ -31761,11 +31793,14 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
31761
31793
|
annotations: { destructiveHint: true },
|
|
31762
31794
|
inputSchema: {
|
|
31763
31795
|
email: external_exports.string().describe("Google account email to authorize"),
|
|
31764
|
-
services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe)
|
|
31796
|
+
services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe),
|
|
31797
|
+
extraScopes: external_exports.string().optional().describe(extraScopesDescribe)
|
|
31765
31798
|
}
|
|
31766
|
-
}, async ({ email: email3, services = defaultServices }) => {
|
|
31799
|
+
}, async ({ email: email3, services = defaultServices, extraScopes }) => {
|
|
31767
31800
|
try {
|
|
31768
|
-
|
|
31801
|
+
const args = ["auth", "add", email3, "--services", services];
|
|
31802
|
+
if (extraScopes) args.push(`--extra-scopes=${extraScopes}`, "--force-consent");
|
|
31803
|
+
return rawTextResult(await run(args, {
|
|
31769
31804
|
interactive: true,
|
|
31770
31805
|
timeout: 3e5
|
|
31771
31806
|
}));
|
|
@@ -31777,14 +31812,14 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
31777
31812
|
description: "Begin REMOTE/headless Google authorization (step 1 of 2). Returns a sign-in URL to open in any browser \u2014 no local server or terminal on the gogcli host is needed, so this works over the hosted connector where the interactive gog_auth_add cannot. Hand the URL to the user; after they sign in, the browser is redirected to a localhost URL that fails to load \u2014 that is expected. They copy that full redirected URL (from the address bar) and you pass it to gog_auth_add_complete. The link is valid for 10 minutes. If you pass a custom `services` here, pass the SAME value to gog_auth_add_complete or the second step will not match this one.",
|
|
31778
31813
|
inputSchema: {
|
|
31779
31814
|
email: external_exports.string().describe("Google account email to authorize"),
|
|
31780
|
-
services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe)
|
|
31815
|
+
services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe),
|
|
31816
|
+
extraScopes: external_exports.string().optional().describe(`${extraScopesDescribe} Pass the SAME value to gog_auth_add_complete.`)
|
|
31781
31817
|
}
|
|
31782
|
-
}, async ({ email: email3, services = defaultServices }) => {
|
|
31818
|
+
}, async ({ email: email3, services = defaultServices, extraScopes }) => {
|
|
31783
31819
|
try {
|
|
31784
|
-
|
|
31785
|
-
|
|
31786
|
-
|
|
31787
|
-
));
|
|
31820
|
+
const args = ["auth", "add", email3, "--remote", "--step", "1", "--services", services, "--force-consent"];
|
|
31821
|
+
if (extraScopes) args.push(`--extra-scopes=${extraScopes}`);
|
|
31822
|
+
return rawTextResult(await run(args, { redactMode: "tokens" }));
|
|
31788
31823
|
} catch (err) {
|
|
31789
31824
|
return errorResult(errorText(err));
|
|
31790
31825
|
}
|
|
@@ -31799,25 +31834,28 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
31799
31834
|
),
|
|
31800
31835
|
services: external_exports.string().optional().default(defaultServices).describe(
|
|
31801
31836
|
`Services authorized \u2014 MUST match the value passed to gog_auth_add_url. Default: "${defaultServices}".`
|
|
31837
|
+
),
|
|
31838
|
+
extraScopes: external_exports.string().optional().describe(
|
|
31839
|
+
"Extra OAuth scope URIs \u2014 MUST match the value passed to gog_auth_add_url, for the same reason `services` must: the two steps have to describe the same grant."
|
|
31802
31840
|
)
|
|
31803
31841
|
}
|
|
31804
|
-
}, async ({ email: email3, redirectUrl, services = defaultServices }) => {
|
|
31842
|
+
}, async ({ email: email3, redirectUrl, services = defaultServices, extraScopes }) => {
|
|
31805
31843
|
try {
|
|
31806
|
-
|
|
31807
|
-
|
|
31808
|
-
|
|
31809
|
-
|
|
31810
|
-
|
|
31811
|
-
|
|
31812
|
-
|
|
31813
|
-
|
|
31814
|
-
|
|
31815
|
-
|
|
31816
|
-
|
|
31817
|
-
|
|
31818
|
-
|
|
31819
|
-
|
|
31820
|
-
));
|
|
31844
|
+
const args = [
|
|
31845
|
+
"auth",
|
|
31846
|
+
"add",
|
|
31847
|
+
email3,
|
|
31848
|
+
"--remote",
|
|
31849
|
+
"--step",
|
|
31850
|
+
"2",
|
|
31851
|
+
"--auth-url",
|
|
31852
|
+
redirectUrl,
|
|
31853
|
+
"--services",
|
|
31854
|
+
services,
|
|
31855
|
+
"--force-consent"
|
|
31856
|
+
];
|
|
31857
|
+
if (extraScopes) args.push(`--extra-scopes=${extraScopes}`);
|
|
31858
|
+
return rawTextResult(await run(args));
|
|
31821
31859
|
} catch (err) {
|
|
31822
31860
|
return errorResult(errorText(err));
|
|
31823
31861
|
}
|
|
@@ -31847,16 +31885,18 @@ function registerDriveTools(server) {
|
|
|
31847
31885
|
inputSchema: {
|
|
31848
31886
|
folderId: external_exports.string().optional().describe("Folder ID to list (default: root)"),
|
|
31849
31887
|
max: external_exports.number().optional().describe("Max results (default: 20)"),
|
|
31850
|
-
|
|
31888
|
+
pageToken: pageTokenParam,
|
|
31889
|
+
page: pageAliasParam,
|
|
31851
31890
|
query: external_exports.string().optional().describe(`Drive query filter (e.g. "name contains 'budget'")`),
|
|
31852
31891
|
allDrives: external_exports.boolean().optional().describe("Include shared drives (default: true). Set false for My Drive only."),
|
|
31853
31892
|
account: accountParam
|
|
31854
31893
|
}
|
|
31855
|
-
}, async ({ folderId, max, page, query, allDrives, account }) => {
|
|
31894
|
+
}, async ({ folderId, max, pageToken, page, query, allDrives, account }) => {
|
|
31856
31895
|
const args = ["drive", "ls"];
|
|
31857
31896
|
if (folderId) args.push(`--parent=${folderId}`);
|
|
31858
31897
|
if (max !== void 0) args.push(`--max=${max}`);
|
|
31859
|
-
|
|
31898
|
+
const token = resolvePageToken({ pageToken, page });
|
|
31899
|
+
if (token) args.push(`--page=${token}`);
|
|
31860
31900
|
if (query) args.push(`--query=${query}`);
|
|
31861
31901
|
if (allDrives === false) args.push("--no-all-drives");
|
|
31862
31902
|
return runOrDiagnose(args, { account });
|
|
@@ -32056,7 +32096,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
|
|
|
32056
32096
|
);
|
|
32057
32097
|
|
|
32058
32098
|
// ../gogcli-mcp/src/server.ts
|
|
32059
|
-
var VERSION = true ? "2.
|
|
32099
|
+
var VERSION = true ? "2.24.0" : "0.0.0";
|
|
32060
32100
|
|
|
32061
32101
|
// ../gogcli-mcp/src/auth-log.ts
|
|
32062
32102
|
var FAILURES = /* @__PURE__ */ new Set([
|
|
@@ -32638,13 +32678,15 @@ function registerExtraDriveTools(server) {
|
|
|
32638
32678
|
inputSchema: {
|
|
32639
32679
|
fileId: external_exports.string().describe("File ID"),
|
|
32640
32680
|
max: external_exports.number().optional().describe("Max results (default: 100)"),
|
|
32641
|
-
|
|
32681
|
+
pageToken: pageTokenParam,
|
|
32682
|
+
page: pageAliasParam,
|
|
32642
32683
|
account: accountParam
|
|
32643
32684
|
}
|
|
32644
|
-
}, async ({ fileId, max, page, account }) => {
|
|
32685
|
+
}, async ({ fileId, max, pageToken, page, account }) => {
|
|
32645
32686
|
const args = ["drive", "permissions", fileId];
|
|
32646
32687
|
if (max !== void 0) args.push(`--max=${max}`);
|
|
32647
|
-
|
|
32688
|
+
const token = resolvePageToken({ pageToken, page });
|
|
32689
|
+
if (token) args.push(`--page=${token}`);
|
|
32648
32690
|
return runOrDiagnose(args, { account });
|
|
32649
32691
|
});
|
|
32650
32692
|
server.registerTool("gog_drive_unshare", {
|
|
@@ -32663,15 +32705,17 @@ function registerExtraDriveTools(server) {
|
|
|
32663
32705
|
annotations: { readOnlyHint: true },
|
|
32664
32706
|
inputSchema: {
|
|
32665
32707
|
max: external_exports.number().optional().describe("Max results (default: 100, max allowed: 100)"),
|
|
32666
|
-
|
|
32708
|
+
pageToken: pageTokenParam,
|
|
32709
|
+
page: pageAliasParam,
|
|
32667
32710
|
all: external_exports.boolean().optional().describe("Fetch all pages"),
|
|
32668
32711
|
query: external_exports.string().optional().describe("Search query for filtering shared drives"),
|
|
32669
32712
|
account: accountParam
|
|
32670
32713
|
}
|
|
32671
|
-
}, async ({ max, page, all, query, account }) => {
|
|
32714
|
+
}, async ({ max, pageToken, page, all, query, account }) => {
|
|
32672
32715
|
const args = ["drive", "drives"];
|
|
32673
32716
|
if (max !== void 0) args.push(`--max=${max}`);
|
|
32674
|
-
|
|
32717
|
+
const token = resolvePageToken({ pageToken, page });
|
|
32718
|
+
if (token) args.push(`--page=${token}`);
|
|
32675
32719
|
if (all) args.push("--all");
|
|
32676
32720
|
if (query) args.push(`--query=${query}`);
|
|
32677
32721
|
return runOrDiagnose(args, { account });
|
|
@@ -32831,16 +32875,18 @@ function registerExtraDriveTools(server) {
|
|
|
32831
32875
|
inputSchema: {
|
|
32832
32876
|
token: external_exports.string().describe("Start page token or next page token"),
|
|
32833
32877
|
max: external_exports.number().optional().describe("Max results (default: 100)"),
|
|
32834
|
-
|
|
32878
|
+
pageToken: pageTokenParam,
|
|
32879
|
+
page: pageAliasParam,
|
|
32835
32880
|
all: external_exports.boolean().optional().describe("Fetch all pages"),
|
|
32836
32881
|
includeRemoved: external_exports.boolean().optional().describe("Include removed changes"),
|
|
32837
32882
|
drive: external_exports.string().optional().describe("Shared drive ID for a shared-drive change log"),
|
|
32838
32883
|
account: accountParam
|
|
32839
32884
|
}
|
|
32840
|
-
}, async ({ token, max, page, all, includeRemoved, drive, account }) => {
|
|
32885
|
+
}, async ({ token, max, pageToken, page, all, includeRemoved, drive, account }) => {
|
|
32841
32886
|
const args = ["drive", "changes", "list", `--token=${token}`];
|
|
32842
32887
|
if (max !== void 0) args.push(`--max=${max}`);
|
|
32843
|
-
|
|
32888
|
+
const cursor = resolvePageToken({ pageToken, page });
|
|
32889
|
+
if (cursor) args.push(`--page=${cursor}`);
|
|
32844
32890
|
if (all) args.push("--all");
|
|
32845
32891
|
if (includeRemoved) args.push("--include-removed");
|
|
32846
32892
|
if (drive) args.push(`--drive=${drive}`);
|
|
@@ -32892,10 +32938,16 @@ function registerExtraDriveTools(server) {
|
|
|
32892
32938
|
minimumRole: external_exports.string().optional().describe("Minimum role filter (e.g. READER, APPLIER, ORGANIZER)"),
|
|
32893
32939
|
publishedOnly: external_exports.boolean().optional().describe("Only list published labels"),
|
|
32894
32940
|
adminAccess: external_exports.boolean().optional().describe("Use admin access for Workspace admin accounts"),
|
|
32941
|
+
max: external_exports.number().int().optional().describe("Max results"),
|
|
32942
|
+
pageToken: pageTokenParam,
|
|
32943
|
+
page: pageAliasParam,
|
|
32895
32944
|
account: accountParam
|
|
32896
32945
|
}
|
|
32897
|
-
}, async ({ language, view, minimumRole, publishedOnly, adminAccess, account }) => {
|
|
32946
|
+
}, async ({ language, view, minimumRole, publishedOnly, adminAccess, max, pageToken, page, account }) => {
|
|
32898
32947
|
const args = ["drive", "labels", "list"];
|
|
32948
|
+
if (max !== void 0) args.push(`--max=${max}`);
|
|
32949
|
+
const token = resolvePageToken({ pageToken, page });
|
|
32950
|
+
if (token) args.push(`--page=${token}`);
|
|
32899
32951
|
if (language) args.push(`--language=${language}`);
|
|
32900
32952
|
if (view) args.push(`--view=${view}`);
|
|
32901
32953
|
if (minimumRole) args.push(`--minimum-role=${minimumRole}`);
|
|
@@ -32926,13 +32978,15 @@ function registerExtraDriveTools(server) {
|
|
|
32926
32978
|
inputSchema: {
|
|
32927
32979
|
fileId: external_exports.string().describe("File ID"),
|
|
32928
32980
|
max: external_exports.number().optional().describe("Max results (default: 100)"),
|
|
32929
|
-
|
|
32981
|
+
pageToken: pageTokenParam,
|
|
32982
|
+
page: pageAliasParam,
|
|
32930
32983
|
account: accountParam
|
|
32931
32984
|
}
|
|
32932
|
-
}, async ({ fileId, max, page, account }) => {
|
|
32985
|
+
}, async ({ fileId, max, pageToken, page, account }) => {
|
|
32933
32986
|
const args = ["drive", "labels", "file", "list", fileId];
|
|
32934
32987
|
if (max !== void 0) args.push(`--max=${max}`);
|
|
32935
|
-
|
|
32988
|
+
const token = resolvePageToken({ pageToken, page });
|
|
32989
|
+
if (token) args.push(`--page=${token}`);
|
|
32936
32990
|
return runOrDiagnose(args, { account });
|
|
32937
32991
|
});
|
|
32938
32992
|
server.registerTool("gog_drive_labels_file_apply", {
|
|
@@ -32982,12 +33036,13 @@ function registerExtraDriveTools(server) {
|
|
|
32982
33036
|
to: external_exports.string().optional().describe("Upper activity time bound (RFC3339)"),
|
|
32983
33037
|
filter: external_exports.string().optional().describe("Raw Drive Activity filter expression appended with AND"),
|
|
32984
33038
|
max: external_exports.number().optional().describe("Page size (default: 10)"),
|
|
32985
|
-
|
|
33039
|
+
pageToken: pageTokenParam,
|
|
33040
|
+
page: pageAliasParam,
|
|
32986
33041
|
all: external_exports.boolean().optional().describe("Fetch all pages"),
|
|
32987
33042
|
consolidate: external_exports.boolean().optional().describe("Use Drive Activity legacy consolidation strategy"),
|
|
32988
33043
|
account: accountParam
|
|
32989
33044
|
}
|
|
32990
|
-
}, async ({ file: file2, folder, actions, from, to, filter, max, page, all, consolidate, account }) => {
|
|
33045
|
+
}, async ({ file: file2, folder, actions, from, to, filter, max, pageToken, page, all, consolidate, account }) => {
|
|
32991
33046
|
const args = ["drive", "activity", "query"];
|
|
32992
33047
|
if (file2) args.push(`--file=${file2}`);
|
|
32993
33048
|
if (folder) args.push(`--folder=${folder}`);
|
|
@@ -32996,7 +33051,8 @@ function registerExtraDriveTools(server) {
|
|
|
32996
33051
|
if (to) args.push(`--to=${to}`);
|
|
32997
33052
|
if (filter) args.push(`--filter=${filter}`);
|
|
32998
33053
|
if (max !== void 0) args.push(`--max=${max}`);
|
|
32999
|
-
|
|
33054
|
+
const token = resolvePageToken({ pageToken, page });
|
|
33055
|
+
if (token) args.push(`--page=${token}`);
|
|
33000
33056
|
if (all) args.push("--all");
|
|
33001
33057
|
if (consolidate) args.push("--consolidate");
|
|
33002
33058
|
return runOrDiagnose(args, { account });
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp-drive",
|
|
5
5
|
"display_name": "gogcli (Drive)",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.24.0",
|
|
7
7
|
"description": "Extended Google Drive for Claude via gogcli — auth + full Drive support (upload, download, permissions, comments, shared drives)",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
|
@@ -227,7 +227,7 @@
|
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
229
|
"name": "gog_drive_labels_list",
|
|
230
|
-
"description": "List Drive label schemas"
|
|
230
|
+
"description": "List Drive label schemas available to the account; paginated"
|
|
231
231
|
},
|
|
232
232
|
{
|
|
233
233
|
"name": "gog_drive_labels_get",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-drive",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.24.0",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp-drive",
|
|
5
5
|
"description": "Extended Google Drive MCP server via gogcli — auth + full Drive support (upload/download/permissions/comments/shared drives)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/gogcli-mcp-drive"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.24.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp-drive",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.24.0",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
package/src/tools/drive-extra.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { accountParam, runOrDiagnose, paginationParams, pushPaginationFlags } from '../../../gogcli-mcp/src/lib.js';
|
|
3
|
+
import { accountParam, runOrDiagnose, paginationParams, pushPaginationFlags, pageTokenParam, pageAliasParam, resolvePageToken} from '../../../gogcli-mcp/src/lib.js';
|
|
4
4
|
|
|
5
5
|
export function registerExtraDriveTools(server: McpServer): void {
|
|
6
6
|
server.registerTool('gog_drive_download', {
|
|
@@ -111,13 +111,15 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
111
111
|
inputSchema: {
|
|
112
112
|
fileId: z.string().describe('File ID'),
|
|
113
113
|
max: z.number().optional().describe('Max results (default: 100)'),
|
|
114
|
-
|
|
114
|
+
pageToken: pageTokenParam,
|
|
115
|
+
page: pageAliasParam,
|
|
115
116
|
account: accountParam,
|
|
116
117
|
},
|
|
117
|
-
}, async ({ fileId, max, page, account }) => {
|
|
118
|
+
}, async ({ fileId, max, pageToken, page, account }) => {
|
|
118
119
|
const args = ['drive', 'permissions', fileId];
|
|
119
120
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
120
|
-
|
|
121
|
+
const token = resolvePageToken({ pageToken, page });
|
|
122
|
+
if (token) args.push(`--page=${token}`);
|
|
121
123
|
return runOrDiagnose(args, { account });
|
|
122
124
|
});
|
|
123
125
|
|
|
@@ -138,15 +140,17 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
138
140
|
annotations: { readOnlyHint: true },
|
|
139
141
|
inputSchema: {
|
|
140
142
|
max: z.number().optional().describe('Max results (default: 100, max allowed: 100)'),
|
|
141
|
-
|
|
143
|
+
pageToken: pageTokenParam,
|
|
144
|
+
page: pageAliasParam,
|
|
142
145
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
143
146
|
query: z.string().optional().describe('Search query for filtering shared drives'),
|
|
144
147
|
account: accountParam,
|
|
145
148
|
},
|
|
146
|
-
}, async ({ max, page, all, query, account }) => {
|
|
149
|
+
}, async ({ max, pageToken, page, all, query, account }) => {
|
|
147
150
|
const args = ['drive', 'drives'];
|
|
148
151
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
149
|
-
|
|
152
|
+
const token = resolvePageToken({ pageToken, page });
|
|
153
|
+
if (token) args.push(`--page=${token}`);
|
|
150
154
|
if (all) args.push('--all');
|
|
151
155
|
if (query) args.push(`--query=${query}`);
|
|
152
156
|
return runOrDiagnose(args, { account });
|
|
@@ -320,16 +324,20 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
320
324
|
inputSchema: {
|
|
321
325
|
token: z.string().describe('Start page token or next page token'),
|
|
322
326
|
max: z.number().optional().describe('Max results (default: 100)'),
|
|
323
|
-
|
|
327
|
+
pageToken: pageTokenParam,
|
|
328
|
+
page: pageAliasParam,
|
|
324
329
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
325
330
|
includeRemoved: z.boolean().optional().describe('Include removed changes'),
|
|
326
331
|
drive: z.string().optional().describe('Shared drive ID for a shared-drive change log'),
|
|
327
332
|
account: accountParam,
|
|
328
333
|
},
|
|
329
|
-
}, async ({ token, max, page, all, includeRemoved, drive, account }) => {
|
|
334
|
+
}, async ({ token, max, pageToken, page, all, includeRemoved, drive, account }) => {
|
|
330
335
|
const args = ['drive', 'changes', 'list', `--token=${token}`];
|
|
331
336
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
332
|
-
|
|
337
|
+
// NOT `token` — this tool already binds that name to the start-page token
|
|
338
|
+
// it takes as a required arg, which is a different value entirely.
|
|
339
|
+
const cursor = resolvePageToken({ pageToken, page });
|
|
340
|
+
if (cursor) args.push(`--page=${cursor}`);
|
|
333
341
|
if (all) args.push('--all');
|
|
334
342
|
if (includeRemoved) args.push('--include-removed');
|
|
335
343
|
if (drive) args.push(`--drive=${drive}`);
|
|
@@ -385,10 +393,16 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
385
393
|
minimumRole: z.string().optional().describe('Minimum role filter (e.g. READER, APPLIER, ORGANIZER)'),
|
|
386
394
|
publishedOnly: z.boolean().optional().describe('Only list published labels'),
|
|
387
395
|
adminAccess: z.boolean().optional().describe('Use admin access for Workspace admin accounts'),
|
|
396
|
+
max: z.number().int().optional().describe('Max results'),
|
|
397
|
+
pageToken: pageTokenParam,
|
|
398
|
+
page: pageAliasParam,
|
|
388
399
|
account: accountParam,
|
|
389
400
|
},
|
|
390
|
-
}, async ({ language, view, minimumRole, publishedOnly, adminAccess, account }) => {
|
|
401
|
+
}, async ({ language, view, minimumRole, publishedOnly, adminAccess, max, pageToken, page, account }) => {
|
|
391
402
|
const args = ['drive', 'labels', 'list'];
|
|
403
|
+
if (max !== undefined) args.push(`--max=${max}`);
|
|
404
|
+
const token = resolvePageToken({ pageToken, page });
|
|
405
|
+
if (token) args.push(`--page=${token}`);
|
|
392
406
|
if (language) args.push(`--language=${language}`);
|
|
393
407
|
if (view) args.push(`--view=${view}`);
|
|
394
408
|
if (minimumRole) args.push(`--minimum-role=${minimumRole}`);
|
|
@@ -421,13 +435,15 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
421
435
|
inputSchema: {
|
|
422
436
|
fileId: z.string().describe('File ID'),
|
|
423
437
|
max: z.number().optional().describe('Max results (default: 100)'),
|
|
424
|
-
|
|
438
|
+
pageToken: pageTokenParam,
|
|
439
|
+
page: pageAliasParam,
|
|
425
440
|
account: accountParam,
|
|
426
441
|
},
|
|
427
|
-
}, async ({ fileId, max, page, account }) => {
|
|
442
|
+
}, async ({ fileId, max, pageToken, page, account }) => {
|
|
428
443
|
const args = ['drive', 'labels', 'file', 'list', fileId];
|
|
429
444
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
430
|
-
|
|
445
|
+
const token = resolvePageToken({ pageToken, page });
|
|
446
|
+
if (token) args.push(`--page=${token}`);
|
|
431
447
|
return runOrDiagnose(args, { account });
|
|
432
448
|
});
|
|
433
449
|
|
|
@@ -480,12 +496,13 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
480
496
|
to: z.string().optional().describe('Upper activity time bound (RFC3339)'),
|
|
481
497
|
filter: z.string().optional().describe('Raw Drive Activity filter expression appended with AND'),
|
|
482
498
|
max: z.number().optional().describe('Page size (default: 10)'),
|
|
483
|
-
|
|
499
|
+
pageToken: pageTokenParam,
|
|
500
|
+
page: pageAliasParam,
|
|
484
501
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
485
502
|
consolidate: z.boolean().optional().describe('Use Drive Activity legacy consolidation strategy'),
|
|
486
503
|
account: accountParam,
|
|
487
504
|
},
|
|
488
|
-
}, async ({ file, folder, actions, from, to, filter, max, page, all, consolidate, account }) => {
|
|
505
|
+
}, async ({ file, folder, actions, from, to, filter, max, pageToken, page, all, consolidate, account }) => {
|
|
489
506
|
const args = ['drive', 'activity', 'query'];
|
|
490
507
|
if (file) args.push(`--file=${file}`);
|
|
491
508
|
if (folder) args.push(`--folder=${folder}`);
|
|
@@ -494,7 +511,8 @@ export function registerExtraDriveTools(server: McpServer): void {
|
|
|
494
511
|
if (to) args.push(`--to=${to}`);
|
|
495
512
|
if (filter) args.push(`--filter=${filter}`);
|
|
496
513
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
497
|
-
|
|
514
|
+
const token = resolvePageToken({ pageToken, page });
|
|
515
|
+
if (token) args.push(`--page=${token}`);
|
|
498
516
|
if (all) args.push('--all');
|
|
499
517
|
if (consolidate) args.push('--consolidate');
|
|
500
518
|
return runOrDiagnose(args, { account });
|
|
@@ -459,6 +459,22 @@ describe('gog_drive_labels_list', () => {
|
|
|
459
459
|
await harness.callTool('gog_drive_labels_list', { publishedOnly: false, adminAccess: false });
|
|
460
460
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['drive', 'labels', 'list'], { account: undefined });
|
|
461
461
|
});
|
|
462
|
+
|
|
463
|
+
// gog drive labels list is paginated upstream; the tool exposed neither max
|
|
464
|
+
// nor a cursor, so later pages were unreachable.
|
|
465
|
+
it('passes --max and --page through', async () => {
|
|
466
|
+
await harness.callTool('gog_drive_labels_list', { max: 50, pageToken: 'CURSOR' });
|
|
467
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
468
|
+
['drive', 'labels', 'list', '--max=50', '--page=CURSOR'], { account: undefined },
|
|
469
|
+
);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it('accepts the deprecated page alias', async () => {
|
|
473
|
+
await harness.callTool('gog_drive_labels_list', { page: 'CURSOR' });
|
|
474
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
475
|
+
['drive', 'labels', 'list', '--page=CURSOR'], { account: undefined },
|
|
476
|
+
);
|
|
477
|
+
});
|
|
462
478
|
});
|
|
463
479
|
|
|
464
480
|
describe('gog_drive_labels_get', () => {
|