@coretext-ai/qa-gsuite-f47ac10b-58cc-4372-a567-0e02b2c3d479
Version:
MCP server with GSuite (Contacts, Drive, Gmail, Calendar) integration
846 lines • 36.9 kB
JavaScript
import { Logger } from '../services/logger.js';
export class GoogleGmailTools {
constructor(client) {
this.initialized = false;
this.client = client;
// Get logger from client if available, otherwise create fallback
this.logger = client.logger || new Logger({
logLevel: 'ERROR',
component: 'tools',
enableConsole: true,
enableShipping: false,
serverName: ''
});
}
async ensureInitialized() {
if (!this.initialized) {
// Log tools initialization now that client is ready
this.logger.info('TOOLS_INIT', 'Tools instance initialization started', {
integration: 'google-gmail',
isOAuth: true
});
this.logger.info('CLIENT_INITIALIZATION', 'Starting client initialization', {
isOAuth: true
});
await this.client.initialize();
this.initialized = true;
this.logger.info('CLIENT_INITIALIZATION', 'Client initialization completed', {
initialized: this.initialized
});
}
}
getToolDefinitions() {
return [
{
name: 'google-gmail_send_message',
description: 'Send an email message. Requires message in RFC 2822 format encoded as base64url string',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
raw: {
type: 'string',
description: 'RFC 2822 formatted and base64url encoded email message'
},
},
required: ['raw']
}
},
{
name: 'google-gmail_get_message',
description: 'Get a specific message by ID',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Message ID to retrieve'
},
format: {
type: 'string',
description: 'Format of message (full, metadata, minimal, raw)'
},
metadataHeaders: {
type: 'string',
description: 'Comma-separated list of header names to include when format=metadata'
},
},
required: ['id',]
}
},
{
name: 'google-gmail_list_messages',
description: 'List messages in user's mailbox with optional filtering',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
q: {
type: 'string',
description: 'Gmail search query (e.g., 'from:user@example.com subject:important')'
},
labelIds: {
type: 'string',
description: 'Comma-separated list of label IDs to filter by'
},
maxResults: {
type: 'number',
description: 'Maximum number of messages to return (1-500, default 100)'
},
pageToken: {
type: 'string',
description: 'Page token for pagination'
},
includeSpamTrash: {
type: 'boolean',
description: 'Include messages from SPAM and TRASH'
},
},
required: []
}
},
{
name: 'google-gmail_modify_message',
description: 'Modify labels on a message (add/remove labels, mark read/unread)',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Message ID to modify'
},
addLabelIds: {
type: 'string',
description: 'Comma-separated list of label IDs to add'
},
removeLabelIds: {
type: 'string',
description: 'Comma-separated list of label IDs to remove'
},
},
required: ['id',]
}
},
{
name: 'google-gmail_trash_message',
description: 'Move a message to trash',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Message ID to trash'
},
},
required: ['id']
}
},
{
name: 'google-gmail_untrash_message',
description: 'Remove a message from trash',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Message ID to untrash'
},
},
required: ['id']
}
},
{
name: 'google-gmail_delete_message',
description: 'Permanently delete a message',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Message ID to delete permanently'
},
},
required: ['id']
}
},
{
name: 'google-gmail_list_labels',
description: 'List all labels in the user's mailbox',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
},
required: []
}
},
{
name: 'google-gmail_get_label',
description: 'Get label details by ID',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Label ID to retrieve'
},
},
required: ['id']
}
},
{
name: 'google-gmail_create_label',
description: 'Create a new custom label',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
name: {
type: 'string',
description: 'Display name for the label'
},
labelListVisibility: {
type: 'string',
description: 'Visibility in label list (labelShow, labelShowIfUnread, labelHide)'
},
messageListVisibility: {
type: 'string',
description: 'Visibility in message list (show, hide)'
},
color: {
type: 'string',
description: 'Label color configuration'
},
},
required: ['name',]
}
},
{
name: 'google-gmail_update_label',
description: 'Update an existing label',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Label ID to update'
},
name: {
type: 'string',
description: 'Display name for the label'
},
labelListVisibility: {
type: 'string',
description: 'Visibility in label list (labelShow, labelShowIfUnread, labelHide)'
},
messageListVisibility: {
type: 'string',
description: 'Visibility in message list (show, hide)'
},
color: {
type: 'string',
description: 'Label color configuration'
},
},
required: ['id',]
}
},
{
name: 'google-gmail_delete_label',
description: 'Delete a custom label',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Label ID to delete'
},
},
required: ['id']
}
},
{
name: 'google-gmail_list_threads',
description: 'List email threads in user's mailbox',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
q: {
type: 'string',
description: 'Gmail search query for threads'
},
labelIds: {
type: 'string',
description: 'Comma-separated list of label IDs to filter by'
},
maxResults: {
type: 'number',
description: 'Maximum number of threads to return (1-500, default 100)'
},
pageToken: {
type: 'string',
description: 'Page token for pagination'
},
includeSpamTrash: {
type: 'boolean',
description: 'Include threads from SPAM and TRASH'
},
},
required: []
}
},
{
name: 'google-gmail_get_thread',
description: 'Get a specific thread by ID',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Thread ID to retrieve'
},
format: {
type: 'string',
description: 'Format of messages in thread (full, metadata, minimal)'
},
metadataHeaders: {
type: 'string',
description: 'Comma-separated list of header names when format=metadata'
},
},
required: ['id',]
}
},
{
name: 'google-gmail_modify_thread',
description: 'Modify labels on all messages in a thread',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Thread ID to modify'
},
addLabelIds: {
type: 'string',
description: 'Comma-separated list of label IDs to add'
},
removeLabelIds: {
type: 'string',
description: 'Comma-separated list of label IDs to remove'
},
},
required: ['id',]
}
},
{
name: 'google-gmail_trash_thread',
description: 'Move a thread to trash',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Thread ID to trash'
},
},
required: ['id']
}
},
{
name: 'google-gmail_untrash_thread',
description: 'Remove a thread from trash',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Thread ID to untrash'
},
},
required: ['id']
}
},
{
name: 'google-gmail_delete_thread',
description: 'Permanently delete a thread',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Thread ID to delete permanently'
},
},
required: ['id']
}
},
{
name: 'google-gmail_list_drafts',
description: 'List draft messages in user's mailbox',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
q: {
type: 'string',
description: 'Gmail search query for drafts'
},
maxResults: {
type: 'number',
description: 'Maximum number of drafts to return (1-500, default 100)'
},
pageToken: {
type: 'string',
description: 'Page token for pagination'
},
includeSpamTrash: {
type: 'boolean',
description: 'Include drafts from SPAM and TRASH'
},
},
required: []
}
},
{
name: 'google-gmail_get_draft',
description: 'Get a specific draft by ID',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Draft ID to retrieve'
},
format: {
type: 'string',
description: 'Format of draft message (full, metadata, minimal, raw)'
},
},
required: ['id',]
}
},
{
name: 'google-gmail_create_draft',
description: 'Create a new draft message',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
message: {
type: 'string',
description: 'Message object containing raw RFC 2822 email or structured fields'
},
},
required: ['message']
}
},
{
name: 'google-gmail_update_draft',
description: 'Update an existing draft',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Draft ID to update'
},
message: {
type: 'string',
description: 'Updated message object'
},
},
required: ['id', 'message']
}
},
{
name: 'google-gmail_send_draft',
description: 'Send an existing draft',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Draft ID to send'
},
},
required: ['id']
}
},
{
name: 'google-gmail_delete_draft',
description: 'Delete a draft',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
id: {
type: 'string',
description: 'Draft ID to delete'
},
},
required: ['id']
}
},
{
name: 'google-gmail_get_profile',
description: 'Get user's Gmail profile information',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'User's email address or 'me' for authenticated user'
},
},
required: []
}
}
];
}
canHandle(toolName) {
const supportedTools = [
'google-gmail_send_message',
'google-gmail_get_message',
'google-gmail_list_messages',
'google-gmail_modify_message',
'google-gmail_trash_message',
'google-gmail_untrash_message',
'google-gmail_delete_message',
'google-gmail_list_labels',
'google-gmail_get_label',
'google-gmail_create_label',
'google-gmail_update_label',
'google-gmail_delete_label',
'google-gmail_list_threads',
'google-gmail_get_thread',
'google-gmail_modify_thread',
'google-gmail_trash_thread',
'google-gmail_untrash_thread',
'google-gmail_delete_thread',
'google-gmail_list_drafts',
'google-gmail_get_draft',
'google-gmail_create_draft',
'google-gmail_update_draft',
'google-gmail_send_draft',
'google-gmail_delete_draft',
'google-gmail_get_profile'
];
return supportedTools.includes(toolName);
}
async executeTool(name, args) {
const startTime = Date.now();
this.logger.logToolStart(name, args);
await this.ensureInitialized();
// Validate tool is supported
if (!this.canHandle(name)) {
this.logger.error('TOOL_ERROR', 'Unknown tool requested', {
tool: name,
supportedTools: ['google-gmail_send_message', 'google-gmail_get_message', 'google-gmail_list_messages', 'google-gmail_modify_message', 'google-gmail_trash_message', 'google-gmail_untrash_message', 'google-gmail_delete_message', 'google-gmail_list_labels', 'google-gmail_get_label', 'google-gmail_create_label', 'google-gmail_update_label', 'google-gmail_delete_label', 'google-gmail_list_threads', 'google-gmail_get_thread', 'google-gmail_modify_thread', 'google-gmail_trash_thread', 'google-gmail_untrash_thread', 'google-gmail_delete_thread', 'google-gmail_list_drafts', 'google-gmail_get_draft', 'google-gmail_create_draft', 'google-gmail_update_draft', 'google-gmail_send_draft', 'google-gmail_delete_draft', 'google-gmail_get_profile']
});
throw new Error(`Unknown tool: ${name}`);
}
// Validate required parameters
this.logger.debug('PARAM_VALIDATION', 'Validating tool parameters', {
tool: name,
providedArgs: Object.keys(args || {})
});
try {
let result;
switch (name) {
case 'google-gmail_send_message':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_send_message',
clientMethod: 'sendMessage'
});
result = await this.client.sendMessage(args);
break;
case 'google-gmail_get_message':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_get_message',
clientMethod: 'getMessage'
});
result = await this.client.getMessage(args);
break;
case 'google-gmail_list_messages':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_list_messages',
clientMethod: 'listMessages'
});
result = await this.client.listMessages(args);
break;
case 'google-gmail_modify_message':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_modify_message',
clientMethod: 'modifyMessage'
});
result = await this.client.modifyMessage(args);
break;
case 'google-gmail_trash_message':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_trash_message',
clientMethod: 'trashMessage'
});
result = await this.client.trashMessage(args);
break;
case 'google-gmail_untrash_message':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_untrash_message',
clientMethod: 'untrashMessage'
});
result = await this.client.untrashMessage(args);
break;
case 'google-gmail_delete_message':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_delete_message',
clientMethod: 'deleteMessage'
});
result = await this.client.deleteMessage(args);
break;
case 'google-gmail_list_labels':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_list_labels',
clientMethod: 'listLabels'
});
result = await this.client.listLabels(args);
break;
case 'google-gmail_get_label':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_get_label',
clientMethod: 'getLabel'
});
result = await this.client.getLabel(args);
break;
case 'google-gmail_create_label':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_create_label',
clientMethod: 'createLabel'
});
result = await this.client.createLabel(args);
break;
case 'google-gmail_update_label':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_update_label',
clientMethod: 'updateLabel'
});
result = await this.client.updateLabel(args);
break;
case 'google-gmail_delete_label':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_delete_label',
clientMethod: 'deleteLabel'
});
result = await this.client.deleteLabel(args);
break;
case 'google-gmail_list_threads':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_list_threads',
clientMethod: 'listThreads'
});
result = await this.client.listThreads(args);
break;
case 'google-gmail_get_thread':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_get_thread',
clientMethod: 'getThread'
});
result = await this.client.getThread(args);
break;
case 'google-gmail_modify_thread':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_modify_thread',
clientMethod: 'modifyThread'
});
result = await this.client.modifyThread(args);
break;
case 'google-gmail_trash_thread':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_trash_thread',
clientMethod: 'trashThread'
});
result = await this.client.trashThread(args);
break;
case 'google-gmail_untrash_thread':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_untrash_thread',
clientMethod: 'untrashThread'
});
result = await this.client.untrashThread(args);
break;
case 'google-gmail_delete_thread':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_delete_thread',
clientMethod: 'deleteThread'
});
result = await this.client.deleteThread(args);
break;
case 'google-gmail_list_drafts':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_list_drafts',
clientMethod: 'listDrafts'
});
result = await this.client.listDrafts(args);
break;
case 'google-gmail_get_draft':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_get_draft',
clientMethod: 'getDraft'
});
result = await this.client.getDraft(args);
break;
case 'google-gmail_create_draft':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_create_draft',
clientMethod: 'createDraft'
});
result = await this.client.createDraft(args);
break;
case 'google-gmail_update_draft':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_update_draft',
clientMethod: 'updateDraft'
});
result = await this.client.updateDraft(args);
break;
case 'google-gmail_send_draft':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_send_draft',
clientMethod: 'sendDraft'
});
result = await this.client.sendDraft(args);
break;
case 'google-gmail_delete_draft':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_delete_draft',
clientMethod: 'deleteDraft'
});
result = await this.client.deleteDraft(args);
break;
case 'google-gmail_get_profile':
this.logger.debug('TOOL_EXECUTE', 'Calling client method', {
tool: 'google-gmail_get_profile',
clientMethod: 'getProfile'
});
result = await this.client.getProfile(args);
break;
default:
throw new Error(`Unknown tool: ${name}`);
}
const duration = Date.now() - startTime;
this.logger.logToolSuccess(name, duration, result);
// Format the result for MCP (OAuth templates only)
return {
content: [
{
type: 'text',
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2)
}
]
};
}
catch (error) {
const duration = Date.now() - startTime;
const errorMessage = error instanceof Error ? error.message : String(error);
this.logger.logToolError(name, error, duration, args);
return {
content: [
{
type: 'text',
text: `Error: ${errorMessage}`
}
],
isError: true
};
}
}
}
//# sourceMappingURL=google-gmail-tools.js.map