gogcli-mcp-drive 2.8.0 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-drive",
5
5
  "display_name": "gogcli (Drive)",
6
- "version": "2.8.0",
6
+ "version": "2.18.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",
@@ -61,6 +61,18 @@
61
61
  "name": "gog_auth_add",
62
62
  "description": "Authorize a Google account via browser-based OAuth"
63
63
  },
64
+ {
65
+ "name": "gog_auth_health",
66
+ "description": "Live per-account token health: validity, age, and pre-expiry warnings (detects invalid_grant)"
67
+ },
68
+ {
69
+ "name": "gog_auth_add_url",
70
+ "description": "Begin remote/headless OAuth (step 1): return a sign-in URL to open in any browser"
71
+ },
72
+ {
73
+ "name": "gog_auth_add_complete",
74
+ "description": "Complete remote/headless OAuth (step 2): exchange the pasted redirect URL and store the token"
75
+ },
64
76
  {
65
77
  "name": "gog_auth_list",
66
78
  "description": "List all Google accounts stored in gogcli"
@@ -85,6 +97,14 @@
85
97
  "name": "gog_drive_search",
86
98
  "description": "Full-text search across Drive"
87
99
  },
100
+ {
101
+ "name": "gog_drive_extract_text",
102
+ "description": "Extract readable text from a Drive PDF/image/doc (OCR-converts, returns text; no host FS)"
103
+ },
104
+ {
105
+ "name": "gog_drive_read_bytes",
106
+ "description": "Fetch a Drive file's raw bytes as a base64 resource (local stdio only; connector returns text-only notice)"
107
+ },
88
108
  {
89
109
  "name": "gog_drive_get",
90
110
  "description": "Get file metadata"
@@ -121,6 +141,10 @@
121
141
  "name": "gog_drive_upload",
122
142
  "description": "Upload a local file, optionally replacing an existing file or converting to Google format"
123
143
  },
144
+ {
145
+ "name": "gog_drive_sync_push",
146
+ "description": "Recursively push a local directory's contents into a Drive folder (additive; no remote deletes)"
147
+ },
124
148
  {
125
149
  "name": "gog_drive_copy",
126
150
  "description": "Copy a file to a new file"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-drive",
3
- "version": "2.8.0",
3
+ "version": "2.18.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>",
@@ -19,11 +19,12 @@
19
19
  "build": "tsc --noEmit && npm run bundle",
20
20
  "bundle": "node ../../scripts/bundle.js src/index.ts dist/index.js",
21
21
  "typecheck": "tsc --noEmit",
22
- "test": "vitest run",
22
+ "test": "vitest run --coverage",
23
23
  "test:watch": "vitest",
24
24
  "test:coverage": "vitest run --coverage"
25
25
  },
26
26
  "dependencies": {
27
+ "@chrischall/mcp-utils": "^0.13.3",
27
28
  "@modelcontextprotocol/sdk": "^1.29.0",
28
29
  "zod": "^4.4.3"
29
30
  },
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "source": "github",
8
8
  "subfolder": "packages/gogcli-mcp-drive"
9
9
  },
10
- "version": "2.8.0",
10
+ "version": "2.18.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-drive",
15
- "version": "2.8.0",
15
+ "version": "2.18.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },
package/src/index.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
- import { createServer, registerAuthTools, registerDriveTools } from '../../gogcli-mcp/src/lib.js';
2
+ import { runMcp } from '@chrischall/mcp-utils';
3
+ import { VERSION, authToolsFor, registerDriveTools } from '../../gogcli-mcp/src/lib.js';
4
4
  import { registerExtraDriveTools } from './tools/drive-extra.js';
5
5
 
