wooden-umbrella-84098
03/30/2026, 1:40 PMlimited-student-10747
03/30/2026, 1:52 PMnutritious-balloon-65098
03/30/2026, 1:53 PMnutritious-balloon-65098
03/30/2026, 1:58 PMsoftware-agent-sdk, expanded the original comment into a concrete analysis, and recorded it as a GitHub issue:
- Issue filed: OpenHands/software-agent-sdk#2603
- Link: https://github.com/OpenHands/software-agent-sdk/issues/2603
### Summary of the answer
The problem appears to be both architectural and behavioral:
- Architectural: MCP config is currently effectively conversation-owned.
- RemoteConversation sends the full agent, including agent.mcp_config, to /api/conversations.
- On first real use, LocalConversation → AgentBase._initialize() → create_mcp_tools(...) creates a new MCPClient per conversation.
- Plugin .mcp.json ends up merged into the same agent.mcp_config, so it follows the same path.
- Result: many conversations with the same Slack MCP config can legitimately create many MCP instances.
- Behavioral / cleanup bugs: teardown is not reliably closing MCP clients.
- EventService.close() schedules self._conversation.close in an executor but does not await it.
- LocalConversation.close() calls executor.close() on tool executors, but MCPToolExecutor does not implement close(), so MCP cleanup is effectively a no-op.
- This makes it plausible for MCP subprocesses/connections to survive conversation deletion or server shutdown.
### Suggested changes captured in the issue
- Short-term bugfixes
- Await conversation cleanup in EventService.close()
- Implement MCPToolExecutor.close() to call MCPClient.sync_close()
- Add delete/shutdown tests for MCP cleanup
- Medium-term design
- Move toward a server-managed MCP lifecycle
- Add separate MCP management/persistence endpoints/resources
- Let conversations reference managed MCP resources instead of always owning inline MCP config
- PR #2361 consideration
- The upcoming typed settings model (AgentSettings.mcp_config: MCPConfig | None) should be treated as the canonical schema
- Runtime MCP management should build on that, rather than inventing a second config shape
Since this was an investigation/request-for-analysis task, no local code changes were made.