MCPManager: Missing timeout on future.result(), no thread-safety on clients dict, fragile shutdown

Author: jianyexiCreated Jun 7, 2026Updated Sep 4, 2026

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

  1. All uture.result() calls should have configurable timeouts (default 30s)
  2. self.clients dict should be protected with a hreading.Lock
  3. Shutdown should use proper synchronization instead of ime.sleep
  4. Tool execution should have a configurable timeout

Environment

  • Qwen-Agent: latest main branch
  • Python: 3.10+