Skip to content

Allow .NET 8 projects to consume the MCP SDK#1297

Open
dagirard wants to merge 4 commits intomodelcontextprotocol:mainfrom
dagirard:private/dagirard/net8dependencies
Open

Allow .NET 8 projects to consume the MCP SDK#1297
dagirard wants to merge 4 commits intomodelcontextprotocol:mainfrom
dagirard:private/dagirard/net8dependencies

Conversation

@dagirard
Copy link

@dagirard dagirard commented Feb 17, 2026

Downgrade Microsoft.Extensions.* to 8.x for net8.0 TFM.

Motivation and Context

Large projects may not be able to uptake (yet) .NET 10 due to external dependencies.
The MCP C# SDKs requires Microsoft.Extensions* v10, and it is almost impossible to uptake those in .NET 8 projects, as they have very big cascading effect.

The only one that can be loaded in .NET 8 with custom assembly load context is System.Text.Json V10 and its dependencies. (IO.Pipelines and BCL.AsyncInterfaces)

After analyzing the MCP C# SDK, it has been determined that the .NET 8 version can consume the Microsoft.Extensions* v8 dependencies with minimal conditional changes. (See the file changed)

How Has This Been Tested?

Tested with our product, Microsoft Dynamics 365 Business Central, which successfully managed to uptake the custom version.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Co-Authored with Claud Opus 4.6.

dagirard and others added 2 commits February 17, 2026 14:12
Consumers running on .NET 8 runtime (including PowerShell) hit conflicts
with Microsoft.Extensions.* 10.x dependencies. Condition package versions
so the net8.0 build uses 8.x versions of Microsoft.Extensions.* packages
while other TFMs continue using 10.x.

Key changes:
- Split shared product and testing M.E.* deps into net8.0/non-net8.0 groups
- M.E.AI/AI.Abstractions use 9.10.2 for net8.0 (latest 9.x with 8.x transitive deps)
- Add explicit System.Text.Json 10.x dep for net8.0 (no longer transitive from M.E.*)
- Downgrade Serilog.Extensions.Hosting/Logging to 8.0.0 for net8.0
- Add ILogger field in StreamableHttpPostTransport for 8.x LoggerMessage generator
- Conditional-compile InstrumentAdvice usage (not in net8.0 DiagnosticSource)
- Exclude M.E.AI.OpenAI from net8.0 test builds (requires M.E.AI 10.x)
- Move ChatWithTools sample to net9.0 (depends on M.E.AI.OpenAI)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t.Json 10.x dependency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dagirard dagirard changed the title Allow .NET 8 projects to consume MCP SDKs Allow .NET 8 projects to consume the MCP SDK Feb 17, 2026
@stephentoub stephentoub added the NO MERGE PR should not be merged until the label is removed label Feb 17, 2026
@dagirard dagirard marked this pull request as draft February 17, 2026 17:11
dagirard and others added 2 commits February 17, 2026 19:27
- Fix TestServer.exe path resolution by using full path instead of bare
  filename, which failed when cmd.exe wrapper resolved against repo root
- Fix conformance test success detection to handle Node.js libuv assertion
  crash on Windows by checking stdout for "0 failed" as fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dagirard dagirard marked this pull request as ready for review February 18, 2026 18:26
@dagirard
Copy link
Author

Fix tested with our product in staging environment. Everything is working so far and we are able to execute all our scenarios.

@stephentoub
Copy link
Contributor

@ericstj

@stephentoub
Copy link
Contributor

stephentoub commented Feb 18, 2026

What are the projects you're referring to that are having problems with the 10.x versions of the various nuget packages?

@dagirard
Copy link
Author

There are conflicts between the Microsoft.Extensions.* and System.Diagnostics.* assemblies bundled with .NET 8 (via Microsoft.AspNetCore.App and Microsoft.NETCore.App) and the v10 assemblies referenced by the MCP SDK.

We experimented with loading all the v10 assemblies through a custom AssemblyLoadContext. It worked for most scenarios, but our CI pipelines consistently surfaced incompatibilities that we couldn’t fully isolate.

Given that the SDK doesn’t rely on any v10‑specific features, the most reliable approach is to align the SDK’s dependencies with the assemblies included in the .NET 8 shared framework. This avoids binding conflicts entirely and keeps the integration straightforward.

@ericstj
Copy link
Collaborator

ericstj commented Feb 18, 2026

If your application loads with a deps file you shouldn't need a custom ALC. Do you happen to have some plugin app-model where the plugin is what's using the new packages? If that's the case, then using a deps file for the plugin should work.

@dagirard
Copy link
Author

It does load with deps file, and the main service is working fine.

Most of the issues arrise with our management cmdlets, which are loaded by powershell classic (through a bridge) and pwsh (directly). And pwsh doesn't support .net 10 yet. (The custom alc was done for pwsh).

@ericstj
Copy link
Collaborator

ericstj commented Feb 19, 2026

Powershell classic - do you mean the powershell 5 that's built into windows and runs on .NETFramework? I can see how you might have trouble there. Using nuget packages in netfx is fragile. Maybe that's why you are using some bridge? If you happen to be using AssemblyResolve here that would also explain fragility.

Pwsh - even though it runs on .NET 8 it should work fine with 10.0 Microsoft.Extensions. Pwsh does not redistribute any of the Microsoft.Extensions assemblies nor does it try to restrict their loading. I can see how you might have issues with loading here if you have other addins trying to load different versions of dependencies. Powershell can be like a "type soup" and trouble will arise if you expect types to exchange that don't due to loading different versions. In theory your use of extensions should be totally isolated to your cmdlets. I wouldn't expect you to expose the ME types.

It worked for most scenarios, but our CI pipelines consistently surfaced incompatibilities that we couldn’t fully isolate.

I'm interested to know the specific details about this. Can you share them here, or ping me in teams?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

NO MERGE PR should not be merged until the label is removed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments