Replies: 1 comment
|
For a stdio server, the reliable lifecycle signal is the transport closing (usually EOF/read error), not a signal from the MCP client. Claude Desktop and MCP Inspector do not need to send You can therefore keep the application lifecycle directly around func (s *Server) Run() error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
if err := s.start3pApplication(); err != nil {
return err
}
// Make this idempotent: it may also be called from an application-level
// shutdown path.
defer s.stop3pApplication()
err := s.Server.Run(ctx, &mcp.StdioTransport{})
if errors.Is(err, context.Canceled) || errors.Is(err, io.EOF) {
return nil
}
return err
}This removes the extra goroutine and If the peer keeps stdin open but simply stops sending messages, stdio has no protocol-level disconnect event, so no implementation can detect that immediately. In that case use an application-level timeout/heartbeat only if it matches your server semantics; do not use a short idle timeout for normal MCP clients. Relevant SDK code: |
Uh oh!
There was an error while loading. Please reload this page.
Pre-submission Checklist
Question Category
Your Question
Hi all,
I’m working with the Go SDK and the MCP protocol, and I’m trying to ensure my application state is properly cleaned up when the server disconnects or closes. Here’s a simplified version of my code:
Problem:
When I run this with go run and hit Ctrl+C, everything works as expected: stop3pApplication is called and cleanup happens.
However, when I run the same code via Claude Desktop or the MCP Inspector, stop3pApplication is never called. I suspect these tools are handling disconnects differently (not sending a signal?), so my cleanup code in defer isn’t triggered.
Question:
Any advice or pointers would be greatly appreciated!
All reactions