MCPManager: Missing timeout on future.result(), no thread-safety on clients dict, fragile shutdown
Bug Description
The MCPManager in qwen_agent/tools/mcp_manager.py has several reliability issues that can cause the Agent to hang indefinitely or behave unpredictably under concurrent usage.
Issue 1: No timeout on uture.result() calls
In MCPManager.initConfig() (line ~146) and ToolClass.call() (line ~280), uture.result() is called without a timeout:
`python
initConfig()
result = future.result() # No timeout — blocks forever if MCP server hangs
ToolClass.call()
result = future.result() # Same problem `
If an MCP server becomes unresponsive, the entire Agent will hang permanently with no way to recover.
Issue 2: No thread-safety on self.clients dict
The clients dict is accessed from multiple threads (the main thread and the asyncio event loop thread) without any synchronization primitive:
`python self.clients[client_id] = client # Written from main thread via initConfig() client = manager.clients[self.client_id] # Read from any calling thread
MCPClient.reconnect() also replaces entries
`
Under concurrent access, this can lead to KeyError or stale references.
Issue 3: Fragile shutdown with hardcoded ime.sleep(1)
python def shutdown(self): ... time.sleep(1) # Hardcoded wait — unreliable
The 1-second sleep is a guess that may not be sufficient for all cleanup tasks to complete.
Issue 4: Missing timeout on MCPClient.execute_function()
The xecute_function method calls self.session.call_tool() without a timeout, which can hang if the MCP server is slow or unresponsive.
Expected Behavior
- All uture.result() calls should have configurable timeouts (default 30s)
- self.clients dict should be protected with a hreading.Lock
- Shutdown should use proper synchronization instead of ime.sleep
- Tool execution should have a configurable timeout
Environment
- Qwen-Agent: latest main branch
- Python: 3.10+
Source: QwenLM/Qwen-Agent