Repository navigation
fix: resolve memory leaks causing ~4GB memory growth - #30
Merged
Merged
Conversation
- Remove double process spawn for stdio MCP servers: StdioClientTransport already spawns its own child process, so the redundant SubprocessManager call was creating a second orphaned process per server. - Fix CapaMCPServer.close() to call mcpProxy.closeAll() before closing the MCP server, ensuring all client connections are properly released. - Eliminate leaked temporary CapaMCPServer instances in handleProjectConfigure and handleGetServerTools by reusing a shared getOrCreateMCPServer() helper that stores instances in the mcpServers Map. - Add onclose handlers to MCP clients so dead/disconnected entries are automatically removed from the clients cache.
Arguments passed via `capa sh --arg value` were always strings, causing MCP tool calls to fail when the schema expected number, integer, array, or object types. The new coerceValue() function handles: number, integer, boolean, array (comma-separated or JSON), and object (JSON). For arrays, item types are respected (e.g. array of numbers). When no schema type is declared, values are inferred from their content.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Analysis of a 3.7 GB memory dump revealed several critical memory leaks in the MCP server infrastructure that caused unbounded heap growth:
Double process spawn:
StdioClientTransportalready spawns its own child process internally, butMCPProxy.createStdioClient()was also callingSubprocessManager.getOrCreateSubprocess()— resulting in two processes per stdio MCP server. The first was orphaned and never cleaned up on shutdown.Leaked temporary
CapaMCPServerinstances:handleProjectConfigure(plugin enrichment + tool validation) andhandleGetServerToolscreated temporaryCapaMCPServerinstances with their ownMCPProxyand MCP client connections that were never closed. Each project reconfigure leaked more connections.close()not closing the proxy:CapaMCPServer.close()only closed the MCPServerbut never calledmcpProxy.closeAll(), leaking all client connections and their transport buffers.Changes
SubprocessManagerdependency fromMCPProxy— letStdioClientTransportmanage its own subprocess lifecyclegetOrCreateMCPServer()helper toCapaServerto centralizeCapaMCPServerinstance management and ensure reuse via themcpServersMapCapaMCPServer.close()to callmcpProxy.closeAll()before closing the serveronclosehandlers on MCP clients to auto-remove dead entries from the cacheTest plan
capaserver, configure a project with stdio MCP servers, verify tools still workMade with Cursor