Closed
Description
Hi, I’m currently encountering an issue where the addTool function blocks indefinitely due to a deadlock caused by the global mutex conflicting with another process. Only reproducible when my server is connected to a client already (In this case cursor MCP integration). While we could debate whether adding tools concurrently should even be possible, I saw that we already have mutex in place so I’m assuming this is an intentional design choice.
To resolve the issue, I suggest introducing dedicated mutexes for each tool, middleware, resource, session, etc., rather than relying on a single global one. This will avoid that we block each other. I’ve already prepared a PR that implements this approach. Let me know your thoughts.
Reproducible
// Add tools here ...
time.AfterFunc(5*time.Second, func() {
// Locked forever
s.server.AddTool(
mcp.NewTool(
"dummy_tool",
mcp.WithDescription("Dummy tool to trigger notifications"),
),
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
return nil, fmt.Errorf("dummy tool")
},
)
// never printed because of deadlock
fmt.Println("Dummy tool added")
})
Metadata
Metadata
Assignees
Labels
No labels