Skip to content

Fix: Improve Custom MCP node performance by caching toolkits#4809

Closed
toi500 wants to merge 9 commits into
FlowiseAI:mainfrom
toi500:fix-2
Closed

Fix: Improve Custom MCP node performance by caching toolkits#4809
toi500 wants to merge 9 commits into
FlowiseAI:mainfrom
toi500:fix-2

Conversation

@toi500

@toi500 toi500 commented Jul 7, 2025

Copy link
Copy Markdown
Contributor

As discussed, this PR fixes a critical performance issue in the Custom MCP node caused by redundant process spawning. The STDIO transport is re-spawning a child process on every UI refresh, leading to significant overhead.

Solution:

This is a single file solution implemented entirely within customMCP.ts.

  1. A static toolkitCache is used to store and reuse MCPToolkit instances, preventing the expensive process creation on every refresh.
  2. The cache key is generated by parsing the mcpServerConfig JSON. This makes the cache immune to formatting differences (spaces, newlines) and prevents spawning duplicate processes for the same logical configuration.

chrome_6CVrqvDHHL

Trade-off:

Since we are not modifying core.ts and the node's destroy() method has proven unreliable for cleanup (I have tried to implement it without any success), this solution will leak one process per unique server configuration. This is a necessary trade-off to fix the critical performance issue immediately while keeping the changes isolated to this single file.

@toi500

toi500 commented Jul 7, 2025

Copy link
Copy Markdown
Contributor Author

@HenryHengZJ, this is working very well for me now, very smooth.

I really hope you can find a solution to flush the cache when the custom node is deleted. I tried to implement this myself but without any success.

I will definitely be keeping this change for my own use, as it is much better to have a minor memory leak (especially since the current MCP implementation has some leaks anyway) than to have the constant process churn overload my server and force me to spend 20 minutes filling in actions on a single MCP node.

@HenryHengZJ HenryHengZJ requested a review from Copilot July 9, 2025 08:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Implements caching for MCPToolkit instances to eliminate redundant process spawning on UI refresh, boosting performance.

  • Introduces a static toolkitCache keyed by workspace, parsed config, and sandbox.
  • Parses and canonicalizes mcpServerConfig to generate consistent cache keys.
  • Clears out invalid mcpActions after loading a new toolkit to keep the UI in sync.
Comments suppressed due to low confidence (1)

packages/components/nodes/tools/MCP/CustomMCP/CustomMCP.ts:161

  • Add unit tests to verify that cached toolkits are returned correctly and that the stale-action clearing logic behaves as expected to prevent regressions.
        if (Custom_MCP.toolkitCache.has(cacheKey)) {

Comment thread packages/components/nodes/tools/MCP/CustomMCP/CustomMCP.ts
@ahmedrowaihi

Copy link
Copy Markdown
Contributor

does this takes care of tool availability changes ? when custom mcps are used via npx the mcp tools might change ( which is desired if user wants new version of that mcp server ), but I wonder this cache will not affect that ?

@toi500

toi500 commented Jul 10, 2025

Copy link
Copy Markdown
Contributor Author

does this takes care of tool availability changes ? when custom mcps are used via npx the mcp tools might change ( which is desired if user wants new version of that mcp server ), but I wonder this cache will not affect that ?

Not sure if I am following you here. Every time you add a version, it uses a new mcpServerConfig, and you will fetch whatever actions that version has. That version is then cached until Flowise restarts.

If what you mean is that you will lose the convenience of using "@latest" in some cases, it is a trade-off I would definitely pay for not spinning up the same server 10 times to add 10 actions and spending 10 minutes on it.

image

@toi500

toi500 commented Jul 11, 2025

Copy link
Copy Markdown
Contributor Author
image

@toi500 toi500 marked this pull request as ready for review July 11, 2025 14:46
@toi500

toi500 commented Jul 16, 2025

Copy link
Copy Markdown
Contributor Author

@HenryHengZJ, this PR is ready to review. I have tested it properly, and it works in every edge scenario I thought of. I added it as an option so it may solve any extreme scenario.

Since you pointed out that this cache approach is not compatible with Flowise Cloud and it makes sense more for self-hosted users only, I have also added a flag for queue mode, so on MODE=queue the cache is to be auto-disabled and the UI option hidden.

If you test this on queue mode, the node should work as it does right now (no cache involved, no "Disable Cache" option visible).

@HenryHengZJ

HenryHengZJ commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@toi500 I've been thinking about this and trying to see if I can find an optimal way for both cloud and self hosted users.

I found a better solution for self hosted:
1.) We already have a centralize cache called CachePool which we can reuse
2.) I've hashed the workspaceId and canonicalConfig as the key of the cache, so we can reduce the byte size

For flowise cloud users in QUEUE mode, unfortunately we can't store the toolkit classes into Redis, so its not achievable.

Reason of using centralized CachePool allow us to separate behaviour when using QUEUE mode or normal, and also prevent memory leakage and maximum heap error

Can you try this branch: https://github.com/FlowiseAI/Flowise/tree/bugfix/Custom-MCP-Cache

I've tried multiple times and it works

@toi500

toi500 commented Jul 18, 2025

Copy link
Copy Markdown
Contributor Author

@HenryHengZJ, that makes sense. I just tried it, and it works for me too.

@HenryHengZJ

Copy link
Copy Markdown
Contributor

PR opened here: #4897

@toi500 toi500 closed this Jul 18, 2025
@toi500 toi500 deleted the fix-2 branch July 18, 2025 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants