Skip to content
15 changes: 15 additions & 0 deletions core/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,21 @@ func (a *Agent) consumeJob(job *types.Job, role string) {

availableActions := a.getAvailableActionsForJob(job)
cogitoTools := availableActions.ToCogitoTools(job.GetContext(), a.sharedState)

mcpNeedsInit := false
for _, server := range a.mcpSessions {
err := server.Ping(a.context, &mcp.PingParams{})

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

while I like this, can we make it restart only the sessions which are unresponsive? it sounds safer to re-start only the MCP session which doesn't reply to Pings

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

while I like this, can we make it restart only the sessions which are unresponsive? it sounds safer to re-start only the MCP session which doesn't reply to Pings

Agree that would be better but the code to init the mcp actions is a bit tangled and would need a refactor which I don't have time to dig into at the moment given my level of experience with Golang. While I dug into the mcp library for a bit I couldn't find how to quickly re-establish connection in that context. Although again, given my level of experience in Golang this could easily be an oversight on my part.

I'm using this code now and it really solves my problem. Do you have any thoughts on the best way to restructure the initMcpActions to support the re-init of the individual connection? Before investing more time I want to make sure it's in line with your vision for the project.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

gotcha, I see. One way would be to simply collect the ones that don't respond to the ping and call Close on these individually. If you have issues just ping me, we can merge this otherwise and I would take over

@vugenti vugenti Feb 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I want to make sure that in case of transient connection failure, MCP server restart, or idle timeout that the agent would re-establish a new connection to the MCP server and have all tools available.

It seems like if we were just to call close on the misbehaving transports, we would be stuck with no easy way to re-intialize the session.

I guess the "correct" solution involves refactoring the initMCPActions into multiple methods and when the ping fails, close/remove the broken session and then re-initialize it individually and add it back into the mcpSessions.

Not sure when I would be able to address this but if you are ok merging this and keeping the issue open or having another issue to refactor and improve the efficiency later, I'd be happy to come back around to this at my next opportunity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@mudler I got around to refactoring the http mcp session handling and this is working for me

if err != nil {
mcpNeedsInit = true
xlog.Error("Error pinging MCP server, will re-initialize MCP actions", "error", err)
break
}
}

if mcpNeedsInit {
a.initMCPActions()
}

allActions := append(availableActions, a.mcpActionDefinitions...)

obs := job.Obs
Expand Down
2 changes: 2 additions & 0 deletions core/agent/mcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,6 @@ func (a *Agent) closeMCPServers() {
for _, s := range a.mcpSessions {
s.Close()
}

a.mcpSessions = []*mcp.ClientSession{}
}
Loading