Skip to main content
Glama
hi5d
by hi5d

book_seats

Reserve seats for AMC movie showtimes by providing showtime ID, seat numbers, and user ID to confirm bookings.

Instructions

Reserves selected seats for the user.

Args: showtime_id: Showtime ID (e.g., "st001") seats: List of seat numbers (e.g., ["A5", "A6"]) user_id: User identifier

Returns: JSON string with booking confirmation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
showtime_idYes
seatsYes
user_idYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary handler for the book_seats tool in the standard MCP server. Validates input, checks seat availability by cross-referencing seats data and existing confirmed bookings, computes total price, creates a pending Booking object, stores it, and returns detailed JSON response.
    async def _book_seats(self, args: Dict[str, Any]) -> CallToolResult:
        """Book seats for a showtime"""
        showtime_id = args.get("showtime_id")
        seats = args.get("seats", [])
        user_id = args.get("user_id")
        
        if not showtime_id or showtime_id not in self.showtimes:
            return CallToolResult(
                content=[TextContent(type="text", text=json.dumps({"error": "Invalid showtime ID"}))]
            )
        
        if not seats or not user_id:
            return CallToolResult(
                content=[TextContent(type="text", text=json.dumps({"error": "Seats and user_id are required"}))]
            )
        
        # Check seat availability
        unavailable_seats = []
        total_price = 0.0
        
        showtime_seats = self.seats_data.get(showtime_id, [])
        seat_lookup = {s["seat_number"]: s for s in showtime_seats}
        
        for seat_num in seats:
            # Check if seat exists
            if seat_num not in seat_lookup:
                unavailable_seats.append(f"{seat_num} (doesn't exist)")
                continue
            
            # Check if already booked
            is_booked = any(
                seat_num in booking.seats and booking.status == "confirmed"
                for booking in self.bookings.values()
                if booking.showtime_id == showtime_id
            )
            
            if is_booked:
                unavailable_seats.append(f"{seat_num} (already booked)")
            else:
                seat_price = seat_lookup[seat_num].get("price", 15.00)
                total_price += seat_price
        
        if unavailable_seats:
            return CallToolResult(
                content=[TextContent(type="text", text=json.dumps({"error": f"Unavailable seats: {', '.join(unavailable_seats)}"}))]
            )
        
        # Create booking
        booking_id = str(uuid.uuid4())
        booking = Booking(
            booking_id=booking_id,
            showtime_id=showtime_id,
            seats=seats,
            user_id=user_id,
            status="pending",
            total_price=total_price,
            created_at=datetime.now().isoformat()
        )
        
        self.bookings[booking_id] = booking
        
        showtime = self.showtimes[showtime_id]
        theater = self.theaters.get(showtime.theater_id)
        movie = self.movies.get(showtime.movie_id)
        
        result = {
            "booking_id": booking_id,
            "status": "pending",
            "movie": movie.title if movie else "Unknown",
            "theater": theater.name if theater else "Unknown Theater",
            "date": showtime.date,
            "time": showtime.time,
            "seats": seats,
            "total_price": total_price
        }
        
        return CallToolResult(
            content=[TextContent(type="text", text=json.dumps(result, indent=2))]
        )
  • Tool registration in the list_tools handler, defining name, description, and input schema for book_seats.
    Tool(
        name="book_seats",
        description="Reserves selected seats for the user",
        inputSchema={
            "type": "object",
            "properties": {
                "showtime_id": {"type": "string", "description": "Showtime ID"},
                "seats": {"type": "array", "items": {"type": "string"}, "description": "List of seat numbers (e.g., ['A5', 'A6'])"},
                "user_id": {"type": "string", "description": "User identifier"}
            },
            "required": ["showtime_id", "seats", "user_id"]
        }
    ),
  • Core handler logic for book_seats in the FastMCP server implementation. Identical logic to the standard server: input validation, seat availability check, booking creation.
    def _book_seats(showtime_id: str, seats: List[str], user_id: str) -> str:
        """Internal implementation of book_seats"""
        if not showtime_id or showtime_id not in showtimes:
            return json.dumps({"error": "Invalid showtime ID"})
        
        if not seats or not user_id:
            return json.dumps({"error": "Seats and user_id are required"})
        
        # Check seat availability
        unavailable_seats = []
        total_price = 0.0
        
        showtime_seats = seats_data.get(showtime_id, [])
        seat_lookup = {s["seat_number"]: s for s in showtime_seats}
        
        for seat_num in seats:
            # Check if seat exists
            if seat_num not in seat_lookup:
                unavailable_seats.append(f"{seat_num} (doesn't exist)")
                continue
            
            # Check if already booked
            is_booked = any(
                seat_num in booking.seats and booking.status == "confirmed"
                for booking in bookings.values()
                if booking.showtime_id == showtime_id
            )
            
            if is_booked:
                unavailable_seats.append(f"{seat_num} (already booked)")
            else:
                seat_price = seat_lookup[seat_num].get("price", 15.00)
                total_price += seat_price
        
        if unavailable_seats:
            return json.dumps({"error": f"Unavailable seats: {', '.join(unavailable_seats)}"})
        
        # Create booking
        booking_id = str(uuid.uuid4())
        booking = Booking(
            booking_id=booking_id,
            showtime_id=showtime_id,
            seats=seats,
            user_id=user_id,
            status="pending",
            total_price=total_price,
            created_at=datetime.now().isoformat()
        )
        
        bookings[booking_id] = booking
        
        showtime = showtimes[showtime_id]
        theater = theaters.get(showtime.theater_id)
        movie = movies.get(showtime.movie_id)
        
        result = {
            "booking_id": booking_id,
            "status": "pending",
            "movie": movie.title if movie else "Unknown",
            "theater": theater.name if theater else "Unknown Theater",
            "date": showtime.date,
            "time": showtime.time,
            "seats": seats,
            "total_price": total_price
        }
        
        return json.dumps(result, indent=2)
  • FastMCP tool registration and wrapper handler for book_seats, which delegates to the internal _book_seats implementation.
    def book_seats(showtime_id: str, seats: List[str], user_id: str) -> str:
        """
        Reserves selected seats for the user.
        
        Args:
            showtime_id: Showtime ID (e.g., "st001")
            seats: List of seat numbers (e.g., ["A5", "A6"])
            user_id: User identifier
        
        Returns:
            JSON string with booking confirmation
        """
        return _book_seats(showtime_id, seats, user_id)
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. While 'Reserves' implies a write/mutation operation, it doesn't specify permissions required, whether reservations are reversible, rate limits, or what happens on failure (e.g., seat conflicts). The return format is mentioned but lacks detail on error cases or confirmation structure.

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

