// Copyright 2025 The Go MCP SDK Authors. All rights reserved. // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. //go:build go1.25 package mcp_test import ( "context" "errors" "testing" "testing/synctest" "github.com/modelcontextprotocol/go-sdk/mcp" ) func TestServerRunContextCancel_Synctest(t *testing.T) { synctest.Test(t, func(t *testing.T) { server := mcp.NewServer(&mcp.Implementation{Name: "greeter", Version: "v0.0.1"}, nil) mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi) ctx, cancel := context.WithCancel(context.Background()) defer cancel() serverTransport, clientTransport := mcp.NewInMemoryTransports() // run the server and capture the exit error onServerExit := make(chan error) go func() { onServerExit <- server.Run(ctx, serverTransport) }() // send a ping to the server to ensure it's running client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil) session, err := client.Connect(ctx, clientTransport, nil) if err != nil { t.Fatal(err) } t.Cleanup(func() { session.Close() }) if err := session.Ping(context.Background(), nil); err != nil { t.Fatal(err) } // cancel the context to stop the server cancel() // wait for the server to exit err = <-onServerExit if !errors.Is(err, context.Canceled) { t.Fatalf("server did not exit after context cancellation, got error: %v", err) } }) }