Skip to main content
Glama
by hbd
long-polling-design.md5.65 kB
# Long-Polling Design for MCP Chat ## Concept Instead of using notifications (which require special client support), we use a blocking tool call that waits for incoming messages. This makes our chat server compatible with ANY MCP client. ## How It Works ``` User A Server User B | | | |-- send_message("Hello") ----->| | |<-- "Message sent" ------------| | | | | |-- wait_for_message() -------->| | | (blocks waiting...) |<----- send_message("Hi!") ---| |<-- {"message": "Hi!"} --------| | | | | |-- send_message("How are?") -->| | |<-- "Message sent" ------------| | | |<----- wait_for_message() ----| |-- wait_for_message() -------->| (blocks waiting...) | | (blocks waiting...) | | ``` ## New Tool Design ### `wait_for_message` - **Purpose**: Block until a message is received in the current chat room - **Parameters**: - `room_id`: The chat room to listen in - `timeout`: Optional timeout in seconds (default: 60) - **Returns**: - On success: `{"message": "text", "sender": "display_name", "timestamp": "..."}` - On timeout: `{"timeout": true, "message": "No message received"}` - On error: `{"error": "Not in room"}` or `{"error": "Partner disconnected"}` ## Implementation Approach ```python @mcp.tool() async def wait_for_message(room_id: str, timeout: int = 60) -> Dict[str, Any]: """Wait for a message in the chat room (long-polling).""" # Get user and validate room user = connections.get(connection_id) room = await room_manager.get_room(room_id) # Create a message queue for this user message_queue = asyncio.Queue() # Register the queue to receive messages if room_id not in message_queues: message_queues[room_id] = {} message_queues[room_id][user.user_id] = message_queue try: # Wait for a message with timeout message = await asyncio.wait_for( message_queue.get(), timeout=timeout ) return { "message": message["content"], "sender": message["sender_name"], "timestamp": message["timestamp"] } except asyncio.TimeoutError: return {"timeout": True, "message": "No message received"} finally: # Clean up queue registration if room_id in message_queues: message_queues[room_id].pop(user.user_id, None) ``` ## Modified `send_message` Tool ```python @mcp.tool() async def send_message(room_id: str, message: str) -> Dict[str, Any]: """Send a message and notify waiting recipients.""" # ... validation ... # Create message object msg = { "content": message, "sender_name": user.name, "sender_id": user.user_id, "timestamp": datetime.now().isoformat() } # Deliver to all waiting recipients in the room if room_id in message_queues: for recipient_id, queue in message_queues[room_id].items(): if recipient_id != user.user_id: # Don't send to self await queue.put(msg) return {"success": True, "sent_at": msg["timestamp"]} ``` ## Client Usage (Works with ANY MCP Client!) ### Using FastMCP Dev Client ```bash # Terminal 1 - Alice > call enter_queue {"display_name": "Alice"} # Get room_id when matched > call send_message {"room_id": "abc-123", "message": "Hello Bob!"} > call wait_for_message {"room_id": "abc-123"} # Blocks until Bob responds... # {"message": "Hi Alice!", "sender": "Bob", "timestamp": "..."} > call send_message {"room_id": "abc-123", "message": "How are you?"} > call wait_for_message {"room_id": "abc-123"} # Continues conversation... ``` ### Using Standard HTTP/curl ```bash # Send message curl -X POST http://localhost:8000/mcp/v1/tools/call \ -d '{"method": "send_message", "params": {"room_id": "abc", "message": "Hello!"}}' # Wait for response (this blocks!) curl -X POST http://localhost:8000/mcp/v1/tools/call \ -d '{"method": "wait_for_message", "params": {"room_id": "abc"}}' ``` ## Advantages 1. **Universal Compatibility**: Works with ANY MCP client 2. **Simple Implementation**: No complex notification system needed 3. **Natural Flow**: Mimics request-response pattern 4. **No Special Client**: Can even use curl! 5. **Timeout Control**: Clients can specify how long to wait ## Considerations 1. **Blocking Calls**: Client is blocked while waiting (but that's the point!) 2. **Connection Management**: Need to handle dropped connections gracefully 3. **Multiple Messages**: Might need a `get_messages` tool for history 4. **Timeout Handling**: Clients need to retry after timeout ## Enhanced Tool Set 1. `enter_queue` - Join queue 2. `send_message` - Send a message 3. `wait_for_message` - Wait for incoming message (blocking) 4. `get_messages` - Get recent message history (non-blocking) 5. `leave_chat` - Leave the chat ## Migration Path 1. Keep existing notification system (for future use) 2. Add message queue management 3. Implement `wait_for_message` tool 4. Update `send_message` to deliver to queues 5. Test with various clients This approach is much simpler and more compatible than building a custom client!

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