Conciseness4/5

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

The description is appropriately sized and well-structured with clear sections (purpose, Args, Returns). The purpose statement is front-loaded, and each sentence adds value. Minor verbosity in repeating 'JSON string' could be trimmed, but overall it's efficient.

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

Completeness3/5

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

Given 3 parameters with 0% schema coverage, no annotations, and an output schema exists (though unspecified), the description provides basic purpose and parameter examples but lacks critical context. It doesn't cover error handling, dependencies on other tools, or behavioral traits needed for safe invocation. The output schema existence reduces burden, but gaps remain for a mutation tool.

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?

Schema description coverage is 0%, so the schema provides no parameter documentation. The description adds basic semantics by naming parameters and giving examples (e.g., 'st001', ['A5', 'A6']), which helps understand what each parameter represents. However, it doesn't explain format constraints (e.g., seat numbering scheme) or validation rules, leaving gaps.

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 tool's purpose with a specific verb ('Reserves') and resource ('selected seats'), making it immediately understandable. However, it doesn't explicitly differentiate from sibling tools like 'process_payment' which might handle payment aspects of booking, leaving some ambiguity about the scope of this reservation operation.

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?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing seat availability from 'get_seat_map' first), nor does it clarify if this is the final booking step or if 'process_payment' should follow. There's no explicit when/when-not guidance or alternative tool references.

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/hi5d/amc-mcp'

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