Skip to content

Commit 712068b

Browse files
Copilotstephentoub
andauthored
Seal public Protocol reference types to prevent external inheritance (#1232)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent 0c35f8f commit 712068b

6 files changed

Lines changed: 16 additions & 30 deletions

File tree

src/ModelContextProtocol.Core/Protocol/ContentBlock.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ private protected ContentBlock()
6969
/// Provides a polymorphic converter for the <see cref="ContentBlock"/> class that doesn't require
7070
/// setting <see cref="JsonSerializerOptions.AllowOutOfOrderMetadataProperties"/> explicitly.
7171
[EditorBrowsable(EditorBrowsableState.Never)]
72-
public class Converter : JsonConverter<ContentBlock>
72+
public sealed class Converter : JsonConverter<ContentBlock>
7373
{
7474
/// <inheritdoc/>
7575
public override ContentBlock? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)

src/ModelContextProtocol.Core/Protocol/ElicitRequestParams.cs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public string Mode
103103
public McpTaskMetadata? Task { get; set; }
104104

105105
/// <summary>Represents a request schema used in a form mode elicitation request.</summary>
106-
public class RequestSchema
106+
public sealed class RequestSchema
107107
{
108108
/// <summary>Gets the type of the schema.</summary>
109109
/// <remarks>This value is always "object".</remarks>
@@ -161,7 +161,7 @@ protected private PrimitiveSchemaDefinition()
161161
/// Provides a polymorphic converter for the <see cref="PrimitiveSchemaDefinition"/> class that doesn't require
162162
/// setting <see cref="JsonSerializerOptions.AllowOutOfOrderMetadataProperties"/> explicitly.
163163
[EditorBrowsable(EditorBrowsableState.Never)]
164-
public class Converter : JsonConverter<PrimitiveSchemaDefinition>
164+
public sealed class Converter : JsonConverter<PrimitiveSchemaDefinition>
165165
{
166166
/// <inheritdoc/>
167167
public override PrimitiveSchemaDefinition? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
@@ -315,11 +315,9 @@ public class Converter : JsonConverter<PrimitiveSchemaDefinition>
315315
{
316316
if (enumNames is not null)
317317
{
318-
// EnumSchema is deprecated but supported for backward compatibility.
319-
// Use the EnumSchema class, which is an alias for LegacyTitledEnumSchema,
320-
// to ensure backward compatibility with existing code relying on that type.
318+
// LegacyTitledEnumSchema is deprecated but supported for backward compatibility.
321319
#pragma warning disable MCP9001
322-
psd = new EnumSchema
320+
psd = new LegacyTitledEnumSchema
323321
#pragma warning restore MCP9001
324322
{
325323
Enum = enumValues,
@@ -996,24 +994,12 @@ public override string Type
996994

997995
/// <summary>
998996
/// Represents a legacy schema for an enum type with enumNames.
999-
/// This is a compatibility alias for <see cref="LegacyTitledEnumSchema"/>.
1000997
/// </summary>
1001998
/// <remarks>
1002999
/// This schema is deprecated in favor of <see cref="TitledSingleSelectEnumSchema"/>.
10031000
/// </remarks>
10041001
[Obsolete(Obsoletions.LegacyTitledEnumSchema_Message, DiagnosticId = Obsoletions.LegacyTitledEnumSchema_DiagnosticId, UrlFormat = Obsoletions.LegacyTitledEnumSchema_Url)]
1005-
public sealed class EnumSchema : LegacyTitledEnumSchema
1006-
{
1007-
}
1008-
1009-
/// <summary>
1010-
/// Represents a legacy schema for an enum type with enumNames.
1011-
/// </summary>
1012-
/// <remarks>
1013-
/// This schema is deprecated in favor of <see cref="TitledSingleSelectEnumSchema"/>.
1014-
/// </remarks>
1015-
[Obsolete(Obsoletions.LegacyTitledEnumSchema_Message, DiagnosticId = Obsoletions.LegacyTitledEnumSchema_DiagnosticId, UrlFormat = Obsoletions.LegacyTitledEnumSchema_Url)]
1016-
public class LegacyTitledEnumSchema : PrimitiveSchemaDefinition
1002+
public sealed class LegacyTitledEnumSchema : PrimitiveSchemaDefinition
10171003
{
10181004
/// <inheritdoc/>
10191005
[JsonPropertyName("type")]

src/ModelContextProtocol.Core/Protocol/JsonRpcMessageContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ModelContextProtocol.Protocol;
1212
/// but is not serialized as part of the JSON-RPC payload. This includes transport references, execution context,
1313
/// and authenticated user information.
1414
/// </remarks>
15-
public class JsonRpcMessageContext
15+
public sealed class JsonRpcMessageContext
1616
{
1717
/// <summary>
1818
/// Gets or sets the transport the <see cref="JsonRpcMessage"/> was received on or should be sent over.

src/ModelContextProtocol.Core/Protocol/ResourceContents.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private protected ResourceContents()
6161
/// Provides a <see cref="JsonConverter"/> for <see cref="ResourceContents"/>.
6262
/// </summary>
6363
[EditorBrowsable(EditorBrowsableState.Never)]
64-
public class Converter : JsonConverter<ResourceContents>
64+
public sealed class Converter : JsonConverter<ResourceContents>
6565
{
6666
/// <inheritdoc/>
6767
public override ResourceContents? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)

tests/ModelContextProtocol.Tests/Protocol/EnumSchemaTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public void LegacyTitledEnumSchema_Serializes_Correctly()
298298

299299
// Assert
300300
Assert.NotNull(deserialized);
301-
var result = Assert.IsType<ElicitRequestParams.EnumSchema>(deserialized);
301+
var result = Assert.IsType<ElicitRequestParams.LegacyTitledEnumSchema>(deserialized);
302302
Assert.Equal("string", result.Type);
303303
Assert.Equal("Environment", result.Title);
304304
Assert.Equal("Deployment environment", result.Description);
@@ -309,10 +309,10 @@ public void LegacyTitledEnumSchema_Serializes_Correctly()
309309
}
310310

311311
[Fact]
312-
public void EnumSchema_Serializes_Correctly()
312+
public void LegacyTitledEnumSchema_Direct_Serializes_Correctly()
313313
{
314314
// Arrange
315-
var schema = new ElicitRequestParams.EnumSchema
315+
var schema = new ElicitRequestParams.LegacyTitledEnumSchema
316316
{
317317
Title = "Environment",
318318
Description = "Deployment environment",
@@ -327,7 +327,7 @@ public void EnumSchema_Serializes_Correctly()
327327

328328
// Assert
329329
Assert.NotNull(deserialized);
330-
var result = Assert.IsType<ElicitRequestParams.EnumSchema>(deserialized);
330+
var result = Assert.IsType<ElicitRequestParams.LegacyTitledEnumSchema>(deserialized);
331331
Assert.Equal("string", result.Type);
332332
Assert.Equal("Environment", result.Title);
333333
Assert.Equal("Deployment environment", result.Description);
@@ -338,9 +338,9 @@ public void EnumSchema_Serializes_Correctly()
338338
}
339339

340340
[Fact]
341-
public void Enum_WithEnumNames_Deserializes_As_EnumSchema()
341+
public void Enum_WithEnumNames_Deserializes_As_LegacyTitledEnumSchema()
342342
{
343-
// Arrange - JSON with enumNames should deserialize as (deprecated) EnumSchema
343+
// Arrange - JSON with enumNames should deserialize as (deprecated) LegacyTitledEnumSchema
344344
string json = """
345345
{
346346
"type": "string",
@@ -356,7 +356,7 @@ public void Enum_WithEnumNames_Deserializes_As_EnumSchema()
356356

357357
// Assert
358358
Assert.NotNull(deserialized);
359-
var result = Assert.IsType<ElicitRequestParams.EnumSchema>(deserialized);
359+
var result = Assert.IsType<ElicitRequestParams.LegacyTitledEnumSchema>(deserialized);
360360
Assert.Equal("string", result.Type);
361361
Assert.Equal("Environment", result.Title);
362362
Assert.Equal("Deployment environment", result.Description);

tests/ModelContextProtocol.Tests/Protocol/PrimitiveSchemaDefinitionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ public static void LegacyTitledEnumSchema_UnknownProperties_AreIgnored()
283283
json,
284284
McpJsonUtilities.DefaultOptions);
285285
Assert.NotNull(result);
286-
var enumSchema = Assert.IsType<ElicitRequestParams.EnumSchema>(result);
286+
var enumSchema = Assert.IsType<ElicitRequestParams.LegacyTitledEnumSchema>(result);
287287
Assert.Equal("string", enumSchema.Type);
288288
Assert.Equal(2, enumSchema.Enum.Count);
289289
Assert.Contains("option1", enumSchema.Enum);

0 commit comments

Comments
 (0)