diff --git a/Directory.Packages.props b/Directory.Packages.props
index 3f5540f9d..46180d362 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -5,10 +5,11 @@
9.0.11
10.0.3
10.3.0
+ 9.10.2
-
-
+
+
@@ -17,6 +18,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -34,6 +45,7 @@
+
@@ -67,13 +79,6 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
-
-
-
-
-
@@ -82,8 +87,10 @@
-
-
+
+
+
+
@@ -94,4 +101,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index d282e9af3..06879025f 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,13 @@ For more information about MCP:
- [Protocol Specification](https://modelcontextprotocol.io/specification/)
- [GitHub Organization](https://github.com/modelcontextprotocol)
+## Prerequisites
+
+The SDK targets .NET Standard 2.0, .NET 8.0, .NET 9.0, and .NET 10.0. When targeting .NET 8.0, the SDK uses 8.x versions of `Microsoft.Extensions.*` dependencies for runtime compatibility.
+
+> [!IMPORTANT]
+> The SDK depends on `System.Text.Json` 10.x on all target frameworks, including .NET 8.0. If your application pins `System.Text.Json` to an 8.x version, you will need to allow the upgrade to 10.x for the SDK to function correctly.
+
## Installation
To get started, install the package from NuGet
diff --git a/samples/AspNetCoreMcpServer/AspNetCoreMcpServer.csproj b/samples/AspNetCoreMcpServer/AspNetCoreMcpServer.csproj
index 59ab49828..39ea74a97 100644
--- a/samples/AspNetCoreMcpServer/AspNetCoreMcpServer.csproj
+++ b/samples/AspNetCoreMcpServer/AspNetCoreMcpServer.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net8.0
enable
enable
true
diff --git a/samples/ChatWithTools/ChatWithTools.csproj b/samples/ChatWithTools/ChatWithTools.csproj
index 3723185fe..901e1ad7d 100644
--- a/samples/ChatWithTools/ChatWithTools.csproj
+++ b/samples/ChatWithTools/ChatWithTools.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net9.0
enable
enable
+
+
+
+
diff --git a/src/ModelContextProtocol.Core/README.md b/src/ModelContextProtocol.Core/README.md
index 69913a150..1414a5263 100644
--- a/src/ModelContextProtocol.Core/README.md
+++ b/src/ModelContextProtocol.Core/README.md
@@ -17,6 +17,13 @@ For more information about MCP:
- [Protocol Specification](https://modelcontextprotocol.io/specification/)
- [GitHub Organization](https://github.com/modelcontextprotocol)
+## Prerequisites
+
+The SDK targets .NET Standard 2.0, .NET 8.0, .NET 9.0, and .NET 10.0. When targeting .NET 8.0, the SDK uses 8.x versions of `Microsoft.Extensions.*` dependencies for runtime compatibility.
+
+> [!IMPORTANT]
+> The SDK depends on `System.Text.Json` 10.x on all target frameworks, including .NET 8.0. If your application pins `System.Text.Json` to an 8.x version, you will need to allow the upgrade to 10.x for the SDK to function correctly.
+
## Installation
To get started, install the core package from NuGet
diff --git a/src/ModelContextProtocol.Core/Server/StreamableHttpPostTransport.cs b/src/ModelContextProtocol.Core/Server/StreamableHttpPostTransport.cs
index 7f399bab3..6a69cf440 100644
--- a/src/ModelContextProtocol.Core/Server/StreamableHttpPostTransport.cs
+++ b/src/ModelContextProtocol.Core/Server/StreamableHttpPostTransport.cs
@@ -17,6 +17,7 @@ internal sealed partial class StreamableHttpPostTransport(
CancellationToken sessionCancellationToken,
ILogger logger) : ITransport
{
+ private readonly ILogger _logger = logger;
private readonly SemaphoreSlim _messageLock = new(1, 1);
private readonly TaskCompletionSource _httpResponseTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly SseEventWriter _httpSseWriter = new(responseStream);
diff --git a/tests/ModelContextProtocol.AspNetCore.Tests/ModelContextProtocol.AspNetCore.Tests.csproj b/tests/ModelContextProtocol.AspNetCore.Tests/ModelContextProtocol.AspNetCore.Tests.csproj
index 384e8fcdd..38032f8e8 100644
--- a/tests/ModelContextProtocol.AspNetCore.Tests/ModelContextProtocol.AspNetCore.Tests.csproj
+++ b/tests/ModelContextProtocol.AspNetCore.Tests/ModelContextProtocol.AspNetCore.Tests.csproj
@@ -33,7 +33,7 @@
-
+
diff --git a/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs b/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs
index d2501456c..c00f8c117 100644
--- a/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs
+++ b/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs
@@ -173,10 +173,19 @@ public async Task RunPendingConformanceTest_ServerSsePolling()
);
}
+ var stdOut = outputBuilder.ToString();
+ var stdErr = errorBuilder.ToString();
+
+ // On Windows, the Node.js conformance runner can crash during shutdown due to a libuv assertion
+ // (UV_HANDLE_CLOSING), producing a non-zero exit code even when all tests pass. Fall back to
+ // checking the output for "0 failed" when the exit code is non-zero.
+ bool success = process.ExitCode == 0 ||
+ (stdOut.Contains("0 failed") && !stdOut.Contains("FAILURE"));
+
return (
- Success: process.ExitCode == 0,
- Output: outputBuilder.ToString(),
- Error: errorBuilder.ToString()
+ Success: success,
+ Output: stdOut,
+ Error: stdErr
);
}
}
diff --git a/tests/ModelContextProtocol.Tests/ClientIntegrationTestFixture.cs b/tests/ModelContextProtocol.Tests/ClientIntegrationTestFixture.cs
index 049d72d60..faf83814d 100644
--- a/tests/ModelContextProtocol.Tests/ClientIntegrationTestFixture.cs
+++ b/tests/ModelContextProtocol.Tests/ClientIntegrationTestFixture.cs
@@ -27,8 +27,9 @@ public ClientIntegrationTestFixture()
TestServerTransportOptions = new()
{
- Command = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "TestServer.exe" : PlatformDetection.IsMonoRuntime ? "mono" : "dotnet",
+ Command = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Path.Combine(AppContext.BaseDirectory, "TestServer.exe") : PlatformDetection.IsMonoRuntime ? "mono" : "dotnet",
Name = "TestServer",
+ WorkingDirectory = AppContext.BaseDirectory,
};
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
diff --git a/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs b/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs
index 018e12dbe..a048362ca 100644
--- a/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs
+++ b/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs
@@ -2,7 +2,9 @@
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Tests.Utils;
+#if !NET8_0
using OpenAI;
+#endif
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -10,9 +12,11 @@ namespace ModelContextProtocol.Tests;
public partial class ClientIntegrationTests : LoggedTest, IClassFixture
{
+#if !NET8_0
private static readonly string? s_openAIKey = Environment.GetEnvironmentVariable("AI:OpenAI:ApiKey");
public static bool NoOpenAIKeySet => string.IsNullOrWhiteSpace(s_openAIKey);
+#endif
private readonly ClientIntegrationTestFixture _fixture;
@@ -492,6 +496,7 @@ public async Task CallTool_Stdio_MemoryServer()
await client.DisposeAsync();
}
+#if !NET8_0
[Fact(Skip = "Requires OpenAI API Key", SkipWhen = nameof(NoOpenAIKeySet))]
public async Task ListToolsAsync_UsingEverythingServer_ToolsAreProperlyCalled()
{
@@ -547,6 +552,7 @@ public async Task SamplingViaChatClient_RequestResponseProperlyPropagated()
Assert.Contains("LLM sampling result:", content.Text);
Assert.Contains("Eiffel", content.Text);
}
+#endif
[Theory]
[MemberData(nameof(GetClients))]
diff --git a/tests/ModelContextProtocol.Tests/ModelContextProtocol.Tests.csproj b/tests/ModelContextProtocol.Tests/ModelContextProtocol.Tests.csproj
index 0985f4cd7..3968cbaf2 100644
--- a/tests/ModelContextProtocol.Tests/ModelContextProtocol.Tests.csproj
+++ b/tests/ModelContextProtocol.Tests/ModelContextProtocol.Tests.csproj
@@ -60,7 +60,7 @@
all
-
+
diff --git a/tests/ModelContextProtocol.Tests/Transport/StdioClientTransportTests.cs b/tests/ModelContextProtocol.Tests/Transport/StdioClientTransportTests.cs
index c33ed7f72..6f1817f2f 100644
--- a/tests/ModelContextProtocol.Tests/Transport/StdioClientTransportTests.cs
+++ b/tests/ModelContextProtocol.Tests/Transport/StdioClientTransportTests.cs
@@ -111,7 +111,7 @@ public async Task EscapesCliArgumentsCorrectly(string? cliArgumentValue)
Command = (PlatformDetection.IsMonoRuntime, PlatformDetection.IsWindows) switch
{
(true, _) => "mono",
- (_, true) => "TestServer.exe",
+ (_, true) => Path.Combine(AppContext.BaseDirectory, "TestServer.exe"),
_ => "dotnet",
},
Arguments = (PlatformDetection.IsMonoRuntime, PlatformDetection.IsWindows) switch
@@ -120,6 +120,7 @@ public async Task EscapesCliArgumentsCorrectly(string? cliArgumentValue)
(_, true) => [cliArgument],
_ => ["TestServer.dll", cliArgument],
},
+ WorkingDirectory = AppContext.BaseDirectory,
};
var transport = new StdioClientTransport(options, LoggerFactory);