44 "context"
55 "fmt"
66 "os"
7+ "strings"
78 "time"
89
910 mcpclient "github.com/mark3labs/mcp-go/client"
@@ -40,8 +41,6 @@ func (s *StdioAdapter) Connect(ctx context.Context) error {
4041 }
4142
4243 s .logf ("Connecting to MCP server via stdio: %s %v" , s .config .Command , s .config .Args )
43-
44- // Create stdio client
4544 client , err := mcpclient .NewStdioMCPClient (
4645 s .config .Command ,
4746 s .config .Env ,
@@ -51,21 +50,41 @@ func (s *StdioAdapter) Connect(ctx context.Context) error {
5150 return fmt .Errorf ("failed to create stdio client: %w" , err )
5251 }
5352
53+ // Log client for debugging
54+ s .logf ("Created stdio client: %+v" , client )
55+
5456 s .client = client
5557
58+ // Wait and check if process is still alive
59+ if err := s .waitForProcessReady (ctx ); err != nil {
60+ if closeErr := s .client .Close (); closeErr != nil {
61+ s .logf ("Warning: failed to close stdio client during cleanup: %v" , closeErr )
62+ }
63+ return err
64+ }
65+
5666 // Initialize the connection
5767 initRequest := mcp.InitializeRequest {}
5868 initRequest .Params .ProtocolVersion = mcp .LATEST_PROTOCOL_VERSION
5969 initRequest .Params .ClientInfo = mcp.Implementation {
6070 Name : "mcp-cli-adapter" ,
6171 Version : "1.0.0" ,
6272 }
73+ initRequest .Params .Capabilities = mcp.ClientCapabilities {
74+ Roots : & struct {
75+ ListChanged bool `json:"listChanged,omitempty"`
76+ }{
77+ ListChanged : true ,
78+ },
79+ }
6380
81+ s .logf ("Sending initialize request with timeout: %v" , s .config .Timeout )
6482 ctx , cancel := context .WithTimeout (ctx , s .config .Timeout )
6583 defer cancel ()
6684
6785 result , err := s .client .Initialize (ctx , initRequest )
6886 if err != nil {
87+ s .logf ("Initialize failed: %v" , err )
6988 if err := s .client .Close (); err != nil {
7089 // Log the error but don't return it since this is likely in a cleanup context
7190 fmt .Fprintf (os .Stderr , "Warning: failed to close stdio client: %v\n " , err )
@@ -190,3 +209,63 @@ func (s *StdioAdapter) GetPrompt(ctx context.Context, name string, arguments map
190209
191210 return result , nil
192211}
212+
213+ func (s * StdioAdapter ) waitForProcessReady (ctx context.Context ) error {
214+ s .logf ("Waiting for process to be ready..." )
215+
216+ // Check multiple times with increasing delays
217+ delays := []time.Duration {100 * time .Millisecond , 500 * time .Millisecond , 1 * time .Second }
218+
219+ for i , delay := range delays {
220+ select {
221+ case <- ctx .Done ():
222+ return ctx .Err ()
223+ case <- time .After (delay ):
224+ }
225+
226+ s .logf ("Process readiness check %d/%d" , i + 1 , len (delays ))
227+
228+ // Try a quick ping to see if process responds
229+ pingCtx , cancel := context .WithTimeout (ctx , 1 * time .Second )
230+ err := s .pingProcess (pingCtx )
231+ cancel ()
232+
233+ if err == nil {
234+ s .logf ("Process is ready!" )
235+ return nil
236+ }
237+
238+ if isProcessExitError (err ) {
239+ return fmt .Errorf ("process exited unexpectedly - check command '%s %v'" ,
240+ s .config .Command , s .config .Args )
241+ }
242+
243+ s .logf ("Process not ready yet (attempt %d): %v" , i + 1 , err )
244+ }
245+
246+ return fmt .Errorf ("process did not become ready within expected time" )
247+ }
248+
249+ func (s * StdioAdapter ) pingProcess (ctx context.Context ) error {
250+ // Send a minimal request to test if the process is alive and responding
251+ initRequest := mcp.InitializeRequest {}
252+ initRequest .Params .ProtocolVersion = mcp .LATEST_PROTOCOL_VERSION
253+ initRequest .Params .ClientInfo = mcp.Implementation {
254+ Name : "ping" ,
255+ Version : "1.0.0" ,
256+ }
257+
258+ _ , err := s .client .Initialize (ctx , initRequest )
259+ return err
260+ }
261+ func isProcessExitError (err error ) bool {
262+ if err == nil {
263+ return false
264+ }
265+ errStr := err .Error ()
266+ return strings .Contains (errStr , "process" ) ||
267+ strings .Contains (errStr , "exit" ) ||
268+ strings .Contains (errStr , "pipe" ) ||
269+ strings .Contains (errStr , "broken" ) ||
270+ strings .Contains (errStr , "EOF" )
271+ }
0 commit comments