11using  ModelContextProtocol . Client ; 
2- using  ModelContextProtocol . Configuration ; 
3- using  ModelContextProtocol . Protocol . Messages ; 
4- using  ModelContextProtocol . Protocol . Transport ; 
5- using  ModelContextProtocol . Protocol . Types ; 
62using  Microsoft . Extensions . AI ; 
73using  OpenAI ; 
4+ using  ModelContextProtocol . Protocol . Types ; 
5+ using  ModelContextProtocol . Protocol . Messages ; 
86using  System . Text . Json ; 
7+ using  ModelContextProtocol . Configuration ; 
8+ using  ModelContextProtocol . Protocol . Transport ; 
9+ using  Xunit . Sdk ; 
910
1011namespace  ModelContextProtocol . Tests ; 
1112
@@ -61,8 +62,8 @@ public async Task ListTools_Stdio(string clientId)
6162
6263        // act 
6364        await  using  var  client  =  await  _fixture . CreateClientAsync ( clientId ) ; 
64-         var  tools  =  await  client . ListToolsAsync ( ) . ToListAsync ( ) ; 
65-         var  aiFunctions  =  await  client . GetAIFunctionsAsync ( ) ; 
65+         var  tools  =  await  client . ListToolsAsync ( TestContext . Current . CancellationToken ) . ToListAsync ( TestContext . Current . CancellationToken ) ; 
66+         var  aiFunctions  =  await  client . GetAIFunctionsAsync ( TestContext . Current . CancellationToken ) ; 
6667
6768        // assert 
6869        Assert . NotEmpty ( tools ) ; 
@@ -102,9 +103,9 @@ public async Task CallTool_Stdio_ViaAIFunction_EchoServer(string clientId)
102103
103104        // act 
104105        await  using  var  client  =  await  _fixture . CreateClientAsync ( clientId ) ; 
105-         var  aiFunctions  =  await  client . GetAIFunctionsAsync ( ) ; 
106+         var  aiFunctions  =  await  client . GetAIFunctionsAsync ( TestContext . Current . CancellationToken ) ; 
106107        var  echo  =  aiFunctions . Single ( t =>  t . Name  ==  "echo" ) ; 
107-         var  result  =  await  echo . InvokeAsync ( [ new  KeyValuePair < string ,  object ? > ( "message" ,  "Hello MCP!" ) ] ) ; 
108+         var  result  =  await  echo . InvokeAsync ( [ new  KeyValuePair < string ,  object ? > ( "message" ,  "Hello MCP!" ) ] ,   TestContext . Current . CancellationToken ) ; 
108109
109110        // assert 
110111        Assert . NotNull ( result ) ; 
@@ -119,7 +120,7 @@ public async Task ListPrompts_Stdio(string clientId)
119120
120121        // act 
121122        await  using  var  client  =  await  _fixture . CreateClientAsync ( clientId ) ; 
122-         var  prompts  =  await  client . ListPromptsAsync ( ) . ToListAsync ( ) ; 
123+         var  prompts  =  await  client . ListPromptsAsync ( TestContext . Current . CancellationToken ) . ToListAsync ( TestContext . Current . CancellationToken ) ; 
123124
124125        // assert 
125126        Assert . NotEmpty ( prompts ) ; 
@@ -251,7 +252,7 @@ public async Task SubscribeResource_Stdio()
251252        await  client . SubscribeToResourceAsync ( "test://static/resource/1" ,  CancellationToken . None ) ; 
252253
253254        // notifications happen every 5 seconds, so we wait for 10 seconds to ensure we get at least one notification 
254-         await  Task . Delay ( 10000 ) ; 
255+         await  Task . Delay ( 10000 ,   TestContext . Current . CancellationToken ) ; 
255256
256257        // assert 
257258        Assert . True ( counter  >  0 ) ; 
@@ -276,17 +277,17 @@ public async Task UnsubscribeResource_Stdio()
276277        await  client . SubscribeToResourceAsync ( "test://static/resource/1" ,  CancellationToken . None ) ; 
277278
278279        // notifications happen every 5 seconds, so we wait for 10 seconds to ensure we get at least one notification 
279-         await  Task . Delay ( 10000 ) ; 
280+         await  Task . Delay ( 10000 ,   TestContext . Current . CancellationToken ) ; 
280281
281282        // reset counter 
282283        int  counterAfterSubscribe  =  counter ; 
283-          
284+ 
284285        // unsubscribe 
285286        await  client . UnsubscribeFromResourceAsync ( "test://static/resource/1" ,  CancellationToken . None ) ; 
286287        counter  =  0 ; 
287288
288289        // notifications happen every 5 seconds, so we wait for 10 seconds to ensure we would've gotten at least one notification 
289-         await  Task . Delay ( 10000 ) ; 
290+         await  Task . Delay ( 10000 ,   TestContext . Current . CancellationToken ) ; 
290291
291292        // assert 
292293        Assert . True ( counterAfterSubscribe  >  0 ) ; 
@@ -340,7 +341,7 @@ public async Task GetCompletion_Stdio_PromptReference(string clientId)
340341    [ Theory ] 
341342    [ MemberData ( nameof ( GetClients ) ) ] 
342343    public  async  Task  Sampling_Stdio ( string  clientId ) 
343-     {     
344+     { 
344345        // Set up the sampling handler 
345346        int  samplingHandlerCalls  =  0 ; 
346347        await  using  var  client  =  await  _fixture . CreateClientAsync ( clientId ,  new ( ) 
@@ -375,8 +376,8 @@ public async Task Sampling_Stdio(string clientId)
375376            { 
376377                [ "prompt" ]  =  "Test prompt" , 
377378                [ "maxTokens" ]  =  100 
378-             } 
379-         ) ; 
379+             } , 
380+              TestContext . Current . CancellationToken ) ; 
380381
381382        // assert 
382383        Assert . NotNull ( result ) ; 
@@ -423,8 +424,8 @@ public async Task Notifications_Stdio(string clientId)
423424        await  using  var  client  =  await  _fixture . CreateClientAsync ( clientId ) ; 
424425
425426        // Verify we can send notifications without errors 
426-         await  client . SendNotificationAsync ( NotificationMethods . RootsUpdatedNotification ) ; 
427-         await  client . SendNotificationAsync ( "test/notification" ,  new  {  test  =  true  } ) ; 
427+         await  client . SendNotificationAsync ( NotificationMethods . RootsUpdatedNotification ,   cancellationToken :   TestContext . Current . CancellationToken ) ; 
428+         await  client . SendNotificationAsync ( "test/notification" ,  new  {  test  =  true  } ,   TestContext . Current . CancellationToken ) ; 
428429
429430        // assert 
430431        // no response to check, if no exception is thrown, it's a success 
@@ -452,13 +453,13 @@ public async Task CallTool_Stdio_MemoryServer()
452453            ClientInfo  =  new ( )  {  Name  =  "IntegrationTestClient" ,  Version  =  "1.0.0"  } 
453454        } ; 
454455
455-         await  using  var  client  =  await  McpClientFactory . CreateAsync ( serverConfig ,  clientOptions ,  loggerFactory :  _fixture . LoggerFactory ) ; 
456+         await  using  var  client  =  await  McpClientFactory . CreateAsync ( serverConfig ,  clientOptions ,  loggerFactory :  _fixture . LoggerFactory ,   cancellationToken :   TestContext . Current . CancellationToken ) ; 
456457
457458        // act 
458459        var  result  =  await  client . CallToolAsync ( 
459460            "read_graph" , 
460-             [ ] 
461-         ) ; 
461+             [ ] , 
462+              TestContext . Current . CancellationToken ) ; 
462463
463464        // assert 
464465        Assert . NotNull ( result ) ; 
@@ -471,14 +472,11 @@ public async Task CallTool_Stdio_MemoryServer()
471472    [ Fact ] 
472473    public  async  Task  GetAIFunctionsAsync_UsingEverythingServer_ToolsAreProperlyCalled ( ) 
473474    { 
474-         if  ( s_openAIKey  is  null ) 
475-         { 
476-             return ;  // Skip the test if the OpenAI key is not provided 
477-         } 
475+         SkipTestIfNoOpenAIKey ( ) ; 
478476
479477        // Get the MCP client and tools from it. 
480-         await  using  var  client  =  await  McpClientFactory . CreateAsync ( _fixture . EverythingServerConfig ,  _fixture . DefaultOptions ) ;   ; 
481-         var  mappedTools  =  await  client . GetAIFunctionsAsync ( ) ; 
478+         await  using  var  client  =  await  McpClientFactory . CreateAsync ( _fixture . EverythingServerConfig ,  _fixture . DefaultOptions ,   cancellationToken :   TestContext . Current . CancellationToken ) ; 
479+         var  mappedTools  =  await  client . GetAIFunctionsAsync ( TestContext . Current . CancellationToken ) ; 
482480
483481        // Create the chat client. 
484482        using  IChatClient  chatClient  =  new  OpenAIClient ( s_openAIKey ) . AsChatClient ( "gpt-4o-mini" ) 
@@ -495,7 +493,7 @@ public async Task GetAIFunctionsAsync_UsingEverythingServer_ToolsAreProperlyCall
495493        messages . Add ( new ( ChatRole . User ,  "Please call the echo tool with the string 'Hello MCP!' and output the response ad verbatim." ) ) ; 
496494
497495        // Call the chat client 
498-         var  response  =  await  chatClient . GetResponseAsync ( messages ,  new ( )  {  Tools  =  [ .. mappedTools ] ,  Temperature  =  0  } ) ; 
496+         var  response  =  await  chatClient . GetResponseAsync ( messages ,  new ( )  {  Tools  =  [ .. mappedTools ] ,  Temperature  =  0  } ,   TestContext . Current . CancellationToken ) ; 
499497
500498        // Assert 
501499        Assert . Contains ( "Echo: Hello MCP!" ,  response . Text ) ; 
@@ -504,10 +502,7 @@ public async Task GetAIFunctionsAsync_UsingEverythingServer_ToolsAreProperlyCall
504502    [ Fact ] 
505503    public  async  Task  SamplingViaChatClient_RequestResponseProperlyPropagated ( ) 
506504    { 
507-         if  ( s_openAIKey  is  null ) 
508-         { 
509-             return ;  // Skip the test if the OpenAI key is not provided 
510-         } 
505+         SkipTestIfNoOpenAIKey ( ) ; 
511506
512507        await  using  var  client  =  await  McpClientFactory . CreateAsync ( _fixture . EverythingServerConfig ,  new ( ) 
513508        { 
@@ -519,17 +514,25 @@ public async Task SamplingViaChatClient_RequestResponseProperlyPropagated()
519514                    SamplingHandler  =  new  OpenAIClient ( s_openAIKey ) . AsChatClient ( "gpt-4o-mini" ) . CreateSamplingHandler ( ) , 
520515                } , 
521516            } , 
522-         } ) ; 
517+         } ,   cancellationToken :   TestContext . Current . CancellationToken ) ; 
523518
524519        var  result  =  await  client . CallToolAsync ( "sampleLLM" ,  new ( ) 
525520        { 
526521            [ "prompt" ]  =  "In just a few words, what is the most famous tower in Paris?" , 
527-         } ) ; 
522+         } ,   TestContext . Current . CancellationToken ) ; 
528523
529524        Assert . NotNull ( result ) ; 
530525        Assert . NotEmpty ( result . Content ) ; 
531526        Assert . Equal ( "text" ,  result . Content [ 0 ] . Type ) ; 
532527        Assert . Contains ( "LLM sampling result:" ,  result . Content [ 0 ] . Text ) ; 
533528        Assert . Contains ( "Eiffel" ,  result . Content [ 0 ] . Text ) ; 
534529    } 
530+ 
531+     private  static void  SkipTestIfNoOpenAIKey ( ) 
532+     { 
533+         if  ( string . IsNullOrEmpty ( s_openAIKey ) ) 
534+         { 
535+             throw  SkipException . ForSkip ( "No OpenAI key provided. Skipping test." ) ; 
536+         } 
537+     } 
535538} 
0 commit comments