Skip to main content
Glama
hbd

MCP Chat

by hbd

send_message

Send messages in chat conversations by specifying room ID, message content, and client ID. Use with wait_for_message to maintain real-time dialogue flow.

Instructions

Send a message to your chat partner.

IMPORTANT: After sending a message, you should immediately call wait_for_message to receive the response. This enables real-time conversation flow.

Typical usage:

  1. Call send_message to send your message

  2. Call wait_for_message to wait for the response

  3. Repeat

Args: room_id: The ID of the chat room message: The message to send client_id: Your client identifier (from enter_queue or join_room)

Returns: Success status or error information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
room_idYes
messageYes
client_idYes

Implementation Reference

  • The main handler function for the 'send_message' tool, decorated with @mcp.tool() for registration in FastMCP. It validates the user, room, and partner, creates a Message object, logs the action, and delivers the message via asyncio queues to waiting recipients, also sending a notification.
    @mcp.tool()
    async def send_message(room_id: str, message: str, client_id: str) -> Dict[str, Any]:
        """Send a message to your chat partner.
    
        IMPORTANT: After sending a message, you should immediately call wait_for_message
        to receive the response. This enables real-time conversation flow.
    
        Typical usage:
        1. Call send_message to send your message
        2. Call wait_for_message to wait for the response
        3. Repeat
    
        Args:
            room_id: The ID of the chat room
            message: The message to send
            client_id: Your client identifier (from enter_queue or join_room)
    
        Returns:
            Success status or error information
        """
        # Use the provided client_id
        connection_id = client_id
    
        # Get user
        user = connections.get(connection_id)
        if not user:
            logger.error(f"User not found for client_id: {client_id}")
            logger.debug(f"Active connections: {list(connections.keys())}")
            return {
                "success": False,
                "error": f"User not found. Invalid client_id: {client_id}",
            }
    
        # Get room
        room = await room_manager.get_room(room_id)
        if not room:
            return {"success": False, "error": "Room not found"}
    
        if not room.active:
            return {"success": False, "error": "Chat has ended"}
    
        # Verify user is in the room
        if not room.has_user(user.user_id):
            return {"success": False, "error": "You are not in this room"}
    
        # Get partner
        partner = room.get_partner(user.user_id)
        if not partner:
            return {"success": False, "error": "Partner not found"}
    
        # Create message
        msg = Message(room_id=room_id, sender_id=user.user_id, content=message)
    
        # Log message
        logger.info(f"Message from {user.name} to {partner.name}: {message[:50]}...")
    
        # Create message data
        message_data = {
            "content": message,
            "sender_name": user.name,
            "sender_id": user.user_id,
            "timestamp": msg.timestamp.isoformat(),
            "message_id": msg.message_id,
        }
    
        # Deliver to waiting recipients via message queues
        if room_id in message_queues:
            # Create a copy of items to avoid modification during iteration
            recipients = list(message_queues[room_id].items())
            for recipient_id, queue in recipients:
                if recipient_id != user.user_id:  # Don't send to self
                    try:
                        # Put message in queue (non-blocking)
                        queue.put_nowait(message_data)
                        logger.info(
                            f"Delivered message to waiting queue for {recipient_id}"
                        )
                    except asyncio.QueueFull:
                        logger.warning(f"Queue full for recipient {recipient_id}")
                    except Exception as e:
                        # Handle case where queue was closed/cancelled
                        logger.warning(f"Failed to deliver to {recipient_id}: {e}")
                        # Clean up the dead queue
                        if (
                            room_id in message_queues
                            and recipient_id in message_queues[room_id]
                        ):
                            del message_queues[room_id][recipient_id]
                            if not message_queues[room_id]:
                                del message_queues[room_id]
    
        # Still send notification for future notification support
        await send_notification(
            partner.connection_id,
            "message.received",
            {
                "room_id": room_id,
                "message": message,
                "sender": {"user_id": user.user_id, "display_name": user.name},
                "timestamp": msg.timestamp.isoformat(),
            },
        )
    
        return {
            "success": True,
            "message_id": msg.message_id,
            "timestamp": msg.timestamp.isoformat(),
        }
  • The @mcp.tool() decorator registers the send_message function as an MCP tool.
    @mcp.tool()
  • Function signature and docstring define the input schema (room_id: str, message: str, client_id: str) and output (Dict[str, Any]) for the tool.
    async def send_message(room_id: str, message: str, client_id: str) -> Dict[str, Any]:
        """Send a message to your chat partner.
    
        IMPORTANT: After sending a message, you should immediately call wait_for_message
        to receive the response. This enables real-time conversation flow.
    
        Typical usage:
        1. Call send_message to send your message
        2. Call wait_for_message to wait for the response
        3. Repeat
    
        Args:
            room_id: The ID of the chat room
            message: The message to send
            client_id: Your client identifier (from enter_queue or join_room)
    
        Returns:
            Success status or error information
        """
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes the tool's behavior in a conversational context, including the need for immediate follow-up with 'wait_for_message' and the real-time conversation flow. It mentions what the tool returns ('Success status or error information'), though it doesn't specify authentication needs, rate limits, or error conditions in detail.

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 well-structured with clear sections: purpose statement, important usage note with workflow, typical usage steps, parameter explanations, and return information. Every sentence adds value - the workflow guidance is particularly helpful, and there's no redundant or unnecessary content.

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

Completeness4/5

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

Given the tool's complexity (3 parameters, no annotations, no output schema), the description provides substantial context: clear purpose, detailed usage workflow, parameter semantics, and return information. It effectively compensates for the lack of structured metadata. The only minor gap is not specifying exact return formats or error details, but the workflow guidance makes this quite complete for its purpose.

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

Parameters4/5

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

With 0% schema description coverage (no parameter descriptions in the schema), the description compensates by explaining all three parameters: 'room_id: The ID of the chat room', 'message: The message to send', and 'client_id: Your client identifier (from enter_queue or join_room)'. The 'client_id' explanation even references sibling tools, adding valuable context. This significantly enhances understanding beyond the bare schema.

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 ('Send a message') and target ('to your chat partner'), providing a specific verb+resource combination. However, it doesn't explicitly distinguish this tool from potential sibling tools like 'join_room' or 'leave_chat' in terms of its messaging function versus room management functions.

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

Usage Guidelines5/5

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

The description provides explicit usage guidance with a numbered sequence (1-3) and specifically instructs to 'immediately call wait_for_message to receive the response.' It clearly indicates when to use this tool ('to send your message') and what to do after ('call wait_for_message'), creating a clear workflow pattern.

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/hbd/mcp-chat'

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