Skip to main content
Glama
abutbul

Gatherings MCP Server

by abutbul

add_member

Add a new member to a gathering by specifying the gathering ID and member name to include participants in expense tracking and reimbursement calculations.

Instructions

Add a new member to a gathering

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
gathering_idYesID of the gathering
member_nameYesName of the member to add

Implementation Reference

  • src/index.ts:217-234 (registration)
    Registration of the 'add_member' MCP tool, defining its metadata and input schema.
    {
      name: 'add_member',
      description: 'Add a new member to a gathering',
      inputSchema: {
        type: 'object',
        properties: {
          gathering_id: {
            type: 'string',
            description: 'ID of the gathering',
          },
          member_name: {
            type: 'string',
            description: 'Name of the member to add',
          },
        },
        required: ['gathering_id', 'member_name'],
      },
    },
  • Handler for the 'add_member' tool call in the MCP server. Validates arguments and constructs the Python CLI command to execute the operation.
    case 'add_member':
      if (!isMemberArgs(args)) {
        throw new McpError(ErrorCode.InvalidParams, 'Invalid add_member arguments');
      }
      command += ` add-member "${args.gathering_id}" "${args.member_name}"`;
      break;
  • Type guard helper function used to validate input arguments for the 'add_member' tool.
    const isMemberArgs = (args: any): args is { gathering_id: string; member_name: string } =>
      typeof args === 'object' && args !== null &&
      typeof args.gathering_id === 'string' &&
      typeof args.member_name === 'string';
  • Core implementation of adding a member in the database layer (DatabaseManager.add_member), called by the service.
    def add_member(self, gathering_id: str, member_name: str) -> Member:
        """
        Add a member to a gathering.
        
        Args:
            gathering_id: The ID of the gathering
            member_name: The name of the member
            
        Returns:
            The created Member object
            
        Raises:
            ValueError: If the gathering doesn't exist or is closed, or the member already exists
        """
        session = self.Session()
        try:
            # Get the gathering
            gathering = session.query(Gathering).filter_by(id=gathering_id).first()
            if not gathering:
                raise ValueError(f"Gathering '{gathering_id}' not found")
            
            # Check if gathering is open
            if gathering.status == GatheringStatus.CLOSED:
                raise ValueError(f"Cannot add member to closed gathering '{gathering_id}'")
            
            # Check if member already exists
            existing_member = session.query(Member).filter_by(gathering_id=gathering_id, name=member_name).first()
            if existing_member:
                raise ValueError(f"Member '{member_name}' already exists in gathering '{gathering_id}'")
            
            # Create the member
            member = Member(name=member_name, gathering_id=gathering_id)
            session.add(member)
            
            # Update the total members count
            gathering.total_members += 1
            
            session.commit()
            return member
            
        except Exception as e:
            session.rollback()
            raise e
        finally:
            session.close()
  • Service layer wrapper for add_member, delegates to DB manager and retrieves updated gathering.
    def add_member(self, gathering_id: str, member_name: str) -> Tuple[Gathering, Member]:
        """
        Add a new member to an existing gathering.
        
        Args:
            gathering_id: The ID of the gathering
            member_name: The name of the member to add
            
        Returns:
            Tuple of (updated Gathering, added Member)
            
        Raises:
            ValueError: If the gathering is closed, doesn't exist, or member already exists
        """
        member = self.db_manager.add_member(gathering_id, member_name)
        gathering = self.get_gathering(gathering_id)
        return gathering, member
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states the basic action without disclosing behavioral traits. It doesn't mention permissions needed, whether the addition is reversible, error conditions (e.g., duplicate names), or effects on the gathering, which are critical for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste, front-loading the core action. It's appropriately sized for the tool's simplicity, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description is incomplete. It lacks details on behavioral aspects (e.g., success/failure responses, side effects) and doesn't compensate for the missing structured data, leaving gaps in understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, so parameters are fully documented in the schema. The description adds no meaning beyond the schema, such as format examples or constraints, but meets the baseline since the schema handles the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Add') and target ('a new member to a gathering'), making the purpose understandable. However, it doesn't differentiate from sibling tools like 'rename_member' or 'remove_member' beyond the basic verb, missing specific distinctions about scope or effect.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'rename_member' or 'remove_member'. The description lacks context about prerequisites (e.g., if the gathering must be open) or exclusions, leaving usage ambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/abutbul/gatherings-mcp'

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