Skip to content

Commit cc6ef5b

Browse files
Hide experimental types from external source generators using internal property pattern (#1301)
1 parent 231e013 commit cc6ef5b

File tree

12 files changed

+315
-7
lines changed

12 files changed

+315
-7
lines changed

ModelContextProtocol.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,6 @@
7878
<Project Path="tests/ModelContextProtocol.Tests/ModelContextProtocol.Tests.csproj" />
7979
<Project Path="tests/ModelContextProtocol.TestServer/ModelContextProtocol.TestServer.csproj" />
8080
<Project Path="tests/ModelContextProtocol.TestSseServer/ModelContextProtocol.TestSseServer.csproj" />
81+
<Project Path="tests/ModelContextProtocol.ExperimentalApiRegressionTest/ModelContextProtocol.ExperimentalApiRegressionTest.csproj" />
8182
</Folder>
8283
</Solution>

src/ModelContextProtocol.Core/Protocol/CallToolRequestParams.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using System.Text.Json;
23
using System.Text.Json.Serialization;
34

@@ -33,6 +34,16 @@ public sealed class CallToolRequestParams : RequestParams
3334
/// When present, indicates that the requestor wants this operation executed as a task.
3435
/// The receiver must support task augmentation for this specific request type.
3536
/// </remarks>
37+
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
38+
[JsonIgnore]
39+
public McpTaskMetadata? Task
40+
{
41+
get => TaskCore;
42+
set => TaskCore = value;
43+
}
44+
45+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
46+
[JsonInclude]
3647
[JsonPropertyName("task")]
37-
public McpTaskMetadata? Task { get; set; }
48+
internal McpTaskMetadata? TaskCore { get; set; }
3849
}

src/ModelContextProtocol.Core/Protocol/CallToolResult.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using System.Text.Json.Nodes;
23
using System.Text.Json.Serialization;
34

@@ -72,6 +73,16 @@ public sealed class CallToolResult : Result
7273
/// (<see cref="Content"/>, <see cref="StructuredContent"/>, <see cref="IsError"/>) may not be populated.
7374
/// The actual tool result can be retrieved later via <c>tasks/result</c>.
7475
/// </remarks>
76+
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
77+
[JsonIgnore]
78+
public McpTask? Task
79+
{
80+
get => TaskCore;
81+
set => TaskCore = value;
82+
}
83+
84+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
85+
[JsonInclude]
7586
[JsonPropertyName("task")]
76-
public McpTask? Task { get; set; }
87+
internal McpTask? TaskCore { get; set; }
7788
}

src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.ComponentModel;
2+
using System.Diagnostics.CodeAnalysis;
23
using System.Text.Json.Serialization;
34
using ModelContextProtocol.Client;
45
using ModelContextProtocol.Server;
@@ -80,6 +81,16 @@ public sealed class ClientCapabilities
8081
/// See <see cref="McpTasksCapability"/> for details on configuring which operations support tasks.
8182
/// </para>
8283
/// </remarks>
84+
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
85+
[JsonIgnore]
86+
public McpTasksCapability? Tasks
87+
{
88+
get => TasksCore;
89+
set => TasksCore = value;
90+
}
91+
92+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
93+
[JsonInclude]
8394
[JsonPropertyName("tasks")]
84-
public McpTasksCapability? Tasks { get; set; }
95+
internal McpTasksCapability? TasksCore { get; set; }
8596
}

src/ModelContextProtocol.Core/Protocol/CreateMessageRequestParams.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using System.Text.Json;
23
using System.Text.Json.Serialization;
34

@@ -160,6 +161,16 @@ public sealed class CreateMessageRequestParams : RequestParams
160161
/// When present, indicates that the requestor wants this operation executed as a task.
161162
/// The receiver must support task augmentation for this specific request type.
162163
/// </remarks>
164+
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
165+
[JsonIgnore]
166+
public McpTaskMetadata? Task
167+
{
168+
get => TaskCore;
169+
set => TaskCore = value;
170+
}
171+
172+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
173+
[JsonInclude]
163174
[JsonPropertyName("task")]
164-
public McpTaskMetadata? Task { get; set; }
175+
internal McpTaskMetadata? TaskCore { get; set; }
165176
}

