Hide experimental types from external source generators using internal property pattern#1301
Merged
MackinnonBuck merged 3 commits intomainfrom Feb 19, 2026
Merged
Conversation
…l source generators Experimental properties on stable protocol types cause external STJ source generators to emit code referencing experimental types, creating binary compatibility risks and unwanted MCPEXP001 diagnostics for consumers who don't use those APIs. This commit addresses both concerns: - Internal property pattern: each experimental property delegates to an internal *Core property with [JsonInclude][JsonPropertyName]. External source generators cannot see internal members, so only the SDK's own McpJsonUtilities.DefaultOptions serializes these properties. This eliminates binary coupling to experimental types across assemblies. - MCPEXP001Suppressor: on net8.0/net9.0, the SG still references experimental types in [JsonIgnore] property metadata (fixed in net10.0 by dotnet/runtime#120181). The suppressor silences MCPEXP001 in .g.cs files so it only surfaces in hand-written code. Applied to all 7 experimental properties: Tool.Execution, ServerCapabilities.Tasks, ClientCapabilities.Tasks, CallToolResult.Task, CallToolRequestParams.Task, CreateMessageRequestParams.Task, ElicitRequestParams.Task. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
stephentoub
reviewed
Feb 17, 2026
stephentoub
reviewed
Feb 18, 2026
jeffhandley
reviewed
Feb 18, 2026
jeffhandley
approved these changes
Feb 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Experimental properties on stable protocol types (e.g.
Tool.Execution,ServerCapabilities.Tasks) cause two problems for consumers who don't use those APIs:MCPEXP001at compile time, forcing consumers to suppress a diagnostic for an API they aren't using.Approach
Alternative to #1260. Each experimental property is marked
[JsonIgnore]and delegates to aninternalproperty marked[JsonInclude][JsonPropertyName]:This resolves both issues. Because
internalmembers are invisible across assembly boundaries, external source generators never emit code referencing experimental types, eliminating the binary compatibility concern. And because the public property is[JsonIgnore]d, the source generator usesobjectrather than the experimental type, avoiding theMCPEXP001diagnostic entirely. The only code path that serializes these properties is the SDK's ownMcpJsonUtilities.DefaultOptions.Consumer experience
MCPEXP001as usual. Serialization throughMcpJsonUtilities.DefaultOptionshandles everything.JsonSerializerContext+ experimental APIs: ConfigureTypeInfoResolverChainso the SDK's resolver takes precedence for SDK types. Only needed by consumers who both use experimental APIs and define a custom serialization context.[Experimental]/[JsonIgnore], add[JsonPropertyName], convert to auto-property, delete the*Coreproperty. No consumer changes required.Changes
ExperimentalApiRegressionTest) that builds with[JsonSerializable]references to all affected types, verifying noMCPEXP001diagnostics are emittedFixes #1255