#!/usr/bin/env node
/**
* MCP Server for Google Workspace
*
* Provides tools for interacting with Gmail, Drive, Sheets, Docs, and Calendar.
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ErrorCode,
ListToolsRequestSchema,
McpError,
} from '@modelcontextprotocol/sdk/types.js';
import {
getLogger,
getConfig,
formatErrorResponse,
MCPError,
} from '@company-mcp/core';
import { allTools, allHandlers } from './tools/index.js';
import { getAuthClient } from './auth/google-auth.js';
// Initialize logger
const config = getConfig();
const logger = getLogger({
logDir: config.log_dir,
enableConsole: config.log_to_console,
enableFile: config.log_to_file,
minLevel: config.log_level,
});
// Create MCP server
const server = new Server(
{
name: 'mcp-server-google',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Handle list tools request
server.setRequestHandler(ListToolsRequestSchema, async () => {
logger.debug('mcp-server', 'List tools requested');
return {
tools: allTools.map((tool) => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
})),
};
});
// Handle tool call request
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
logger.info('mcp-server', `Tool called: ${name}`);
const handler = allHandlers[name];
if (!handler) {
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
}
try {
// Ensure auth is initialized
getAuthClient();
const result = await handler(args);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
} catch (error) {
logger.error('mcp-server', `Tool error: ${name}`, error as Error);
const errorResponse = formatErrorResponse(error);
// Map to MCP error codes
if (error instanceof MCPError) {
if (error.code === 'VALIDATION_ERROR') {
throw new McpError(ErrorCode.InvalidParams, error.message);
}
if (error.code.startsWith('GOOGLE_API_ERROR_4')) {
throw new McpError(ErrorCode.InvalidRequest, error.message);
}
}
// Return error as content for non-fatal errors
return {
content: [
{
type: 'text',
text: JSON.stringify(errorResponse, null, 2),
},
],
isError: true,
};
}
});
// Start server
async function main(): Promise<void> {
logger.info('mcp-server', 'Starting MCP Server for Google Workspace');
logger.info('mcp-server', `Auth mode: ${config.auth_mode}`);
logger.info('mcp-server', `Available tools: ${allTools.length}`);
// Log feature flags
const enabledFeatures = Object.entries(config.features)
.filter(([, v]) => v === true)
.map(([k]) => k);
logger.info('mcp-server', `Enabled features: ${enabledFeatures.join(', ')}`);
const transport = new StdioServerTransport();
await server.connect(transport);
logger.info('mcp-server', 'Server started successfully');
}
main().catch((error) => {
logger.error('mcp-server', 'Fatal error', error);
process.exit(1);
});