google-tools-mcp 1.0.9 → 1.0.10
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/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# google-tools-mcp
|
|
2
2
|
|
|
3
|
-
A unified MCP server for Google Workspace — Drive, Docs, Sheets, Gmail, Calendar, and Forms — with **
|
|
3
|
+
A unified MCP server for Google Workspace — Drive, Docs, Sheets, Gmail, Calendar, and Forms — with **153 tools** across 9 categories.
|
|
4
4
|
|
|
5
5
|
All tools are loaded at startup so they're immediately available to your AI agent. No discovery step needed.
|
|
6
6
|
|
|
@@ -10,10 +10,10 @@ Most Google MCP servers split functionality across separate packages. This serve
|
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
|
-
- **
|
|
13
|
+
- **153 tools** across 9 categories, all available immediately
|
|
14
14
|
- **Single auth token** — one OAuth flow covers Drive, Docs, Sheets, Gmail, Calendar, and Forms
|
|
15
15
|
- **Lazy-loading auth** — no browser popup until your first tool call
|
|
16
|
-
- **No lazy tool loading** — all
|
|
16
|
+
- **No lazy tool loading** — all 153 tools are registered eagerly at startup since most MCP clients (including Claude Code) don't support `notifications/tools/list_changed`
|
|
17
17
|
- **Multi-profile support** — separate tokens per Google account
|
|
18
18
|
- **No telemetry**
|
|
19
19
|
|
|
@@ -169,10 +169,10 @@ This stores tokens in `~/.config/google-tools-mcp/work/` instead of the default
|
|
|
169
169
|
|
|
170
170
|
## Tool Categories
|
|
171
171
|
|
|
172
|
-
### `files` (
|
|
172
|
+
### `files` (18 tools)
|
|
173
173
|
Google Drive file management and content reading.
|
|
174
174
|
|
|
175
|
-
`listDriveFiles`, `searchDocuments`, `getFileInfo`, `createFolder`, `listFolderContents`, `getFolderInfo`, `moveFile`, `copyFile`, `renameFile`, `deleteFile`, `createDocument`, `createDocumentFromTemplate`, `listSharedDrives`, `listSharedWithMe`, `downloadFile`, `readFile`, `searchFileContents`
|
|
175
|
+
`listDriveFiles`, `searchDocuments`, `getFileInfo`, `getFilePath`, `createFolder`, `listFolderContents`, `getFolderInfo`, `moveFile`, `copyFile`, `renameFile`, `deleteFile`, `createDocument`, `createDocumentFromTemplate`, `listSharedDrives`, `listSharedWithMe`, `downloadFile`, `readFile`, `searchFileContents`
|
|
176
176
|
|
|
177
177
|
### `documents` (22 tools)
|
|
178
178
|
Google Docs read/write/format with markdown support.
|
|
@@ -7,13 +7,13 @@ import { docsJsonToMarkdown } from '../../markdown-transformer/index.js';
|
|
|
7
7
|
export function register(server) {
|
|
8
8
|
server.addTool({
|
|
9
9
|
name: 'readDocument',
|
|
10
|
-
description: "Reads the content of a Google Document. Returns
|
|
10
|
+
description: "Reads the content of a Google Document. Returns markdown by default (formatted content suitable for editing and re-uploading with replaceDocumentWithMarkdown). Use format='text' for plain text, or format='json' for the raw document structure.",
|
|
11
11
|
parameters: DocumentIdParameter.extend({
|
|
12
12
|
format: z
|
|
13
13
|
.enum(['text', 'json', 'markdown'])
|
|
14
14
|
.optional()
|
|
15
|
-
.default('
|
|
16
|
-
.describe("Output format: 'text' (plain text), 'json' (raw API structure, complex)
|
|
15
|
+
.default('markdown')
|
|
16
|
+
.describe("Output format: 'markdown' (formatted content), 'text' (plain text), 'json' (raw API structure, complex)."),
|
|
17
17
|
maxLength: z
|
|
18
18
|
.number()
|
|
19
19
|
.optional()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getDriveClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'getFilePath',
|
|
8
|
+
description: 'Returns the full folder path of a Drive file from root to the file itself (e.g. "My Drive/Projects/Docs/report.pdf"). Walks up the parent chain to reconstruct the complete path.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
fileId: z.string().describe('The ID of the file or folder to get the path for.'),
|
|
11
|
+
}),
|
|
12
|
+
execute: async (args, { log }) => {
|
|
13
|
+
const drive = await getDriveClient();
|
|
14
|
+
log.info(`Getting full path for file: ${args.fileId}`);
|
|
15
|
+
try {
|
|
16
|
+
const pathParts = [];
|
|
17
|
+
let currentId = args.fileId;
|
|
18
|
+
|
|
19
|
+
while (currentId) {
|
|
20
|
+
const response = await drive.files.get({
|
|
21
|
+
fileId: currentId,
|
|
22
|
+
fields: 'id,name,parents',
|
|
23
|
+
supportsAllDrives: true,
|
|
24
|
+
});
|
|
25
|
+
const file = response.data;
|
|
26
|
+
if (!file) break;
|
|
27
|
+
|
|
28
|
+
pathParts.unshift(file.name);
|
|
29
|
+
|
|
30
|
+
if (file.parents && file.parents.length > 0) {
|
|
31
|
+
currentId = file.parents[0];
|
|
32
|
+
} else {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const fullPath = pathParts.join('/');
|
|
38
|
+
|
|
39
|
+
return JSON.stringify({ fileId: args.fileId, path: fullPath }, null, 2);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
log.error(`Error getting file path: ${error.message || error}`);
|
|
42
|
+
if (error.code === 404)
|
|
43
|
+
throw new UserError(`File not found (ID: ${args.fileId}).`);
|
|
44
|
+
if (error.code === 403)
|
|
45
|
+
throw new UserError('Permission denied. Make sure you have access to this file.');
|
|
46
|
+
throw new UserError(`Failed to get file path: ${error.message || 'Unknown error'}`);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -13,6 +13,7 @@ import { register as createFromTemplate } from './createFromTemplate.js';
|
|
|
13
13
|
import { register as listSharedDrives } from './listSharedDrives.js';
|
|
14
14
|
import { register as listSharedWithMe } from './listSharedWithMe.js';
|
|
15
15
|
import { register as downloadFile } from './downloadFile.js';
|
|
16
|
+
import { register as getFilePath } from './getFilePath.js';
|
|
16
17
|
export function registerDriveTools(server) {
|
|
17
18
|
listDriveFiles(server);
|
|
18
19
|
searchGoogleDocs(server);
|
|
@@ -29,4 +30,5 @@ export function registerDriveTools(server) {
|
|
|
29
30
|
listSharedDrives(server);
|
|
30
31
|
listSharedWithMe(server);
|
|
31
32
|
downloadFile(server);
|
|
33
|
+
getFilePath(server);
|
|
32
34
|
}
|