src/ModelContextProtocol.Core/Protocol/ElicitRequestParams.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,18 @@ public string Mode
9999
/// When present, indicates that the requestor wants this operation executed as a task.
100100
/// The receiver must support task augmentation for this specific request type.
101101
/// </remarks>
102+
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
103+
[JsonIgnore]
104+
public McpTaskMetadata? Task
105+
{
106+
get => TaskCore;
107+
set => TaskCore = value;
108+
}
109+
110+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
111+
[JsonInclude]
102112
[JsonPropertyName("task")]
103-
public McpTaskMetadata? Task { get; set; }
113+
internal McpTaskMetadata? TaskCore { get; set; }
104114

105115
/// <summary>Represents a request schema used in a form mode elicitation request.</summary>
106116
public sealed class RequestSchema

src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.ComponentModel;
2+
using System.Diagnostics.CodeAnalysis;
23
using System.Text.Json.Serialization;
34
using ModelContextProtocol.Server;
45

@@ -79,6 +80,16 @@ public sealed class ServerCapabilities
7980
/// See <see cref="McpTasksCapability"/> for details on configuring which operations support tasks.
8081
/// </para>
8182
/// </remarks>
83+
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
84+
[JsonIgnore]
85+
public McpTasksCapability? Tasks
86+
{
87+
get => TasksCore;
88+
set => TasksCore = value;
89+
}
90+
91+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
92+
[JsonInclude]
8293
[JsonPropertyName("tasks")]
83-
public McpTasksCapability? Tasks { get; set; }
94+
internal McpTasksCapability? TasksCore { get; set; }
8495
}

src/ModelContextProtocol.Core/Protocol/Tool.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,17 @@ public JsonElement? OutputSchema
128128
/// regarding task augmentation support. See <see cref="ToolExecution"/> for details.
129129
/// </remarks>
130130
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
131+
[JsonIgnore]
132+
public ToolExecution? Execution
133+
{
134+
get => ExecutionCore;
135+
set => ExecutionCore = value;
136+
}
137+
138+
// See ExperimentalInternalPropertyTests.cs before modifying this property.
139+
[JsonInclude]
131140
[JsonPropertyName("execution")]
132-
public ToolExecution? Execution { get; set; }
141+
internal ToolExecution? ExecutionCore { get; set; }
133142

134143
/// <summary>
135144
/// Gets or sets an optional list of icons for this tool.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Text.Json.Serialization;
2+
using ModelContextProtocol.Protocol;
3+
4+
namespace ModelContextProtocol.ExperimentalApiRegressionTest;
5+
6+
/// <summary>
7+
/// This file validates that the System.Text.Json source generator does not produce
8+
/// MCPEXP001 diagnostics for MCP protocol types with experimental properties.
9+
/// </summary>
10+
[JsonSerializable(typeof(Tool))]
11+
[JsonSerializable(typeof(ServerCapabilities))]
12+
[JsonSerializable(typeof(ClientCapabilities))]
13+
[JsonSerializable(typeof(CallToolResult))]
14+
[JsonSerializable(typeof(CallToolRequestParams))]
15+
[JsonSerializable(typeof(CreateMessageRequestParams))]
16+
[JsonSerializable(typeof(ElicitRequestParams))]
17+
internal partial class ExperimentalPropertyRegressionContext : JsonSerializerContext;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>net10.0;net9.0;net8.0</TargetFrameworks>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsPackable>false</IsPackable>
8+
9+
<!--
10+
This project validates that MCPEXP001 diagnostics are NOT emitted by the
11+
System.Text.Json source generator for types with experimental properties.
12+
tests/Directory.Build.props suppresses MCPEXP001 globally for all test projects,
13+
but this project must NOT suppress it: its successful compilation IS the test.
14+
-->
15+
<NoWarn>$(NoWarn.Replace('MCPEXP001',''))</NoWarn>
16+
17+
<!--
18+
[JsonInclude] internal members trigger this warning only because the MCP C# SDK
19+
is a project reference here. NuGet consumers won't see it since Roslyn doesn't import
20+
internal members from metadata.
21+
-->
22+
<NoWarn>$(NoWarn);SYSLIB1038</NoWarn>
23+
</PropertyGroup>
24+
25+
<ItemGroup>
26+
<ProjectReference Include="..\..\src\ModelContextProtocol.Core\ModelContextProtocol.Core.csproj" />
27+
</ItemGroup>
28+
29+
</Project>

0 commit comments

Comments
 (0)