6
- const server = createServer({ name: 'gogcli-drive' });
7
- registerAuthTools(server);
8
- registerDriveTools(server);
9
- registerExtraDriveTools(server);
10
-
11
- const transport = new StdioServerTransport();
12
- await server.connect(transport);
6
+ await runMcp({
7
+ name: 'gogcli-drive',
8
+ version: VERSION,
9
+ tools: [authToolsFor('drive,driveactivity,drivelabels'), registerDriveTools, registerExtraDriveTools],
10
+ });
@@ -10,12 +10,14 @@ export function registerExtraDriveTools(server: McpServer): void {
10
10
  fileId: z.string().describe('File ID to download'),
11
11
  out: z.string().optional().describe('Output file path (default: gogcli config dir)'),
12
12
  format: z.string().optional().describe('Export format for Google Docs: pdf, csv, xlsx, pptx, txt, png, docx, md (default: inferred)'),
13
+ overwrite: z.boolean().optional().describe('Overwrite the output file if it already exists (gog refuses otherwise)'),
13
14
  account: accountParam,
14
15
  },
15
- }, async ({ fileId, out, format, account }) => {
16
+ }, async ({ fileId, out, format, overwrite, account }) => {
16
17
  const args = ['drive', 'download', fileId];
17
18
  if (out) args.push(`--out=${out}`);
18
19
  if (format) args.push(`--format=${format}`);
20
+ if (overwrite) args.push('--overwrite');
19
21
  return runOrDiagnose(args, { account });
20
22
  });
21
23
 
@@ -45,6 +47,23 @@ export function registerExtraDriveTools(server: McpServer): void {
45
47
  return runOrDiagnose(args, { account });
46
48
  });
47
49
 
50
+ server.registerTool('gog_drive_sync_push', {
51
+ description: 'Recursively push a local directory\'s contents into an existing Drive folder — uploads new files, updates changed ones (matched by name + MD5), and creates missing subfolders. One-way and additive: it never deletes anything on Drive. Use dryRun to preview the planned actions first.',
52
+ annotations: { destructiveHint: true },
53
+ inputSchema: {
54
+ localPath: z.string().describe('Local directory to push (its contents are mirrored into the parent folder)'),
55
+ parent: z.string().describe('Existing destination Drive folder ID'),
56
+ dryRun: z.boolean().optional().describe('Preview the planned actions without making any changes'),
57
+ allDrives: z.boolean().optional().describe('Include shared drives (default: true; set false for My Drive only)'),
58
+ account: accountParam,
59
+ },
60
+ }, async ({ localPath, parent, dryRun, allDrives, account }) => {
61
+ const args = ['drive', 'sync', 'push', localPath, `--parent=${parent}`];
62
+ if (dryRun) args.push('--dry-run');
63
+ if (allDrives === false) args.push('--no-all-drives');
64
+ return runOrDiagnose(args, { account });
65
+ });
66
+
48
67
  server.registerTool('gog_drive_copy', {
49
68
  description: 'Copy a Drive file to a new file with the given name.',
50
69
  inputSchema: {
@@ -95,7 +114,7 @@ export function registerExtraDriveTools(server: McpServer): void {
95
114
  account: accountParam,
96
115
  },
97
116
  }, async ({ fileId, permissionId, account }) => {
98
- return runOrDiagnose(['drive', 'unshare', fileId, permissionId], { account });
117
+ return runOrDiagnose(['drive', 'unshare', fileId, permissionId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
99
118
  });
100
119
 
101
120
  server.registerTool('gog_drive_drives_list', {
@@ -180,7 +199,7 @@ export function registerExtraDriveTools(server: McpServer): void {
180
199
  account: accountParam,
181
200
  },
182
201
  }, async ({ fileId, commentId, account }) => {
183
- return runOrDiagnose(['drive', 'comments', 'delete', fileId, commentId], { account });
202
+ return runOrDiagnose(['drive', 'comments', 'delete', fileId, commentId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
184
203
  });
185
204
 
186
205
  server.registerTool('gog_drive_comments_reply', {
@@ -431,7 +450,7 @@ export function registerExtraDriveTools(server: McpServer): void {
431
450
  account: accountParam,
432
451
  },
433
452
  }, async ({ fileId, labelId, account }) => {
434
- return runOrDiagnose(['drive', 'labels', 'file', 'remove', fileId, labelId], { account });
453
+ return runOrDiagnose(['drive', 'labels', 'file', 'remove', fileId, labelId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
435
454
  });
436
455
 
437
456
  server.registerTool('gog_drive_activity', {