import { z } from 'zod';
import { GamExecutor, GamSchemas } from '../gam-executor.js';
/**
* Group Management Tools for GAM MCP Server
* Provides comprehensive group administration capabilities
*/
const gam = new GamExecutor();
// Schema for group list parameters
const ListGroupsSchema = z.object({
domain: GamSchemas.domain.optional(),
maxResults: GamSchemas.maxResults
});
// Schema for get group parameters
const GetGroupSchema = z.object({
groupEmail: GamSchemas.email
});
// Schema for create group parameters
const CreateGroupSchema = z.object({
groupEmail: GamSchemas.email,
groupName: GamSchemas.groupName,
description: GamSchemas.description
});
// Schema for add/remove group member parameters
const GroupMemberSchema = z.object({
groupEmail: GamSchemas.email,
memberEmail: GamSchemas.email,
role: GamSchemas.role
});
// Schema for list org units parameters
const ListOrgUnitsSchema = z.object({
maxResults: GamSchemas.maxResults
});
// Schema for domain info parameters
const DomainInfoSchema = z.object({});
/**
* List all groups in the Google Workspace domain
*/
export const gam_list_groups = {
name: 'gam_list_groups',
description: 'List all groups in the Google Workspace domain with optional filtering',
inputSchema: ListGroupsSchema,
handler: async (params: z.infer<typeof ListGroupsSchema>) => {
try {
const args = ['print', 'groups'];
if (params.domain) {
args.push('domain', params.domain);
}
if (params.maxResults) {
args.push('limit', params.maxResults.toString());
}
args.push('fields', 'email,name,description,memberCount,adminCreated');
const result = await gam.executeCommandWithCsv(args);
if (!result.success) {
return {
success: false,
error: result.error || 'Failed to list groups',
data: null
};
}
const groups = result.parsedData.map(group => ({
email: group['email'],
name: group['name'],
description: group['description'],
memberCount: parseInt(group['memberCount'] || '0', 10),
adminCreated: group['adminCreated'] === 'True'
}));
return {
success: true,
data: {
groups,
totalCount: groups.length,
executionTime: result.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};
/**
* Get detailed information about a specific group
*/
export const gam_get_group = {
name: 'gam_get_group',
description: 'Get detailed information about a specific group including members and settings',
inputSchema: GetGroupSchema,
handler: async (params: z.infer<typeof GetGroupSchema>) => {
try {
// Get basic group info
const groupArgs = ['show', 'group', params.groupEmail];
const groupResult = await gam.executeCommandWithCsv(groupArgs);
if (!groupResult.success) {
return {
success: false,
error: groupResult.error || 'Failed to get group information',
data: null
};
}
// Get group members
const membersArgs = ['print', 'group-members', 'group', params.groupEmail];
const membersResult = await gam.executeCommandWithCsv(membersArgs);
const groupData = groupResult.parsedData[0] || {};
const members = membersResult.success ? membersResult.parsedData : [];
return {
success: true,
data: {
email: groupData['email'],
name: groupData['name'],
description: groupData['description'],
memberCount: parseInt(groupData['memberCount'] || '0', 10),
adminCreated: groupData['adminCreated'] === 'True',
members: members.map(member => ({
email: member['email'],
role: member['role'],
type: member['type']
})),
executionTime: groupResult.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};
/**
* Create a new group in Google Workspace
*/
export const gam_create_group = {
name: 'gam_create_group',
description: 'Create a new group in Google Workspace with specified details',
inputSchema: CreateGroupSchema,
handler: async (params: z.infer<typeof CreateGroupSchema>) => {
try {
const args = ['create', 'group', params.groupEmail, 'name', params.groupName];
if (params.description) {
args.push('description', params.description);
}
const result = await gam.executeCommand(args);
if (!result.success) {
return {
success: false,
error: result.error || 'Failed to create group',
data: null
};
}
return {
success: true,
data: {
groupEmail: params.groupEmail,
message: 'Group created successfully',
executionTime: result.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};
/**
* Add a member to a group
*/
export const gam_add_group_member = {
name: 'gam_add_group_member',
description: 'Add a user as a member to a group with specified role',
inputSchema: GroupMemberSchema,
handler: async (params: z.infer<typeof GroupMemberSchema>) => {
try {
const args = ['add', 'group', params.groupEmail, 'member', params.memberEmail];
if (params.role) {
args.push('role', params.role);
}
const result = await gam.executeCommand(args);
if (!result.success) {
return {
success: false,
error: result.error || 'Failed to add member to group',
data: null
};
}
return {
success: true,
data: {
groupEmail: params.groupEmail,
memberEmail: params.memberEmail,
role: params.role || 'MEMBER',
message: 'Member added to group successfully',
executionTime: result.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};
/**
* Remove a member from a group
*/
export const gam_remove_group_member = {
name: 'gam_remove_group_member',
description: 'Remove a user from a group',
inputSchema: z.object({
groupEmail: GamSchemas.email,
memberEmail: GamSchemas.email
}),
handler: async (params: { groupEmail: string; memberEmail: string }) => {
try {
const args = ['remove', 'group', params.groupEmail, 'member', params.memberEmail];
const result = await gam.executeCommand(args);
if (!result.success) {
return {
success: false,
error: result.error || 'Failed to remove member from group',
data: null
};
}
return {
success: true,
data: {
groupEmail: params.groupEmail,
memberEmail: params.memberEmail,
message: 'Member removed from group successfully',
executionTime: result.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};
/**
* List all organizational units
*/
export const gam_list_orgunits = {
name: 'gam_list_orgunits',
description: 'List all organizational units in the Google Workspace domain',
inputSchema: ListOrgUnitsSchema,
handler: async (params: z.infer<typeof ListOrgUnitsSchema>) => {
try {
const args = ['print', 'orgunits'];
if (params.maxResults) {
args.push('limit', params.maxResults.toString());
}
args.push('fields', 'orgUnitPath,name,description,parentOrgUnitPath');
const result = await gam.executeCommandWithCsv(args);
if (!result.success) {
return {
success: false,
error: result.error || 'Failed to list org units',
data: null
};
}
const orgUnits = result.parsedData.map(ou => ({
orgUnitPath: ou['orgUnitPath'],
name: ou['name'],
description: ou['description'],
parentOrgUnitPath: ou['parentOrgUnitPath']
}));
return {
success: true,
data: {
orgUnits,
totalCount: orgUnits.length,
executionTime: result.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};
/**
* Get domain information and settings
*/
export const gam_get_domain_info = {
name: 'gam_get_domain_info',
description: 'Get domain information and settings for the Google Workspace domain',
inputSchema: DomainInfoSchema,
handler: async () => {
try {
const args = ['info', 'domain'];
const result = await gam.executeCommand(args);
if (!result.success) {
return {
success: false,
error: result.error || 'Failed to get domain information',
data: null
};
}
// Parse the domain info output
const lines = result.stdout.split('\n');
const domainInfo: Record<string, string> = {};
for (const line of lines) {
const [key, value] = line.split(':').map(s => s.trim());
if (key && value) {
domainInfo[key] = value;
}
}
return {
success: true,
data: {
domainInfo,
executionTime: result.executionTime
},
error: null
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
data: null
};
}
}
};