google-tools-mcp 1.2.11 → 2.0.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/LICENSE +21 -21
- package/README.md +555 -276
- package/dist/cachedToolsList.js +52 -52
- package/dist/googleDocsApiHelpers.js +76 -12
- package/dist/helpers.js +572 -252
- package/dist/httpAuth.js +296 -0
- package/dist/index.js +162 -11
- package/dist/logger.js +87 -87
- package/dist/markdown-transformer/docsToMarkdown.js +222 -21
- package/dist/markdown-transformer/index.js +19 -9
- package/dist/markdown-transformer/markdownToDocs.js +458 -28
- package/dist/readTracker.js +136 -17
- package/dist/sessionContext.js +37 -0
- package/dist/setup.js +187 -9
- package/dist/tools/calendar/getBusy.js +64 -64
- package/dist/tools/calendar/getEvents.js +141 -141
- package/dist/tools/calendar/getFree.js +225 -225
- package/dist/tools/calendar/index.js +19 -19
- package/dist/tools/calendar/listCalendars.js +38 -38
- package/dist/tools/calendar/listRecurringInstances.js +83 -83
- package/dist/tools/calendar/manageCalendar.js +121 -121
- package/dist/tools/calendar/manageEvent.js +258 -258
- package/dist/tools/calendar/moveEvent.js +66 -66
- package/dist/tools/docs/addTab.js +10 -12
- package/dist/tools/docs/appendToGoogleDoc.js +9 -4
- package/dist/tools/docs/deleteRange.js +9 -4
- package/dist/tools/docs/findAndReplace.js +9 -4
- package/dist/tools/docs/formatting/applyParagraphStyle.js +4 -1
- package/dist/tools/docs/formatting/getFormatting.js +171 -171
- package/dist/tools/docs/insertImage.js +15 -2
- package/dist/tools/docs/insertPageBreak.js +4 -1
- package/dist/tools/docs/insertTable.js +4 -1
- package/dist/tools/docs/insertTableWithData.js +4 -1
- package/dist/tools/docs/modifyText.js +14 -4
- package/dist/tools/docs/modifyText.test.js +84 -84
- package/dist/tools/docs/readGoogleDoc.js +71 -11
- package/dist/tools/docs/renameTab.js +12 -14
- package/dist/tools/drafts.js +165 -165
- package/dist/tools/drive/createDocument.js +13 -1
- package/dist/tools/drive/downloadFile.js +268 -268
- package/dist/tools/drive/getFileInfo.js +48 -48
- package/dist/tools/drive/getFilePath.js +50 -50
- package/dist/tools/drive/listDriveFiles.js +112 -112
- package/dist/tools/drive/listSharedDrives.js +52 -52
- package/dist/tools/drive/listSharedWithMe.js +97 -97
- package/dist/tools/drive/uploadFile.js +111 -111
- package/dist/tools/extras/index.js +9 -9
- package/dist/tools/extras/readDriveFile.js +212 -206
- package/dist/tools/extras/readFile.js +84 -84
- package/dist/tools/extras/searchFileContents.js +81 -81
- package/dist/tools/forms/batchUpdateForm.js +81 -81
- package/dist/tools/forms/createForm.js +54 -54
- package/dist/tools/forms/getForm.js +118 -118
- package/dist/tools/forms/getFormResponse.js +45 -45
- package/dist/tools/forms/index.js +15 -15
- package/dist/tools/forms/listFormResponses.js +56 -56
- package/dist/tools/forms/setPublishSettings.js +59 -59
- package/dist/tools/gmail/drafts.js +165 -165
- package/dist/tools/gmail/labels.js +54 -83
- package/dist/tools/gmail/messages.js +444 -441
- package/dist/tools/gmail/settings.js +358 -528
- package/dist/tools/gmail/threads.js +286 -164
- package/dist/tools/index.js +511 -473
- package/dist/tools/labels.js +103 -103
- package/dist/tools/legacyAliases.js +426 -0
- package/dist/tools/maps/directions.js +72 -0
- package/dist/tools/maps/geocode.js +16 -0
- package/dist/tools/maps/index.js +15 -0
- package/dist/tools/maps/mapsClient.js +83 -0
- package/dist/tools/maps/placeDetails.js +16 -0
- package/dist/tools/maps/reverseGeocode.js +19 -0
- package/dist/tools/maps/searchNearby.js +54 -0
- package/dist/tools/maps/searchPlaces.js +24 -0
- package/dist/tools/messages.js +448 -448
- package/dist/tools/settings.js +528 -528
- package/dist/tools/slides/createPresentation.js +104 -104
- package/dist/tools/slides/createShape.js +92 -92
- package/dist/tools/slides/createTextBox.js +82 -82
- package/dist/tools/slides/deleteSlide.js +30 -30
- package/dist/tools/slides/duplicateSlide.js +37 -37
- package/dist/tools/slides/exportThumbnail.js +42 -42
- package/dist/tools/slides/formatParagraph.js +72 -72
- package/dist/tools/slides/formatText.js +84 -84
- package/dist/tools/slides/getPresentation.js +87 -87
- package/dist/tools/slides/index.js +33 -33
- package/dist/tools/slides/reorderSlides.js +41 -41
- package/dist/tools/slides/replaceAllText.js +46 -46
- package/dist/tools/slides/setBackground.js +58 -58
- package/dist/tools/slides/speakerNotes.js +102 -102
- package/dist/tools/slides/styleShape.js +111 -111
- package/dist/tools/slides/updatePresentation.js +128 -128
- package/dist/tools/threads.js +145 -145
- package/dist/tools/utils/appendMarkdownToGoogleDoc.js +31 -7
- package/dist/tools/utils/replaceDocumentWithMarkdown.js +72 -9
- package/dist/updateCheck.js +202 -0
- package/dist/workspace.js +122 -0
- package/package.json +82 -80
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { UserError } from 'fastmcp';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
import { getDriveClient } from '../../clients.js';
|
|
6
|
-
|
|
7
|
-
// Common MIME type mappings for file extensions
|
|
8
|
-
const MIME_TYPES = {
|
|
9
|
-
'.pdf': 'application/pdf',
|
|
10
|
-
'.doc': 'application/msword',
|
|
11
|
-
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
12
|
-
'.xls': 'application/vnd.ms-excel',
|
|
13
|
-
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
14
|
-
'.ppt': 'application/vnd.ms-powerpoint',
|
|
15
|
-
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
16
|
-
'.txt': 'text/plain',
|
|
17
|
-
'.csv': 'text/csv',
|
|
18
|
-
'.json': 'application/json',
|
|
19
|
-
'.xml': 'application/xml',
|
|
20
|
-
'.html': 'text/html',
|
|
21
|
-
'.htm': 'text/html',
|
|
22
|
-
'.md': 'text/markdown',
|
|
23
|
-
'.png': 'image/png',
|
|
24
|
-
'.jpg': 'image/jpeg',
|
|
25
|
-
'.jpeg': 'image/jpeg',
|
|
26
|
-
'.gif': 'image/gif',
|
|
27
|
-
'.svg': 'image/svg+xml',
|
|
28
|
-
'.webp': 'image/webp',
|
|
29
|
-
'.mp3': 'audio/mpeg',
|
|
30
|
-
'.mp4': 'video/mp4',
|
|
31
|
-
'.zip': 'application/zip',
|
|
32
|
-
'.gz': 'application/gzip',
|
|
33
|
-
'.tar': 'application/x-tar',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export function register(server) {
|
|
37
|
-
server.addTool({
|
|
38
|
-
name: 'uploadFile',
|
|
39
|
-
description:
|
|
40
|
-
'Uploads a local file from the filesystem to Google Drive. ' +
|
|
41
|
-
'Auto-detects MIME type from file extension. ' +
|
|
42
|
-
'Returns the uploaded file\'s Drive ID and URL.',
|
|
43
|
-
parameters: z.object({
|
|
44
|
-
localPath: z.string().describe('Absolute path to the local file to upload.'),
|
|
45
|
-
name: z
|
|
46
|
-
.string()
|
|
47
|
-
.optional()
|
|
48
|
-
.describe('Custom name for the file in Drive. If not provided, uses the local filename.'),
|
|
49
|
-
parentFolderId: z
|
|
50
|
-
.string()
|
|
51
|
-
.optional()
|
|
52
|
-
.describe('ID of the Drive folder to upload into. If not provided, uploads to the root of My Drive.'),
|
|
53
|
-
mimeType: z
|
|
54
|
-
.string()
|
|
55
|
-
.optional()
|
|
56
|
-
.describe('MIME type override. If not provided, auto-detected from file extension.'),
|
|
57
|
-
}),
|
|
58
|
-
execute: async (args, { log }) => {
|
|
59
|
-
const drive = await getDriveClient();
|
|
60
|
-
|
|
61
|
-
// Validate file exists
|
|
62
|
-
if (!fs.existsSync(args.localPath)) {
|
|
63
|
-
throw new UserError(`File not found: ${args.localPath}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const stats = fs.statSync(args.localPath);
|
|
67
|
-
if (!stats.isFile()) {
|
|
68
|
-
throw new UserError(`Path is not a file: ${args.localPath}`);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const fileName = args.name || path.basename(args.localPath);
|
|
72
|
-
const ext = path.extname(args.localPath).toLowerCase();
|
|
73
|
-
const mimeType = args.mimeType || MIME_TYPES[ext] || 'application/octet-stream';
|
|
74
|
-
|
|
75
|
-
log.info(`Uploading "${args.localPath}" as "${fileName}" (${mimeType}, ${stats.size} bytes)`);
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
const fileMetadata = { name: fileName };
|
|
79
|
-
if (args.parentFolderId) {
|
|
80
|
-
fileMetadata.parents = [args.parentFolderId];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const response = await drive.files.create({
|
|
84
|
-
requestBody: fileMetadata,
|
|
85
|
-
media: {
|
|
86
|
-
mimeType,
|
|
87
|
-
body: fs.createReadStream(args.localPath),
|
|
88
|
-
},
|
|
89
|
-
fields: 'id,name,webViewLink,mimeType,size',
|
|
90
|
-
supportsAllDrives: true,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const file = response.data;
|
|
94
|
-
return JSON.stringify({
|
|
95
|
-
id: file.id,
|
|
96
|
-
name: file.name,
|
|
97
|
-
url: file.webViewLink,
|
|
98
|
-
mimeType: file.mimeType,
|
|
99
|
-
size: file.size,
|
|
100
|
-
}, null, 2);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
log.error(`Error uploading file: ${error.message || error}`);
|
|
103
|
-
if (error.code === 404)
|
|
104
|
-
throw new UserError('Destination folder not found. Check the parentFolderId.');
|
|
105
|
-
if (error.code === 403)
|
|
106
|
-
throw new UserError('Permission denied. Make sure you have write access to the destination folder.');
|
|
107
|
-
throw new UserError(`Failed to upload file: ${error.message || 'Unknown error'}`);
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
}
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { UserError } from 'fastmcp';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { getDriveClient } from '../../clients.js';
|
|
6
|
+
|
|
7
|
+
// Common MIME type mappings for file extensions
|
|
8
|
+
const MIME_TYPES = {
|
|
9
|
+
'.pdf': 'application/pdf',
|
|
10
|
+
'.doc': 'application/msword',
|
|
11
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
12
|
+
'.xls': 'application/vnd.ms-excel',
|
|
13
|
+
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
14
|
+
'.ppt': 'application/vnd.ms-powerpoint',
|
|
15
|
+
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
16
|
+
'.txt': 'text/plain',
|
|
17
|
+
'.csv': 'text/csv',
|
|
18
|
+
'.json': 'application/json',
|
|
19
|
+
'.xml': 'application/xml',
|
|
20
|
+
'.html': 'text/html',
|
|
21
|
+
'.htm': 'text/html',
|
|
22
|
+
'.md': 'text/markdown',
|
|
23
|
+
'.png': 'image/png',
|
|
24
|
+
'.jpg': 'image/jpeg',
|
|
25
|
+
'.jpeg': 'image/jpeg',
|
|
26
|
+
'.gif': 'image/gif',
|
|
27
|
+
'.svg': 'image/svg+xml',
|
|
28
|
+
'.webp': 'image/webp',
|
|
29
|
+
'.mp3': 'audio/mpeg',
|
|
30
|
+
'.mp4': 'video/mp4',
|
|
31
|
+
'.zip': 'application/zip',
|
|
32
|
+
'.gz': 'application/gzip',
|
|
33
|
+
'.tar': 'application/x-tar',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export function register(server) {
|
|
37
|
+
server.addTool({
|
|
38
|
+
name: 'uploadFile',
|
|
39
|
+
description:
|
|
40
|
+
'Uploads a local file from the filesystem to Google Drive. ' +
|
|
41
|
+
'Auto-detects MIME type from file extension. ' +
|
|
42
|
+
'Returns the uploaded file\'s Drive ID and URL.',
|
|
43
|
+
parameters: z.object({
|
|
44
|
+
localPath: z.string().describe('Absolute path to the local file to upload.'),
|
|
45
|
+
name: z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe('Custom name for the file in Drive. If not provided, uses the local filename.'),
|
|
49
|
+
parentFolderId: z
|
|
50
|
+
.string()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe('ID of the Drive folder to upload into. If not provided, uploads to the root of My Drive.'),
|
|
53
|
+
mimeType: z
|
|
54
|
+
.string()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('MIME type override. If not provided, auto-detected from file extension.'),
|
|
57
|
+
}),
|
|
58
|
+
execute: async (args, { log }) => {
|
|
59
|
+
const drive = await getDriveClient();
|
|
60
|
+
|
|
61
|
+
// Validate file exists
|
|
62
|
+
if (!fs.existsSync(args.localPath)) {
|
|
63
|
+
throw new UserError(`File not found: ${args.localPath}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const stats = fs.statSync(args.localPath);
|
|
67
|
+
if (!stats.isFile()) {
|
|
68
|
+
throw new UserError(`Path is not a file: ${args.localPath}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const fileName = args.name || path.basename(args.localPath);
|
|
72
|
+
const ext = path.extname(args.localPath).toLowerCase();
|
|
73
|
+
const mimeType = args.mimeType || MIME_TYPES[ext] || 'application/octet-stream';
|
|
74
|
+
|
|
75
|
+
log.info(`Uploading "${args.localPath}" as "${fileName}" (${mimeType}, ${stats.size} bytes)`);
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const fileMetadata = { name: fileName };
|
|
79
|
+
if (args.parentFolderId) {
|
|
80
|
+
fileMetadata.parents = [args.parentFolderId];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const response = await drive.files.create({
|
|
84
|
+
requestBody: fileMetadata,
|
|
85
|
+
media: {
|
|
86
|
+
mimeType,
|
|
87
|
+
body: fs.createReadStream(args.localPath),
|
|
88
|
+
},
|
|
89
|
+
fields: 'id,name,webViewLink,mimeType,size',
|
|
90
|
+
supportsAllDrives: true,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const file = response.data;
|
|
94
|
+
return JSON.stringify({
|
|
95
|
+
id: file.id,
|
|
96
|
+
name: file.name,
|
|
97
|
+
url: file.webViewLink,
|
|
98
|
+
mimeType: file.mimeType,
|
|
99
|
+
size: file.size,
|
|
100
|
+
}, null, 2);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
log.error(`Error uploading file: ${error.message || error}`);
|
|
103
|
+
if (error.code === 404)
|
|
104
|
+
throw new UserError('Destination folder not found. Check the parentFolderId.');
|
|
105
|
+
if (error.code === 403)
|
|
106
|
+
throw new UserError('Permission denied. Make sure you have write access to the destination folder.');
|
|
107
|
+
throw new UserError(`Failed to upload file: ${error.message || 'Unknown error'}`);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { register as readFile } from './readFile.js';
|
|
2
|
-
import { register as searchFileContents } from './searchFileContents.js';
|
|
3
|
-
import { register as readDriveFile } from './readDriveFile.js';
|
|
4
|
-
|
|
5
|
-
export function registerExtrasTools(server) {
|
|
6
|
-
readFile(server);
|
|
7
|
-
searchFileContents(server);
|
|
8
|
-
readDriveFile(server);
|
|
9
|
-
}
|
|
1
|
+
import { register as readFile } from './readFile.js';
|
|
2
|
+
import { register as searchFileContents } from './searchFileContents.js';
|
|
3
|
+
import { register as readDriveFile } from './readDriveFile.js';
|
|
4
|
+
|
|
5
|
+
export function registerExtrasTools(server) {
|
|
6
|
+
readFile(server);
|
|
7
|
+
searchFileContents(server);
|
|
8
|
+
readDriveFile(server);
|
|
9
|
+
}
|