google-tools-mcp 1.2.5 → 1.2.6
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/dist/auth.js +2 -0
- package/dist/clients.js +17 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/tasks/completeTask.js +43 -0
- package/dist/tools/tasks/createTask.js +53 -0
- package/dist/tools/tasks/createTaskList.js +25 -0
- package/dist/tools/tasks/deleteTask.js +30 -0
- package/dist/tools/tasks/deleteTaskList.js +29 -0
- package/dist/tools/tasks/index.js +19 -0
- package/dist/tools/tasks/listTaskLists.js +26 -0
- package/dist/tools/tasks/listTasks.js +69 -0
- package/dist/tools/tasks/updateTask.js +68 -0
- package/package.json +1 -1
package/dist/auth.js
CHANGED
|
@@ -54,6 +54,8 @@ const SCOPES = [
|
|
|
54
54
|
'https://www.googleapis.com/auth/forms.responses.readonly',
|
|
55
55
|
// Slides
|
|
56
56
|
'https://www.googleapis.com/auth/presentations',
|
|
57
|
+
// Tasks
|
|
58
|
+
'https://www.googleapis.com/auth/tasks',
|
|
57
59
|
];
|
|
58
60
|
|
|
59
61
|
// ---------------------------------------------------------------------------
|
package/dist/clients.js
CHANGED
|
@@ -14,6 +14,7 @@ let gmailClient = null;
|
|
|
14
14
|
let calendarClient = null;
|
|
15
15
|
let formsClient = null;
|
|
16
16
|
let slidesClient = null;
|
|
17
|
+
let tasksClient = null;
|
|
17
18
|
|
|
18
19
|
async function ensureAuth() {
|
|
19
20
|
if (authClient) return;
|
|
@@ -46,6 +47,7 @@ async function reauthorize() {
|
|
|
46
47
|
calendarClient = null;
|
|
47
48
|
formsClient = null;
|
|
48
49
|
slidesClient = null;
|
|
50
|
+
tasksClient = null;
|
|
49
51
|
authClient = await authorize();
|
|
50
52
|
logger.info('Re-authorization successful.');
|
|
51
53
|
}
|
|
@@ -120,6 +122,7 @@ export function resetClients() {
|
|
|
120
122
|
calendarClient = null;
|
|
121
123
|
formsClient = null;
|
|
122
124
|
slidesClient = null;
|
|
125
|
+
tasksClient = null;
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
/**
|
|
@@ -194,3 +197,17 @@ export async function getSlidesClient() {
|
|
|
194
197
|
if (!slides) throw new UserError('Google Slides client is not initialized.');
|
|
195
198
|
return slides;
|
|
196
199
|
}
|
|
200
|
+
|
|
201
|
+
// --- Tasks client ---
|
|
202
|
+
export async function initializeTasksClient() {
|
|
203
|
+
if (tasksClient) return { authClient, tasksClient };
|
|
204
|
+
await ensureAuth();
|
|
205
|
+
if (!tasksClient) tasksClient = google.tasks({ version: 'v1', auth: authClient });
|
|
206
|
+
return { authClient, tasksClient };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export async function getTasksClient() {
|
|
210
|
+
const { tasksClient: tasks } = await initializeTasksClient();
|
|
211
|
+
if (!tasks) throw new UserError('Google Tasks client is not initialized.');
|
|
212
|
+
return tasks;
|
|
213
|
+
}
|
package/dist/tools/index.js
CHANGED
|
@@ -178,6 +178,12 @@ const CATEGORIES = {
|
|
|
178
178
|
registerSlidesTools(server);
|
|
179
179
|
},
|
|
180
180
|
},
|
|
181
|
+
tasks: {
|
|
182
|
+
async loader(server) {
|
|
183
|
+
const { registerTasksTools } = await import('./tasks/index.js');
|
|
184
|
+
registerTasksTools(server);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
181
187
|
};
|
|
182
188
|
|
|
183
189
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'completeTask',
|
|
8
|
+
description: 'Marks a task as completed.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
taskListId: z.string().describe('ID of the task list containing the task'),
|
|
11
|
+
taskId: z.string().describe('ID of the task to complete'),
|
|
12
|
+
}),
|
|
13
|
+
execute: async (args, { log }) => {
|
|
14
|
+
const tasks = await getTasksClient();
|
|
15
|
+
log.info(`Completing task ${args.taskId} in list: ${args.taskListId}`);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const response = await tasks.tasks.patch({
|
|
19
|
+
tasklist: args.taskListId,
|
|
20
|
+
task: args.taskId,
|
|
21
|
+
requestBody: { status: 'completed', completed: new Date().toISOString() },
|
|
22
|
+
});
|
|
23
|
+
const t = response.data;
|
|
24
|
+
return JSON.stringify({
|
|
25
|
+
id: t.id,
|
|
26
|
+
taskListId: args.taskListId,
|
|
27
|
+
title: t.title || '',
|
|
28
|
+
notes: t.notes || null,
|
|
29
|
+
status: t.status,
|
|
30
|
+
due: t.due || null,
|
|
31
|
+
completed: t.completed || null,
|
|
32
|
+
}, null, 2);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
log.error(`Error completing task: ${error.message || error}`);
|
|
35
|
+
if (error.code === 404)
|
|
36
|
+
throw new UserError(`Task not found (taskId: ${args.taskId}, listId: ${args.taskListId}).`);
|
|
37
|
+
if (error.code === 403)
|
|
38
|
+
throw new UserError('Permission denied. Make sure you have access to this task.');
|
|
39
|
+
throw new UserError(`Failed to complete task: ${error.message || 'Unknown error'}`);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'createTask',
|
|
8
|
+
description: 'Creates a new task in a Google Tasks task list.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
taskListId: z.string().describe('ID of the task list to add the task to'),
|
|
11
|
+
title: z.string().describe('Title of the task'),
|
|
12
|
+
notes: z.string().optional().describe('Optional notes or description for the task'),
|
|
13
|
+
due: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Optional due date in RFC 3339 or plain date format (e.g. "2025-04-30")'),
|
|
17
|
+
}),
|
|
18
|
+
execute: async (args, { log }) => {
|
|
19
|
+
const tasks = await getTasksClient();
|
|
20
|
+
log.info(`Creating task "${args.title}" in list: ${args.taskListId}`);
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const body = { title: args.title };
|
|
24
|
+
if (args.notes) body.notes = args.notes;
|
|
25
|
+
if (args.due) body.due = normalizeDate(args.due);
|
|
26
|
+
|
|
27
|
+
const response = await tasks.tasks.insert({ tasklist: args.taskListId, requestBody: body });
|
|
28
|
+
const t = response.data;
|
|
29
|
+
return JSON.stringify({
|
|
30
|
+
id: t.id,
|
|
31
|
+
taskListId: args.taskListId,
|
|
32
|
+
title: t.title || '',
|
|
33
|
+
notes: t.notes || null,
|
|
34
|
+
status: t.status,
|
|
35
|
+
due: t.due || null,
|
|
36
|
+
completed: t.completed || null,
|
|
37
|
+
}, null, 2);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
log.error(`Error creating task: ${error.message || error}`);
|
|
40
|
+
if (error.code === 404)
|
|
41
|
+
throw new UserError(`Task list not found (ID: ${args.taskListId}).`);
|
|
42
|
+
if (error.code === 403)
|
|
43
|
+
throw new UserError('Permission denied. Make sure you have access to this task list.');
|
|
44
|
+
throw new UserError(`Failed to create task: ${error.message || 'Unknown error'}`);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function normalizeDate(value) {
|
|
51
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'createTaskList',
|
|
8
|
+
description: 'Creates a new Google Tasks task list with the given title.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
title: z.string().describe('Title for the new task list'),
|
|
11
|
+
}),
|
|
12
|
+
execute: async (args, { log }) => {
|
|
13
|
+
const tasks = await getTasksClient();
|
|
14
|
+
log.info(`Creating task list: ${args.title}`);
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const response = await tasks.tasklists.insert({ requestBody: { title: args.title } });
|
|
18
|
+
return JSON.stringify({ id: response.data.id, title: response.data.title }, null, 2);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
log.error(`Error creating task list: ${error.message || error}`);
|
|
21
|
+
throw new UserError(`Failed to create task list: ${error.message || 'Unknown error'}`);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'deleteTask',
|
|
8
|
+
description: 'Permanently deletes a task.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
taskListId: z.string().describe('ID of the task list containing the task'),
|
|
11
|
+
taskId: z.string().describe('ID of the task to delete'),
|
|
12
|
+
}),
|
|
13
|
+
execute: async (args, { log }) => {
|
|
14
|
+
const tasks = await getTasksClient();
|
|
15
|
+
log.info(`Deleting task ${args.taskId} from list: ${args.taskListId}`);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
await tasks.tasks.delete({ tasklist: args.taskListId, task: args.taskId });
|
|
19
|
+
return JSON.stringify({ deleted: true, taskId: args.taskId, taskListId: args.taskListId }, null, 2);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
log.error(`Error deleting task: ${error.message || error}`);
|
|
22
|
+
if (error.code === 404)
|
|
23
|
+
throw new UserError(`Task not found (taskId: ${args.taskId}, listId: ${args.taskListId}).`);
|
|
24
|
+
if (error.code === 403)
|
|
25
|
+
throw new UserError('Permission denied. Make sure you have access to this task.');
|
|
26
|
+
throw new UserError(`Failed to delete task: ${error.message || 'Unknown error'}`);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'deleteTaskList',
|
|
8
|
+
description: 'Permanently deletes a task list and all tasks within it.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
taskListId: z.string().describe('ID of the task list to delete'),
|
|
11
|
+
}),
|
|
12
|
+
execute: async (args, { log }) => {
|
|
13
|
+
const tasks = await getTasksClient();
|
|
14
|
+
log.info(`Deleting task list: ${args.taskListId}`);
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
await tasks.tasklists.delete({ tasklist: args.taskListId });
|
|
18
|
+
return JSON.stringify({ deleted: true, taskListId: args.taskListId }, null, 2);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
log.error(`Error deleting task list: ${error.message || error}`);
|
|
21
|
+
if (error.code === 404)
|
|
22
|
+
throw new UserError(`Task list not found (ID: ${args.taskListId}).`);
|
|
23
|
+
if (error.code === 403)
|
|
24
|
+
throw new UserError('Permission denied. You can only delete task lists you own.');
|
|
25
|
+
throw new UserError(`Failed to delete task list: ${error.message || 'Unknown error'}`);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { register as listTaskLists } from './listTaskLists.js';
|
|
2
|
+
import { register as createTaskList } from './createTaskList.js';
|
|
3
|
+
import { register as deleteTaskList } from './deleteTaskList.js';
|
|
4
|
+
import { register as listTasks } from './listTasks.js';
|
|
5
|
+
import { register as createTask } from './createTask.js';
|
|
6
|
+
import { register as updateTask } from './updateTask.js';
|
|
7
|
+
import { register as completeTask } from './completeTask.js';
|
|
8
|
+
import { register as deleteTask } from './deleteTask.js';
|
|
9
|
+
|
|
10
|
+
export function registerTasksTools(server) {
|
|
11
|
+
listTaskLists(server);
|
|
12
|
+
createTaskList(server);
|
|
13
|
+
deleteTaskList(server);
|
|
14
|
+
listTasks(server);
|
|
15
|
+
createTask(server);
|
|
16
|
+
updateTask(server);
|
|
17
|
+
completeTask(server);
|
|
18
|
+
deleteTask(server);
|
|
19
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'listTaskLists',
|
|
8
|
+
description: 'Lists all Google Task lists for the authenticated user. Returns the id and title of each list.',
|
|
9
|
+
parameters: z.object({}),
|
|
10
|
+
execute: async (_args, { log }) => {
|
|
11
|
+
const tasks = await getTasksClient();
|
|
12
|
+
log.info('Listing task lists');
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
const response = await tasks.tasklists.list();
|
|
16
|
+
const lists = response.data.items || [];
|
|
17
|
+
return JSON.stringify(lists.map((l) => ({ id: l.id, title: l.title })), null, 2);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
log.error(`Error listing task lists: ${error.message || error}`);
|
|
20
|
+
if (error.code === 401)
|
|
21
|
+
throw new UserError('Authentication failed. Try logging out and re-authenticating.');
|
|
22
|
+
throw new UserError(`Failed to list task lists: ${error.message || 'Unknown error'}`);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'listTasks',
|
|
8
|
+
description:
|
|
9
|
+
'Lists tasks in a Google Tasks task list. Optionally filter by completion status or due date range.',
|
|
10
|
+
parameters: z.object({
|
|
11
|
+
taskListId: z.string().describe('ID of the task list to read from'),
|
|
12
|
+
showCompleted: z
|
|
13
|
+
.boolean()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe('Whether to include completed tasks (default: true)'),
|
|
16
|
+
dueMin: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Lower bound for due date filter, RFC 3339 or plain date (e.g. "2025-04-01")'),
|
|
20
|
+
dueMax: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('Upper bound for due date filter, RFC 3339 or plain date (e.g. "2025-04-30")'),
|
|
24
|
+
}),
|
|
25
|
+
execute: async (args, { log }) => {
|
|
26
|
+
const tasks = await getTasksClient();
|
|
27
|
+
const showCompleted = args.showCompleted ?? true;
|
|
28
|
+
log.info(`Listing tasks in list: ${args.taskListId}`);
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const params = {
|
|
32
|
+
tasklist: args.taskListId,
|
|
33
|
+
showCompleted,
|
|
34
|
+
showHidden: showCompleted,
|
|
35
|
+
};
|
|
36
|
+
if (args.dueMin) params.dueMin = normalizeDate(args.dueMin);
|
|
37
|
+
if (args.dueMax) params.dueMax = normalizeDate(args.dueMax);
|
|
38
|
+
|
|
39
|
+
const response = await tasks.tasks.list(params);
|
|
40
|
+
const items = response.data.items || [];
|
|
41
|
+
return JSON.stringify(items.map((t) => formatTask(t, args.taskListId)), null, 2);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
log.error(`Error listing tasks: ${error.message || error}`);
|
|
44
|
+
if (error.code === 404)
|
|
45
|
+
throw new UserError(`Task list not found (ID: ${args.taskListId}).`);
|
|
46
|
+
if (error.code === 403)
|
|
47
|
+
throw new UserError('Permission denied. Make sure you have access to this task list.');
|
|
48
|
+
throw new UserError(`Failed to list tasks: ${error.message || 'Unknown error'}`);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function formatTask(t, taskListId) {
|
|
55
|
+
return {
|
|
56
|
+
id: t.id,
|
|
57
|
+
taskListId,
|
|
58
|
+
title: t.title || '',
|
|
59
|
+
notes: t.notes || null,
|
|
60
|
+
status: t.status,
|
|
61
|
+
due: t.due || null,
|
|
62
|
+
completed: t.completed || null,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function normalizeDate(value) {
|
|
67
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTasksClient } from '../../clients.js';
|
|
4
|
+
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'updateTask',
|
|
8
|
+
description:
|
|
9
|
+
'Updates fields on an existing task. Only provided fields are changed; omitted fields are left as-is.',
|
|
10
|
+
parameters: z.object({
|
|
11
|
+
taskListId: z.string().describe('ID of the task list containing the task'),
|
|
12
|
+
taskId: z.string().describe('ID of the task to update'),
|
|
13
|
+
title: z.string().optional().describe('New title for the task'),
|
|
14
|
+
notes: z.string().optional().describe('New notes for the task'),
|
|
15
|
+
due: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('New due date in RFC 3339 or plain date format (e.g. "2025-04-30")'),
|
|
19
|
+
status: z
|
|
20
|
+
.enum(['needsAction', 'completed'])
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('New status for the task'),
|
|
23
|
+
}),
|
|
24
|
+
execute: async (args, { log }) => {
|
|
25
|
+
const tasks = await getTasksClient();
|
|
26
|
+
log.info(`Updating task ${args.taskId} in list: ${args.taskListId}`);
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const body = {};
|
|
30
|
+
if (args.title !== undefined) body.title = args.title;
|
|
31
|
+
if (args.notes !== undefined) body.notes = args.notes;
|
|
32
|
+
if (args.due !== undefined) body.due = normalizeDate(args.due);
|
|
33
|
+
if (args.status !== undefined) {
|
|
34
|
+
body.status = args.status;
|
|
35
|
+
if (args.status === 'completed') body.completed = new Date().toISOString();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const response = await tasks.tasks.patch({
|
|
39
|
+
tasklist: args.taskListId,
|
|
40
|
+
task: args.taskId,
|
|
41
|
+
requestBody: body,
|
|
42
|
+
});
|
|
43
|
+
const t = response.data;
|
|
44
|
+
return JSON.stringify({
|
|
45
|
+
id: t.id,
|
|
46
|
+
taskListId: args.taskListId,
|
|
47
|
+
title: t.title || '',
|
|
48
|
+
notes: t.notes || null,
|
|
49
|
+
status: t.status,
|
|
50
|
+
due: t.due || null,
|
|
51
|
+
completed: t.completed || null,
|
|
52
|
+
}, null, 2);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
log.error(`Error updating task: ${error.message || error}`);
|
|
55
|
+
if (error.code === 404)
|
|
56
|
+
throw new UserError(`Task not found (taskId: ${args.taskId}, listId: ${args.taskListId}).`);
|
|
57
|
+
if (error.code === 403)
|
|
58
|
+
throw new UserError('Permission denied. Make sure you have access to this task.');
|
|
59
|
+
throw new UserError(`Failed to update task: ${error.message || 'Unknown error'}`);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function normalizeDate(value) {
|
|
66
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
|
|
67
|
+
return value;
|
|
68
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "google-tools-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "The easiest MCP server for Google Workspace — Drive, Docs, Sheets, Gmail, Calendar, and Forms. 153 tools with one-click browser auth. Read Word docs, PDFs, and spreadsheets straight from Drive.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|