bn-google-workspace-mcp-server 0.0.1
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 +718 -0
- package/dist/debug-middleware.d.ts +12 -0
- package/dist/debug-middleware.d.ts.map +1 -0
- package/dist/debug-middleware.js +36 -0
- package/dist/debug-middleware.js.map +1 -0
- package/dist/google-api-client.d.ts +46 -0
- package/dist/google-api-client.d.ts.map +1 -0
- package/dist/google-api-client.js +76 -0
- package/dist/google-api-client.js.map +1 -0
- package/dist/helpers.d.ts +40 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +171 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas.d.ts +303 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +611 -0
- package/dist/schemas.js.map +1 -0
- package/dist/tool-loader.d.ts +35 -0
- package/dist/tool-loader.d.ts.map +1 -0
- package/dist/tool-loader.js +121 -0
- package/dist/tool-loader.js.map +1 -0
- package/dist/tool-registry.d.ts +44 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +56 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/calendar.d.ts +44 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +76 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/chat.d.ts +29 -0
- package/dist/tools/chat.d.ts.map +1 -0
- package/dist/tools/chat.js +42 -0
- package/dist/tools/chat.js.map +1 -0
- package/dist/tools/docs.d.ts +29 -0
- package/dist/tools/docs.d.ts.map +1 -0
- package/dist/tools/docs.js +63 -0
- package/dist/tools/docs.js.map +1 -0
- package/dist/tools/drive.d.ts +45 -0
- package/dist/tools/drive.d.ts.map +1 -0
- package/dist/tools/drive.js +135 -0
- package/dist/tools/drive.js.map +1 -0
- package/dist/tools/forms.d.ts +30 -0
- package/dist/tools/forms.d.ts.map +1 -0
- package/dist/tools/forms.js +46 -0
- package/dist/tools/forms.js.map +1 -0
- package/dist/tools/gmail.d.ts +55 -0
- package/dist/tools/gmail.d.ts.map +1 -0
- package/dist/tools/gmail.js +112 -0
- package/dist/tools/gmail.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +22 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/sheets.d.ts +40 -0
- package/dist/tools/sheets.d.ts.map +1 -0
- package/dist/tools/sheets.js +64 -0
- package/dist/tools/sheets.js.map +1 -0
- package/dist/tools/slides.d.ts +32 -0
- package/dist/tools/slides.d.ts.map +1 -0
- package/dist/tools/slides.js +46 -0
- package/dist/tools/slides.js.map +1 -0
- package/dist/tools/tasks.d.ts +43 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +69 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
- package/tools.json +379 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ToolResponse } from "./types.js";
|
|
2
|
+
export declare const DEBUG_MODE: boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Wraps a tool execution with debug metadata when DEBUG mode is enabled.
|
|
5
|
+
*
|
|
6
|
+
* @param toolName - Name of the tool being executed
|
|
7
|
+
* @param toolInput - Input arguments passed to the tool
|
|
8
|
+
* @param executeToolFn - Async function that executes the tool and returns data
|
|
9
|
+
* @returns ToolResponse with data and optional debug metadata
|
|
10
|
+
*/
|
|
11
|
+
export declare function wrapWithDebug<T>(toolName: string, toolInput: unknown, executeToolFn: () => Promise<T>): Promise<ToolResponse<T>>;
|
|
12
|
+
//# sourceMappingURL=debug-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-middleware.d.ts","sourceRoot":"","sources":["../src/debug-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,YAAY,CAAC;AAG9D,eAAO,MAAM,UAAU,SAA+B,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA0B1B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Check if DEBUG mode is enabled via environment variable
|
|
2
|
+
export const DEBUG_MODE = process.env.DEBUG === "true";
|
|
3
|
+
/**
|
|
4
|
+
* Wraps a tool execution with debug metadata when DEBUG mode is enabled.
|
|
5
|
+
*
|
|
6
|
+
* @param toolName - Name of the tool being executed
|
|
7
|
+
* @param toolInput - Input arguments passed to the tool
|
|
8
|
+
* @param executeToolFn - Async function that executes the tool and returns data
|
|
9
|
+
* @returns ToolResponse with data and optional debug metadata
|
|
10
|
+
*/
|
|
11
|
+
export async function wrapWithDebug(toolName, toolInput, executeToolFn) {
|
|
12
|
+
const startTime = performance.now();
|
|
13
|
+
try {
|
|
14
|
+
const data = await executeToolFn();
|
|
15
|
+
const endTime = performance.now();
|
|
16
|
+
const toolCallTime = endTime - startTime;
|
|
17
|
+
if (DEBUG_MODE) {
|
|
18
|
+
return {
|
|
19
|
+
data,
|
|
20
|
+
debug: {
|
|
21
|
+
toolName,
|
|
22
|
+
toolInput,
|
|
23
|
+
toolCallTime,
|
|
24
|
+
timestamp: new Date().toISOString(),
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// In non-debug mode, return just the data wrapped
|
|
29
|
+
return { data };
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
// Re-throw the error to be handled by caller
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=debug-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-middleware.js","sourceRoot":"","sources":["../src/debug-middleware.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,SAAkB,EAClB,aAA+B;IAE/B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;QAEzC,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,IAAI;gBACJ,KAAK,EAAE;oBACL,QAAQ;oBACR,SAAS;oBACT,YAAY;oBACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC;aACF,CAAC;QACJ,CAAC;QAED,kDAAkD;QAClD,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6CAA6C;QAC7C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Auth } from "googleapis";
|
|
2
|
+
import type { Request } from "express";
|
|
3
|
+
/**
|
|
4
|
+
* Extract Google OAuth credentials from the request Authorization header
|
|
5
|
+
* @param req - Express request object
|
|
6
|
+
* @returns OAuth2Client configured with the access token
|
|
7
|
+
* @throws Error if Authorization header is missing or invalid
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractGoogleCredentials(req: Request): Auth.OAuth2Client;
|
|
10
|
+
/**
|
|
11
|
+
* Get Gmail API service
|
|
12
|
+
*/
|
|
13
|
+
export declare function getGmailService(req: Request): import("googleapis").gmail_v1.Gmail;
|
|
14
|
+
/**
|
|
15
|
+
* Get Google Drive API service
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDriveService(req: Request): import("googleapis").drive_v3.Drive;
|
|
18
|
+
/**
|
|
19
|
+
* Get Google Calendar API service
|
|
20
|
+
*/
|
|
21
|
+
export declare function getCalendarService(req: Request): import("googleapis").calendar_v3.Calendar;
|
|
22
|
+
/**
|
|
23
|
+
* Get Google Docs API service
|
|
24
|
+
*/
|
|
25
|
+
export declare function getDocsService(req: Request): import("googleapis").docs_v1.Docs;
|
|
26
|
+
/**
|
|
27
|
+
* Get Google Sheets API service
|
|
28
|
+
*/
|
|
29
|
+
export declare function getSheetsService(req: Request): import("googleapis").sheets_v4.Sheets;
|
|
30
|
+
/**
|
|
31
|
+
* Get Google Slides API service
|
|
32
|
+
*/
|
|
33
|
+
export declare function getSlidesService(req: Request): import("googleapis").slides_v1.Slides;
|
|
34
|
+
/**
|
|
35
|
+
* Get Google Tasks API service
|
|
36
|
+
*/
|
|
37
|
+
export declare function getTasksService(req: Request): import("googleapis").tasks_v1.Tasks;
|
|
38
|
+
/**
|
|
39
|
+
* Get Google Forms API service
|
|
40
|
+
*/
|
|
41
|
+
export declare function getFormsService(req: Request): import("googleapis").forms_v1.Forms;
|
|
42
|
+
/**
|
|
43
|
+
* Get Google Chat API service
|
|
44
|
+
*/
|
|
45
|
+
export declare function getChatService(req: Request): import("googleapis").chat_v1.Chat;
|
|
46
|
+
//# sourceMappingURL=google-api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-api-client.d.ts","sourceRoot":"","sources":["../src/google-api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,IAAI,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC,YAAY,CAoBxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,uCAE3C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,uCAE3C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,6CAE9C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,qCAE1C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,yCAE5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,yCAE5C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,uCAE3C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,uCAE3C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,qCAE1C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { google } from "googleapis";
|
|
2
|
+
/**
|
|
3
|
+
* Extract Google OAuth credentials from the request Authorization header
|
|
4
|
+
* @param req - Express request object
|
|
5
|
+
* @returns OAuth2Client configured with the access token
|
|
6
|
+
* @throws Error if Authorization header is missing or invalid
|
|
7
|
+
*/
|
|
8
|
+
export function extractGoogleCredentials(req) {
|
|
9
|
+
const authHeader = req.headers["authorization"];
|
|
10
|
+
if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) {
|
|
11
|
+
throw new Error("Authentication required. Please provide Authorization: Bearer <google_access_token> header");
|
|
12
|
+
}
|
|
13
|
+
const accessToken = authHeader.substring(7).trim();
|
|
14
|
+
if (!accessToken) {
|
|
15
|
+
throw new Error("Invalid Authorization header: Bearer token is empty");
|
|
16
|
+
}
|
|
17
|
+
// Create OAuth2 client with just the access token (stateless)
|
|
18
|
+
const oauth2Client = new google.auth.OAuth2();
|
|
19
|
+
oauth2Client.setCredentials({ access_token: accessToken });
|
|
20
|
+
return oauth2Client;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get Gmail API service
|
|
24
|
+
*/
|
|
25
|
+
export function getGmailService(req) {
|
|
26
|
+
return google.gmail({ version: "v1", auth: extractGoogleCredentials(req) });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get Google Drive API service
|
|
30
|
+
*/
|
|
31
|
+
export function getDriveService(req) {
|
|
32
|
+
return google.drive({ version: "v3", auth: extractGoogleCredentials(req) });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get Google Calendar API service
|
|
36
|
+
*/
|
|
37
|
+
export function getCalendarService(req) {
|
|
38
|
+
return google.calendar({ version: "v3", auth: extractGoogleCredentials(req) });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get Google Docs API service
|
|
42
|
+
*/
|
|
43
|
+
export function getDocsService(req) {
|
|
44
|
+
return google.docs({ version: "v1", auth: extractGoogleCredentials(req) });
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get Google Sheets API service
|
|
48
|
+
*/
|
|
49
|
+
export function getSheetsService(req) {
|
|
50
|
+
return google.sheets({ version: "v4", auth: extractGoogleCredentials(req) });
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get Google Slides API service
|
|
54
|
+
*/
|
|
55
|
+
export function getSlidesService(req) {
|
|
56
|
+
return google.slides({ version: "v1", auth: extractGoogleCredentials(req) });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get Google Tasks API service
|
|
60
|
+
*/
|
|
61
|
+
export function getTasksService(req) {
|
|
62
|
+
return google.tasks({ version: "v1", auth: extractGoogleCredentials(req) });
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get Google Forms API service
|
|
66
|
+
*/
|
|
67
|
+
export function getFormsService(req) {
|
|
68
|
+
return google.forms({ version: "v1", auth: extractGoogleCredentials(req) });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get Google Chat API service
|
|
72
|
+
*/
|
|
73
|
+
export function getChatService(req) {
|
|
74
|
+
return google.chat({ version: "v1", auth: extractGoogleCredentials(req) });
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=google-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-api-client.js","sourceRoot":"","sources":["../src/google-api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for Google Workspace MCP Server
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract plain text from Gmail message payload
|
|
6
|
+
* Handles both simple and multipart messages, including HTML-only emails
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractEmailBody(payload: any): string;
|
|
9
|
+
/**
|
|
10
|
+
* Decode base64url encoded string (used by Gmail API)
|
|
11
|
+
*/
|
|
12
|
+
export declare function decodeBase64Url(data: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Encode string to base64url (used for Gmail message creation)
|
|
15
|
+
*/
|
|
16
|
+
export declare function encodeBase64Url(data: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get header value from Gmail message headers
|
|
19
|
+
*/
|
|
20
|
+
export declare function getHeader(headers: Array<{
|
|
21
|
+
name?: string | null;
|
|
22
|
+
value?: string | null;
|
|
23
|
+
}> | undefined, headerName: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Extract text content from Google Docs document
|
|
26
|
+
*/
|
|
27
|
+
export declare function extractDocsContent(body: any): string;
|
|
28
|
+
/**
|
|
29
|
+
* Format Google Calendar event time for display
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatEventTime(eventTime: any): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Create a simple email message in RFC 2822 format
|
|
34
|
+
*/
|
|
35
|
+
export declare function createEmailMessage(to: string, subject: string, body: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Safely stringify error for logging
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatError(error: unknown): string;
|
|
40
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AAEH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,CAmDrD;AAsCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAEvB,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GAAG,SAAS,EAC3E,UAAU,EAAE,MAAM,GACjB,MAAM,CAMR;AAED;;GAEG;AAEH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAepD;AAED;;GAEG;AAEH,wBAAgB,eAAe,CAAC,SAAS,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAGlE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,MAAM,CAUR;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKlD"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for Google Workspace MCP Server
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract plain text from Gmail message payload
|
|
6
|
+
* Handles both simple and multipart messages, including HTML-only emails
|
|
7
|
+
*/
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
export function extractEmailBody(payload) {
|
|
10
|
+
// Simple message with body data
|
|
11
|
+
if (payload.body?.data) {
|
|
12
|
+
const content = decodeBase64Url(payload.body.data);
|
|
13
|
+
// If the top-level is HTML, strip tags
|
|
14
|
+
if (payload.mimeType === "text/html") {
|
|
15
|
+
return stripHtmlTags(content);
|
|
16
|
+
}
|
|
17
|
+
return content;
|
|
18
|
+
}
|
|
19
|
+
// Multipart message - look for text/plain part first
|
|
20
|
+
if (payload.parts) {
|
|
21
|
+
// First pass: look for text/plain
|
|
22
|
+
for (const part of payload.parts) {
|
|
23
|
+
if (part.mimeType === "text/plain" && part.body?.data) {
|
|
24
|
+
return decodeBase64Url(part.body.data);
|
|
25
|
+
}
|
|
26
|
+
// Check nested multipart (e.g., multipart/alternative inside multipart/mixed)
|
|
27
|
+
if (part.mimeType?.startsWith("multipart/") && part.parts) {
|
|
28
|
+
const nested = extractEmailBody(part);
|
|
29
|
+
if (nested)
|
|
30
|
+
return nested;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Second pass: look for text/html and convert to plain text
|
|
34
|
+
for (const part of payload.parts) {
|
|
35
|
+
if (part.mimeType === "text/html" && part.body?.data) {
|
|
36
|
+
const htmlContent = decodeBase64Url(part.body.data);
|
|
37
|
+
return stripHtmlTags(htmlContent);
|
|
38
|
+
}
|
|
39
|
+
// Check nested multipart for HTML
|
|
40
|
+
if (part.mimeType?.startsWith("multipart/") && part.parts) {
|
|
41
|
+
for (const nestedPart of part.parts) {
|
|
42
|
+
if (nestedPart.mimeType === "text/html" && nestedPart.body?.data) {
|
|
43
|
+
const htmlContent = decodeBase64Url(nestedPart.body.data);
|
|
44
|
+
return stripHtmlTags(htmlContent);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Fallback to first part with data
|
|
50
|
+
for (const part of payload.parts) {
|
|
51
|
+
if (part.body?.data) {
|
|
52
|
+
return decodeBase64Url(part.body.data);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Strip HTML tags and decode common HTML entities
|
|
60
|
+
* Converts HTML to readable plain text
|
|
61
|
+
*/
|
|
62
|
+
function stripHtmlTags(html) {
|
|
63
|
+
return (html
|
|
64
|
+
// Remove script and style content
|
|
65
|
+
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
|
|
66
|
+
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
|
|
67
|
+
// Replace common block elements with newlines
|
|
68
|
+
.replace(/<\/(p|div|h[1-6]|li|tr|br\s*\/?)>/gi, "\n")
|
|
69
|
+
.replace(/<br\s*\/?>/gi, "\n")
|
|
70
|
+
// Remove all remaining HTML tags
|
|
71
|
+
.replace(/<[^>]+>/g, "")
|
|
72
|
+
// Decode common HTML entities
|
|
73
|
+
.replace(/ /gi, " ")
|
|
74
|
+
.replace(/&/gi, "&")
|
|
75
|
+
.replace(/</gi, "<")
|
|
76
|
+
.replace(/>/gi, ">")
|
|
77
|
+
.replace(/"/gi, '"')
|
|
78
|
+
.replace(/'/gi, "'")
|
|
79
|
+
.replace(/’/gi, "'")
|
|
80
|
+
.replace(/‘/gi, "'")
|
|
81
|
+
.replace(/”/gi, '"')
|
|
82
|
+
.replace(/“/gi, '"')
|
|
83
|
+
.replace(/–/gi, "-")
|
|
84
|
+
.replace(/—/gi, "—")
|
|
85
|
+
.replace(/&#\d+;/gi, "") // Remove numeric entities
|
|
86
|
+
// Clean up whitespace
|
|
87
|
+
.replace(/\n\s*\n/g, "\n\n")
|
|
88
|
+
.replace(/[ \t]+/g, " ")
|
|
89
|
+
.trim());
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Decode base64url encoded string (used by Gmail API)
|
|
93
|
+
*/
|
|
94
|
+
export function decodeBase64Url(data) {
|
|
95
|
+
// Convert base64url to standard base64
|
|
96
|
+
const base64 = data.replace(/-/g, "+").replace(/_/g, "/");
|
|
97
|
+
// Decode
|
|
98
|
+
return Buffer.from(base64, "base64").toString("utf-8");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Encode string to base64url (used for Gmail message creation)
|
|
102
|
+
*/
|
|
103
|
+
export function encodeBase64Url(data) {
|
|
104
|
+
return Buffer.from(data)
|
|
105
|
+
.toString("base64")
|
|
106
|
+
.replace(/\+/g, "-")
|
|
107
|
+
.replace(/\//g, "_")
|
|
108
|
+
.replace(/=+$/, "");
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get header value from Gmail message headers
|
|
112
|
+
*/
|
|
113
|
+
export function getHeader(
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
headers, headerName) {
|
|
116
|
+
if (!headers)
|
|
117
|
+
return "";
|
|
118
|
+
const header = headers.find((h) => h.name?.toLowerCase() === headerName.toLowerCase());
|
|
119
|
+
return header?.value || "";
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Extract text content from Google Docs document
|
|
123
|
+
*/
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
export function extractDocsContent(body) {
|
|
126
|
+
if (!body?.content)
|
|
127
|
+
return "";
|
|
128
|
+
const textParts = [];
|
|
129
|
+
for (const element of body.content) {
|
|
130
|
+
if (element.paragraph?.elements) {
|
|
131
|
+
for (const textElement of element.paragraph.elements) {
|
|
132
|
+
if (textElement.textRun?.content) {
|
|
133
|
+
textParts.push(textElement.textRun.content);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return textParts.join("");
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Format Google Calendar event time for display
|
|
142
|
+
*/
|
|
143
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
|
+
export function formatEventTime(eventTime) {
|
|
145
|
+
if (!eventTime)
|
|
146
|
+
return undefined;
|
|
147
|
+
return eventTime.dateTime || eventTime.date || undefined;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Create a simple email message in RFC 2822 format
|
|
151
|
+
*/
|
|
152
|
+
export function createEmailMessage(to, subject, body) {
|
|
153
|
+
const message = [
|
|
154
|
+
`To: ${to}`,
|
|
155
|
+
`Subject: ${subject}`,
|
|
156
|
+
"Content-Type: text/plain; charset=utf-8",
|
|
157
|
+
"",
|
|
158
|
+
body,
|
|
159
|
+
].join("\r\n");
|
|
160
|
+
return message;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Safely stringify error for logging
|
|
164
|
+
*/
|
|
165
|
+
export function formatError(error) {
|
|
166
|
+
if (error instanceof Error) {
|
|
167
|
+
return error.message;
|
|
168
|
+
}
|
|
169
|
+
return String(error);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Google Workspace MCP Server
|
|
4
|
+
*
|
|
5
|
+
* A stateless Model Context Protocol server for Google Workspace services
|
|
6
|
+
* using Bearer token authentication.
|
|
7
|
+
*/
|
|
8
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
9
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
10
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
+
import express from "express";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
// Import schemas
|
|
14
|
+
import { GmailListLabelsSchema, GmailSearchMessagesSchema, GmailGetMessageContentSchema, GmailSendMessageSchema, DriveListFilesSchema, DriveGetFileContentSchema, DriveCreateFileSchema, CalendarListEventsSchema, CalendarListCalendarsSchema, CalendarCreateEventSchema, DocsGetDocumentSchema, DocsCreateDocumentSchema, SheetsGetSpreadsheetSchema, SheetsReadValuesSchema, SheetsCreateSpreadsheetSchema, SlidesGetPresentationSchema, SlidesCreatePresentationSchema, TasksListTaskListsSchema, TasksListTasksSchema, TasksCreateTaskSchema, FormsCreateFormSchema, FormsGetFormSchema, ChatListSpacesSchema, ChatSendMessageSchema, } from "./schemas.js";
|
|
15
|
+
// Import tool handlers
|
|
16
|
+
import { gmailListLabels, gmailSearchMessages, gmailGetMessageContent, gmailSendMessage, driveListFiles, driveGetFileContent, driveCreateFile, calendarListEvents, calendarListCalendars, calendarCreateEvent, docsGetDocument, docsCreateDocument, sheetsGetSpreadsheet, sheetsReadValues, sheetsCreateSpreadsheet, slidesGetPresentation, slidesCreatePresentation, tasksListTaskLists, tasksListTasks, tasksCreateTask, formsCreateForm, formsGetForm, chatListSpaces, chatSendMessage, } from "./tools/index.js";
|
|
17
|
+
// Import tool loader
|
|
18
|
+
import { loadToolDefinitions } from "./tool-loader.js";
|
|
19
|
+
// Import tool registry
|
|
20
|
+
import { ToolRegistry } from "./tool-registry.js";
|
|
21
|
+
// Import debug mode flag
|
|
22
|
+
import { DEBUG_MODE } from "./debug-middleware.js";
|
|
23
|
+
// Create tool registry and register all tools
|
|
24
|
+
const toolRegistry = new ToolRegistry();
|
|
25
|
+
// Register Gmail tools (4)
|
|
26
|
+
toolRegistry.register("gmail_list_labels", GmailListLabelsSchema, gmailListLabels);
|
|
27
|
+
toolRegistry.register("gmail_search_messages", GmailSearchMessagesSchema, gmailSearchMessages);
|
|
28
|
+
toolRegistry.register("gmail_get_message_content", GmailGetMessageContentSchema, gmailGetMessageContent);
|
|
29
|
+
toolRegistry.register("gmail_send_message", GmailSendMessageSchema, gmailSendMessage);
|
|
30
|
+
// Register Drive tools (3)
|
|
31
|
+
toolRegistry.register("drive_list_files", DriveListFilesSchema, driveListFiles);
|
|
32
|
+
toolRegistry.register("drive_get_file_content", DriveGetFileContentSchema, driveGetFileContent);
|
|
33
|
+
toolRegistry.register("drive_create_file", DriveCreateFileSchema, driveCreateFile);
|
|
34
|
+
// Register Calendar tools (3)
|
|
35
|
+
toolRegistry.register("calendar_list_events", CalendarListEventsSchema, calendarListEvents);
|
|
36
|
+
toolRegistry.register("calendar_list_calendars", CalendarListCalendarsSchema, calendarListCalendars);
|
|
37
|
+
toolRegistry.register("calendar_create_event", CalendarCreateEventSchema, calendarCreateEvent);
|
|
38
|
+
// Register Docs tools (2)
|
|
39
|
+
toolRegistry.register("docs_get_document", DocsGetDocumentSchema, docsGetDocument);
|
|
40
|
+
toolRegistry.register("docs_create_document", DocsCreateDocumentSchema, docsCreateDocument);
|
|
41
|
+
// Register Sheets tools (3)
|
|
42
|
+
toolRegistry.register("sheets_get_spreadsheet", SheetsGetSpreadsheetSchema, sheetsGetSpreadsheet);
|
|
43
|
+
toolRegistry.register("sheets_read_values", SheetsReadValuesSchema, sheetsReadValues);
|
|
44
|
+
toolRegistry.register("sheets_create_spreadsheet", SheetsCreateSpreadsheetSchema, sheetsCreateSpreadsheet);
|
|
45
|
+
// Register Slides tools (2)
|
|
46
|
+
toolRegistry.register("slides_get_presentation", SlidesGetPresentationSchema, slidesGetPresentation);
|
|
47
|
+
toolRegistry.register("slides_create_presentation", SlidesCreatePresentationSchema, slidesCreatePresentation);
|
|
48
|
+
// Register Tasks tools (3)
|
|
49
|
+
toolRegistry.register("tasks_list_task_lists", TasksListTaskListsSchema, tasksListTaskLists);
|
|
50
|
+
toolRegistry.register("tasks_list_tasks", TasksListTasksSchema, tasksListTasks);
|
|
51
|
+
toolRegistry.register("tasks_create_task", TasksCreateTaskSchema, tasksCreateTask);
|
|
52
|
+
// Register Forms tools (2)
|
|
53
|
+
toolRegistry.register("forms_create_form", FormsCreateFormSchema, formsCreateForm);
|
|
54
|
+
toolRegistry.register("forms_get_form", FormsGetFormSchema, formsGetForm);
|
|
55
|
+
// Register Chat tools (2)
|
|
56
|
+
toolRegistry.register("chat_list_spaces", ChatListSpacesSchema, chatListSpaces);
|
|
57
|
+
toolRegistry.register("chat_send_message", ChatSendMessageSchema, chatSendMessage);
|
|
58
|
+
// Create MCP server
|
|
59
|
+
const server = new Server({
|
|
60
|
+
name: "google-workspace-mcp-server",
|
|
61
|
+
version: "1.0.0",
|
|
62
|
+
}, {
|
|
63
|
+
capabilities: {
|
|
64
|
+
tools: {},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
// Register tool handlers
|
|
68
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
69
|
+
// Load tool definitions from JSON (reloads on each request in dev mode)
|
|
70
|
+
const toolDefinitions = loadToolDefinitions();
|
|
71
|
+
return {
|
|
72
|
+
tools: toolDefinitions,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
// Store current request in context (set during HTTP request handling)
|
|
76
|
+
let currentRequest = null;
|
|
77
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
78
|
+
if (!currentRequest) {
|
|
79
|
+
throw new Error("No request context available. This server must be called via HTTP transport.");
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
// Execute tool via registry (includes automatic validation and debug wrapping)
|
|
83
|
+
const result = await toolRegistry.execute(request.params.name, request.params.arguments, currentRequest);
|
|
84
|
+
// Return formatted response with data and optional debug info
|
|
85
|
+
// Debug info is included in the response when DEBUG mode is enabled
|
|
86
|
+
return {
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: JSON.stringify(result, null, 2),
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (error instanceof z.ZodError) {
|
|
97
|
+
throw new Error(`Invalid arguments: ${error.message}`);
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// Create Express app with stateless HTTP transport
|
|
103
|
+
const app = express();
|
|
104
|
+
app.use(express.json());
|
|
105
|
+
// Create stateless transport (no session management)
|
|
106
|
+
const transport = new StreamableHTTPServerTransport({
|
|
107
|
+
sessionIdGenerator: undefined, // Stateless mode
|
|
108
|
+
enableJsonResponse: true,
|
|
109
|
+
});
|
|
110
|
+
// Connect server to transport
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
// Handle MCP requests
|
|
113
|
+
app.post("/mcp", async (req, res) => {
|
|
114
|
+
try {
|
|
115
|
+
// Store request in context for tool handlers to access headers
|
|
116
|
+
currentRequest = req;
|
|
117
|
+
await transport.handleRequest(req, res, req.body);
|
|
118
|
+
currentRequest = null; // Clear context after request
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
currentRequest = null; // Clear context on error
|
|
122
|
+
console.error("Error handling MCP request:", error);
|
|
123
|
+
res.status(500).json({
|
|
124
|
+
error: "Internal server error",
|
|
125
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// Health check endpoint
|
|
130
|
+
app.get("/health", (_req, res) => {
|
|
131
|
+
res.json({
|
|
132
|
+
status: "healthy",
|
|
133
|
+
server: "google-workspace-mcp-server",
|
|
134
|
+
version: "1.0.0",
|
|
135
|
+
stateless: true,
|
|
136
|
+
debug: DEBUG_MODE,
|
|
137
|
+
registeredTools: toolRegistry.getToolNames(),
|
|
138
|
+
services: [
|
|
139
|
+
"Gmail",
|
|
140
|
+
"Drive",
|
|
141
|
+
"Calendar",
|
|
142
|
+
"Docs",
|
|
143
|
+
"Sheets",
|
|
144
|
+
"Slides",
|
|
145
|
+
"Tasks",
|
|
146
|
+
"Forms",
|
|
147
|
+
"Chat",
|
|
148
|
+
],
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
// Start server
|
|
152
|
+
const PORT = process.env.PORT || 30000;
|
|
153
|
+
app.listen(PORT, () => {
|
|
154
|
+
console.log(`Google Workspace MCP Server running on http://localhost:${PORT}`);
|
|
155
|
+
console.log(`MCP endpoint: http://localhost:${PORT}/mcp`);
|
|
156
|
+
console.log(`Health check: http://localhost:${PORT}/health`);
|
|
157
|
+
console.log("Mode: Stateless (no session management)");
|
|
158
|
+
console.log("Authentication: Bearer token required");
|
|
159
|
+
console.log(`Debug mode: ${DEBUG_MODE ? "ENABLED" : "DISABLED"}`);
|
|
160
|
+
console.log(`Available services: Gmail, Drive, Calendar, Docs, Sheets, Slides, Tasks, Forms, Chat`);
|
|
161
|
+
console.log(`Total tools: ${toolRegistry.getToolNames().length}`);
|
|
162
|
+
if (DEBUG_MODE) {
|
|
163
|
+
console.log(`Registered tools: ${toolRegistry.getToolNames().join(", ")}`);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,OAAyB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iBAAiB;AACjB,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC9B,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAEtB,uBAAuB;AACvB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,qBAAqB;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,yBAAyB;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,8CAA8C;AAC9C,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;AAExC,2BAA2B;AAC3B,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;AACnF,YAAY,CAAC,QAAQ,CAAC,uBAAuB,EAAE,yBAAyB,EAAE,mBAAmB,CAAC,CAAC;AAC/F,YAAY,CAAC,QAAQ,CAAC,2BAA2B,EAAE,4BAA4B,EAAE,sBAAsB,CAAC,CAAC;AACzG,YAAY,CAAC,QAAQ,CAAC,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;AAEtF,2BAA2B;AAC3B,YAAY,CAAC,QAAQ,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAAC;AAChF,YAAY,CAAC,QAAQ,CAAC,wBAAwB,EAAE,yBAAyB,EAAE,mBAAmB,CAAC,CAAC;AAChG,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;AAEnF,8BAA8B;AAC9B,YAAY,CAAC,QAAQ,CAAC,sBAAsB,EAAE,wBAAwB,EAAE,kBAAkB,CAAC,CAAC;AAC5F,YAAY,CAAC,QAAQ,CAAC,yBAAyB,EAAE,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;AACrG,YAAY,CAAC,QAAQ,CAAC,uBAAuB,EAAE,yBAAyB,EAAE,mBAAmB,CAAC,CAAC;AAE/F,0BAA0B;AAC1B,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;AACnF,YAAY,CAAC,QAAQ,CAAC,sBAAsB,EAAE,wBAAwB,EAAE,kBAAkB,CAAC,CAAC;AAE5F,4BAA4B;AAC5B,YAAY,CAAC,QAAQ,CAAC,wBAAwB,EAAE,0BAA0B,EAAE,oBAAoB,CAAC,CAAC;AAClG,YAAY,CAAC,QAAQ,CAAC,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;AACtF,YAAY,CAAC,QAAQ,CAAC,2BAA2B,EAAE,6BAA6B,EAAE,uBAAuB,CAAC,CAAC;AAE3G,4BAA4B;AAC5B,YAAY,CAAC,QAAQ,CAAC,yBAAyB,EAAE,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;AACrG,YAAY,CAAC,QAAQ,CAAC,4BAA4B,EAAE,8BAA8B,EAAE,wBAAwB,CAAC,CAAC;AAE9G,2BAA2B;AAC3B,YAAY,CAAC,QAAQ,CAAC,uBAAuB,EAAE,wBAAwB,EAAE,kBAAkB,CAAC,CAAC;AAC7F,YAAY,CAAC,QAAQ,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAAC;AAChF,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;AAEnF,2BAA2B;AAC3B,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;AACnF,YAAY,CAAC,QAAQ,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,CAAC,CAAC;AAE1E,0BAA0B;AAC1B,YAAY,CAAC,QAAQ,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAAC;AAChF,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;AAEnF,oBAAoB;AACpB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,6BAA6B;IACnC,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,wEAAwE;IACxE,MAAM,eAAe,GAAG,mBAAmB,EAAE,CAAC;IAE9C,OAAO;QACL,KAAK,EAAE,eAAe;KACvB,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,sEAAsE;AACtE,IAAI,cAAc,GAAmB,IAAI,CAAC;AAE1C,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,+EAA+E;QAC/E,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CACvC,OAAO,CAAC,MAAM,CAAC,IAAI,EACnB,OAAO,CAAC,MAAM,CAAC,SAAS,EACxB,cAAc,CACf,CAAC;QAEF,8DAA8D;QAC9D,oEAAoE;QACpE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,mDAAmD;AACnD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAExB,qDAAqD;AACrD,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;IAClD,kBAAkB,EAAE,SAAS,EAAE,iBAAiB;IAChD,kBAAkB,EAAE,IAAI;CACzB,CAAC,CAAC;AAEH,8BAA8B;AAC9B,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAEhC,sBAAsB;AACtB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAClC,IAAI,CAAC;QACH,+DAA+D;QAC/D,cAAc,GAAG,GAAG,CAAC;QACrB,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,cAAc,GAAG,IAAI,CAAC,CAAC,8BAA8B;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,GAAG,IAAI,CAAC,CAAC,yBAAyB;QAChD,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAClE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,wBAAwB;AACxB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAC/B,GAAG,CAAC,IAAI,CAAC;QACP,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,6BAA6B;QACrC,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,YAAY,CAAC,YAAY,EAAE;QAC5C,QAAQ,EAAE;YACR,OAAO;YACP,OAAO;YACP,UAAU;YACV,MAAM;YACN,QAAQ;YACR,QAAQ;YACR,OAAO;YACP,OAAO;YACP,MAAM;SACP;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,eAAe;AACf,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC;AACvC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACpB,OAAO,CAAC,GAAG,CAAC,2DAA2D,IAAI,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,MAAM,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,SAAS,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CACT,sFAAsF,CACvF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,qBAAqB,YAAY,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC,CAAC,CAAC"}
|