Skip to main content
Glama
index.js5.24 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import { GamExecutor } from './gam-executor.js'; import { allTools } from './tools/index.js'; /** * GAM MCP Server * Provides Google Workspace administration capabilities via GAM CLI */ async function main() { // Initialize GAM executor with path from environment or default const gamPath = process.env['GAM_PATH'] || 'gam'; const gamExecutor = new GamExecutor(gamPath); // Validate GAM setup before starting console.log('[MCP] Validating GAM installation...'); const isInstalled = await gamExecutor.checkGamInstallation(); if (!isInstalled) { console.error('[MCP] GAM is not properly installed or configured'); console.error('[MCP] Please ensure GAM is installed and authenticated'); console.error('[MCP] Run "gam oauth create" to set up authentication'); process.exit(1); } console.log('[MCP] GAM installation validated successfully'); // Create MCP server const server = new Server({ name: 'gam-mcp-server', version: '1.0.0', description: 'Google Workspace administration via GAM CLI - MCP Server for Claude' }, { capabilities: { tools: {} } }); // Set up tools list handler server.setRequestHandler(z.object({ method: z.literal('tools/list') }), async () => { const tools = allTools.map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema })); return { tools }; }); // Set up tool call handler server.setRequestHandler(z.object({ method: z.literal('tools/call'), params: z.object({ name: z.string(), arguments: z.any() }) }), async (request) => { const toolName = request.params.name; const tool = allTools.find(t => t.name === toolName); if (!tool) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Unknown tool: ${toolName}`, data: null }, null, 2) } ], isError: true }; } try { // Validate input parameters const args = request.params.arguments ?? {}; const validatedParams = tool.inputSchema.parse(args); // Execute tool handler const result = await tool.handler(validatedParams); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } catch (error) { console.error(`[MCP] Tool ${toolName} error:`, error); // Handle validation errors specifically let errorMessage = 'Unknown error occurred'; if (error instanceof Error) { errorMessage = error.message; } else if (error && typeof error === 'object' && 'issues' in error) { // Zod validation error const zodError = error; errorMessage = `Validation error: ${zodError.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`).join(', ')}`; } return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: errorMessage, data: null }, null, 2) } ], isError: true }; } }); // Set up error handling server.onerror = (error) => { console.error('[MCP] Server error:', error); }; process.on('SIGINT', () => { console.log('[MCP] Received SIGINT, shutting down gracefully...'); server.close().then(() => { console.log('[MCP] Server shutdown complete'); process.exit(0); }); }); process.on('SIGTERM', () => { console.log('[MCP] Received SIGTERM, shutting down gracefully...'); server.close().then(() => { console.log('[MCP] Server shutdown complete'); process.exit(0); }); }); try { // Create transport and start server const transport = new StdioServerTransport(); await server.connect(transport); console.log('[MCP] GAM MCP Server started successfully'); console.log('[MCP] Available tools:', allTools.map(t => t.name).join(', ')); } catch (error) { console.error('[MCP] Failed to start server:', error); process.exit(1); } } // Start the server main().catch((error) => { console.error('[MCP] Failed to start server:', error); process.exit(1); }); //# sourceMappingURL=index.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dbarks/mcp-gam'

If you have feedback or need assistance with the MCP directory API, please join our Discord server