@alanse/mcp-server-google-workspace 0.2.1 → 1.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/README.md +109 -5
- package/dist/auth.js +1 -0
- package/dist/index.js +1 -1
- package/dist/lib/document-id-resolver.js +76 -0
- package/dist/lib/response-formatter.js +82 -0
- package/dist/lib/validation.js +112 -0
- package/dist/tools/docs/basic/gdocs_create.js +37 -0
- package/dist/tools/docs/basic/gdocs_get_metadata.js +45 -0
- package/dist/tools/docs/basic/gdocs_list_documents.js +59 -0
- package/dist/tools/docs/basic/gdocs_read.js +62 -0
- package/dist/tools/docs/content/gdocs_append_text.js +57 -0
- package/dist/tools/docs/content/gdocs_apply_style.js +86 -0
- package/dist/tools/docs/content/gdocs_create_heading.js +89 -0
- package/dist/tools/docs/content/gdocs_create_list.js +86 -0
- package/dist/tools/docs/content/gdocs_delete_text.js +64 -0
- package/dist/tools/docs/content/gdocs_format_text.js +137 -0
- package/dist/tools/docs/content/gdocs_insert_text.js +62 -0
- package/dist/tools/docs/content/gdocs_replace_text.js +64 -0
- package/dist/tools/docs/content/gdocs_set_alignment.js +76 -0
- package/dist/tools/docs/content/gdocs_update_text.js +78 -0
- package/dist/tools/docs/elements/gdocs_batch_update.js +108 -0
- package/dist/tools/docs/elements/gdocs_create_table.js +73 -0
- package/dist/tools/docs/elements/gdocs_export.js +62 -0
- package/dist/tools/docs/elements/gdocs_insert_image.js +96 -0
- package/dist/tools/docs/elements/gdocs_insert_link.js +77 -0
- package/dist/tools/docs/elements/gdocs_insert_page_break.js +55 -0
- package/dist/tools/docs/elements/gdocs_insert_toc.js +71 -0
- package/dist/tools/docs/elements/gdocs_merge_documents.js +104 -0
- package/dist/tools/docs/elements/gdocs_suggest_mode.js +41 -0
- package/dist/tools/index.js +119 -0
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { google } from "googleapis";
|
|
2
|
+
import { ResponseFormatter } from "../../../lib/response-formatter.js";
|
|
3
|
+
import { DocumentIdResolver } from "../../../lib/document-id-resolver.js";
|
|
4
|
+
export const schema = {
|
|
5
|
+
name: "gdocs_merge_documents",
|
|
6
|
+
description: "Merge multiple Google Documents into one. Creates a new document or appends to an existing target document.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
sourceDocumentIds: {
|
|
11
|
+
type: "array",
|
|
12
|
+
description: "Array of source document IDs or URLs to merge (in order)",
|
|
13
|
+
items: {
|
|
14
|
+
type: "string",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
targetDocumentId: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Target document ID or URL to merge into. If not provided, creates a new document.",
|
|
20
|
+
},
|
|
21
|
+
title: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Title for the new merged document (only used if targetDocumentId is not provided)",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: ["sourceDocumentIds"],
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export async function mergeDocuments(args) {
|
|
30
|
+
try {
|
|
31
|
+
if (args.sourceDocumentIds.length === 0) {
|
|
32
|
+
throw new Error("At least one source document is required");
|
|
33
|
+
}
|
|
34
|
+
const docs = google.docs("v1");
|
|
35
|
+
// Resolve source document IDs
|
|
36
|
+
const sourceIds = args.sourceDocumentIds.map((id) => {
|
|
37
|
+
const ref = DocumentIdResolver.resolve(id);
|
|
38
|
+
return ref.id;
|
|
39
|
+
});
|
|
40
|
+
// Determine target document
|
|
41
|
+
let targetDocumentId;
|
|
42
|
+
if (args.targetDocumentId) {
|
|
43
|
+
const targetRef = DocumentIdResolver.resolve(args.targetDocumentId);
|
|
44
|
+
targetDocumentId = targetRef.id;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Create a new document
|
|
48
|
+
const createResponse = await docs.documents.create({
|
|
49
|
+
requestBody: {
|
|
50
|
+
title: args.title || "Merged Document",
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
targetDocumentId = createResponse.data.documentId;
|
|
54
|
+
}
|
|
55
|
+
// Read each source document and append to target
|
|
56
|
+
for (const sourceId of sourceIds) {
|
|
57
|
+
const sourceDoc = await docs.documents.get({ documentId: sourceId });
|
|
58
|
+
// Extract text content from source
|
|
59
|
+
let textContent = "";
|
|
60
|
+
if (sourceDoc.data.body?.content) {
|
|
61
|
+
for (const element of sourceDoc.data.body.content) {
|
|
62
|
+
if (element.paragraph?.elements) {
|
|
63
|
+
for (const textElement of element.paragraph.elements) {
|
|
64
|
+
if (textElement.textRun?.content) {
|
|
65
|
+
textContent += textElement.textRun.content;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Get target document end index
|
|
72
|
+
const targetDoc = await docs.documents.get({ documentId: targetDocumentId });
|
|
73
|
+
const endIndex = targetDoc.data.body?.content?.[targetDoc.data.body.content.length - 1]?.endIndex || 1;
|
|
74
|
+
// Append content to target
|
|
75
|
+
if (textContent) {
|
|
76
|
+
await docs.documents.batchUpdate({
|
|
77
|
+
documentId: targetDocumentId,
|
|
78
|
+
requestBody: {
|
|
79
|
+
requests: [
|
|
80
|
+
{
|
|
81
|
+
insertText: {
|
|
82
|
+
text: "\n" + textContent,
|
|
83
|
+
location: {
|
|
84
|
+
index: endIndex - 1,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const targetUrl = `https://docs.google.com/document/d/${targetDocumentId}/edit`;
|
|
94
|
+
return ResponseFormatter.success({
|
|
95
|
+
targetDocumentId,
|
|
96
|
+
targetDocumentUrl: targetUrl,
|
|
97
|
+
mergedDocuments: sourceIds.length,
|
|
98
|
+
sourceDocumentIds: sourceIds,
|
|
99
|
+
}, `Successfully merged ${sourceIds.length} document(s)`);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
return ResponseFormatter.error(error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { google } from "googleapis";
|
|
2
|
+
import { ResponseFormatter } from "../../../lib/response-formatter.js";
|
|
3
|
+
import { DocumentIdResolver } from "../../../lib/document-id-resolver.js";
|
|
4
|
+
export const schema = {
|
|
5
|
+
name: "gdocs_suggest_mode",
|
|
6
|
+
description: "NOTE: This tool cannot programmatically control suggestion mode. The Google Docs API doesn't support enabling/disabling suggestion mode. To use suggestion mode, open the document in Google Docs UI and use the 'Editing/Suggesting/Viewing' dropdown in the top-right corner.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
documentId: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "Document ID or full Google Docs URL",
|
|
13
|
+
},
|
|
14
|
+
enabled: {
|
|
15
|
+
type: "boolean",
|
|
16
|
+
description: "true to enable suggestion mode, false to disable",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ["documentId", "enabled"],
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export async function suggestMode(args) {
|
|
23
|
+
try {
|
|
24
|
+
// Resolve document ID from URL if needed
|
|
25
|
+
const docRef = DocumentIdResolver.resolve(args.documentId);
|
|
26
|
+
const documentId = docRef.id;
|
|
27
|
+
const docs = google.docs("v1");
|
|
28
|
+
// Verify document exists
|
|
29
|
+
await docs.documents.get({ documentId });
|
|
30
|
+
// Return informative error about API limitation
|
|
31
|
+
return ResponseFormatter.error(new Error(`Suggestion mode cannot be controlled programmatically via the Google Docs API. ` +
|
|
32
|
+
`To ${args.enabled ? "enable" : "disable"} suggestion mode, please:\n\n` +
|
|
33
|
+
`1. Open the document at: https://docs.google.com/document/d/${documentId}/edit\n` +
|
|
34
|
+
`2. Click the 'Editing' dropdown in the top-right corner\n` +
|
|
35
|
+
`3. Select '${args.enabled ? "Suggesting" : "Editing"}'\n\n` +
|
|
36
|
+
`This is a limitation of the Google Docs API, not this tool.`));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return ResponseFormatter.error(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
package/dist/tools/index.js
CHANGED
|
@@ -62,6 +62,32 @@ import { schema as gsheetsUpdateDimensionGroupSchema, updateDimensionGroup } fro
|
|
|
62
62
|
import { schema as gsheetsCreateDeveloperMetadataSchema, createDeveloperMetadata } from './sheets/advanced/gsheets_create_developer_metadata.js';
|
|
63
63
|
import { schema as gsheetsUpdateDeveloperMetadataSchema, updateDeveloperMetadata } from './sheets/advanced/gsheets_update_developer_metadata.js';
|
|
64
64
|
import { schema as gsheetsDeleteDeveloperMetadataSchema, deleteDeveloperMetadata } from './sheets/advanced/gsheets_delete_developer_metadata.js';
|
|
65
|
+
// Google Docs - Basic operations
|
|
66
|
+
import { schema as gdocsCreateSchema, createDocument } from './docs/basic/gdocs_create.js';
|
|
67
|
+
import { schema as gdocsReadSchema, readDocument } from './docs/basic/gdocs_read.js';
|
|
68
|
+
import { schema as gdocsGetMetadataSchema, getMetadata } from './docs/basic/gdocs_get_metadata.js';
|
|
69
|
+
import { schema as gdocsListDocumentsSchema, listDocuments } from './docs/basic/gdocs_list_documents.js';
|
|
70
|
+
// Google Docs - Content/Formatting operations
|
|
71
|
+
import { schema as gdocsInsertTextSchema, insertText } from './docs/content/gdocs_insert_text.js';
|
|
72
|
+
import { schema as gdocsUpdateTextSchema, updateText } from './docs/content/gdocs_update_text.js';
|
|
73
|
+
import { schema as gdocsDeleteTextSchema, deleteText } from './docs/content/gdocs_delete_text.js';
|
|
74
|
+
import { schema as gdocsReplaceTextSchema, replaceText } from './docs/content/gdocs_replace_text.js';
|
|
75
|
+
import { schema as gdocsAppendTextSchema, appendText } from './docs/content/gdocs_append_text.js';
|
|
76
|
+
import { schema as gdocsFormatTextSchema, formatText } from './docs/content/gdocs_format_text.js';
|
|
77
|
+
import { schema as gdocsCreateHeadingSchema, createHeading } from './docs/content/gdocs_create_heading.js';
|
|
78
|
+
import { schema as gdocsCreateListSchema, createList } from './docs/content/gdocs_create_list.js';
|
|
79
|
+
import { schema as gdocsSetAlignmentSchema, setAlignment } from './docs/content/gdocs_set_alignment.js';
|
|
80
|
+
import { schema as gdocsApplyStyleSchema, applyStyle } from './docs/content/gdocs_apply_style.js';
|
|
81
|
+
// Google Docs - Elements/Advanced operations
|
|
82
|
+
import { schema as gdocsInsertImageSchema, insertImage } from './docs/elements/gdocs_insert_image.js';
|
|
83
|
+
import { schema as gdocsCreateTableSchema, createTable } from './docs/elements/gdocs_create_table.js';
|
|
84
|
+
import { schema as gdocsInsertPageBreakSchema, insertPageBreak } from './docs/elements/gdocs_insert_page_break.js';
|
|
85
|
+
import { schema as gdocsInsertLinkSchema, insertLink } from './docs/elements/gdocs_insert_link.js';
|
|
86
|
+
import { schema as gdocsInsertTocSchema, insertToc } from './docs/elements/gdocs_insert_toc.js';
|
|
87
|
+
import { schema as gdocsBatchUpdateSchema, batchUpdate as gdocsBatchUpdate } from './docs/elements/gdocs_batch_update.js';
|
|
88
|
+
import { schema as gdocsMergeDocumentsSchema, mergeDocuments } from './docs/elements/gdocs_merge_documents.js';
|
|
89
|
+
import { schema as gdocsExportSchema, exportDocument } from './docs/elements/gdocs_export.js';
|
|
90
|
+
import { schema as gdocsSuggestModeSchema, suggestMode } from './docs/elements/gdocs_suggest_mode.js';
|
|
65
91
|
export const tools = [
|
|
66
92
|
{
|
|
67
93
|
...driveSearchSchema,
|
|
@@ -290,5 +316,98 @@ export const tools = [
|
|
|
290
316
|
{
|
|
291
317
|
...gsheetsDeleteDeveloperMetadataSchema,
|
|
292
318
|
handler: deleteDeveloperMetadata,
|
|
319
|
+
},
|
|
320
|
+
// Google Docs tools
|
|
321
|
+
{
|
|
322
|
+
...gdocsCreateSchema,
|
|
323
|
+
handler: createDocument,
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
...gdocsReadSchema,
|
|
327
|
+
handler: readDocument,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
...gdocsGetMetadataSchema,
|
|
331
|
+
handler: getMetadata,
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
...gdocsListDocumentsSchema,
|
|
335
|
+
handler: listDocuments,
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
...gdocsInsertTextSchema,
|
|
339
|
+
handler: insertText,
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
...gdocsUpdateTextSchema,
|
|
343
|
+
handler: updateText,
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
...gdocsDeleteTextSchema,
|
|
347
|
+
handler: deleteText,
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
...gdocsReplaceTextSchema,
|
|
351
|
+
handler: replaceText,
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
...gdocsAppendTextSchema,
|
|
355
|
+
handler: appendText,
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
...gdocsFormatTextSchema,
|
|
359
|
+
handler: formatText,
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
...gdocsCreateHeadingSchema,
|
|
363
|
+
handler: createHeading,
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
...gdocsCreateListSchema,
|
|
367
|
+
handler: createList,
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
...gdocsSetAlignmentSchema,
|
|
371
|
+
handler: setAlignment,
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
...gdocsApplyStyleSchema,
|
|
375
|
+
handler: applyStyle,
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
...gdocsInsertImageSchema,
|
|
379
|
+
handler: insertImage,
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
...gdocsCreateTableSchema,
|
|
383
|
+
handler: createTable,
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
...gdocsInsertPageBreakSchema,
|
|
387
|
+
handler: insertPageBreak,
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
...gdocsInsertLinkSchema,
|
|
391
|
+
handler: insertLink,
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
...gdocsInsertTocSchema,
|
|
395
|
+
handler: insertToc,
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
...gdocsBatchUpdateSchema,
|
|
399
|
+
handler: gdocsBatchUpdate,
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
...gdocsMergeDocumentsSchema,
|
|
403
|
+
handler: mergeDocuments,
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
...gdocsExportSchema,
|
|
407
|
+
handler: exportDocument,
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
...gdocsSuggestModeSchema,
|
|
411
|
+
handler: suggestMode,
|
|
293
412
|
}
|
|
294
413
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alanse/mcp-server-google-workspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "The most comprehensive MCP server for Google Workspace - Complete integration for Sheets (57 tools), Drive, and future Docs, Calendar, Forms support",
|
|
5
5
|
"license": "Elastic-2.0",
|
|
6
6
|
"author": "Alanse inc",
|