Skip to content

Commit 750d0d1

Browse files
Copilotstephentoub
andcommitted
Seal public Protocol reference types to prevent external inheritance
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent f15f0fc commit 750d0d1

4 files changed

Lines changed: 60 additions & 7 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: 57 additions & 4 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)
@@ -647,6 +647,25 @@ public override void Write(Utf8JsonWriter writer, PrimitiveSchemaDefinition valu
647647
}
648648
break;
649649

650+
#pragma warning disable MCP9001 // EnumSchema is deprecated but supported for backward compatibility
651+
case EnumSchema enumSchema:
652+
#pragma warning restore MCP9001
653+
if (enumSchema.Enum is not null)
654+
{
655+
writer.WritePropertyName("enum");
656+
JsonSerializer.Serialize(writer, enumSchema.Enum, McpJsonUtilities.JsonContext.Default.IListString);
657+
}
658+
if (enumSchema.EnumNames is not null)
659+
{
660+
writer.WritePropertyName("enumNames");
661+
JsonSerializer.Serialize(writer, enumSchema.EnumNames, McpJsonUtilities.JsonContext.Default.IListString);
662+
}
663+
if (enumSchema.Default is not null)
664+
{
665+
writer.WriteString("default", enumSchema.Default);
666+
}
667+
break;
668+
650669
default:
651670
throw new JsonException($"Unexpected schema type: {value.GetType().Name}");
652671
}
@@ -1002,8 +1021,42 @@ public override string Type
10021021
/// This schema is deprecated in favor of <see cref="TitledSingleSelectEnumSchema"/>.
10031022
/// </remarks>
10041023
[Obsolete(Obsoletions.LegacyTitledEnumSchema_Message, DiagnosticId = Obsoletions.LegacyTitledEnumSchema_DiagnosticId, UrlFormat = Obsoletions.LegacyTitledEnumSchema_Url)]
1005-
public sealed class EnumSchema : LegacyTitledEnumSchema
1024+
public sealed class EnumSchema : PrimitiveSchemaDefinition
10061025
{
1026+
/// <inheritdoc/>
1027+
[JsonPropertyName("type")]
1028+
public override string Type
1029+
{
1030+
get => "string";
1031+
set
1032+
{
1033+
if (value is not "string")
1034+
{
1035+
throw new ArgumentException("Type must be 'string'.", nameof(value));
1036+
}
1037+
}
1038+
}
1039+
1040+
/// <summary>Gets or sets the list of allowed string values for the enum.</summary>
1041+
[JsonPropertyName("enum")]
1042+
[field: MaybeNull]
1043+
public IList<string> Enum
1044+
{
1045+
get => field ??= [];
1046+
set
1047+
{
1048+
Throw.IfNull(value);
1049+
field = value;
1050+
}
1051+
}
1052+
1053+
/// <summary>Gets or sets optional display names corresponding to the enum values.</summary>
1054+
[JsonPropertyName("enumNames")]
1055+
public IList<string>? EnumNames { get; set; }
1056+
1057+
/// <summary>Gets or sets the default value for the enum.</summary>
1058+
[JsonPropertyName("default")]
1059+
public string? Default { get; set; }
10071060
}
10081061

10091062
/// <summary>
@@ -1013,7 +1066,7 @@ public sealed class EnumSchema : LegacyTitledEnumSchema
10131066
/// This schema is deprecated in favor of <see cref="TitledSingleSelectEnumSchema"/>.
10141067
/// </remarks>
10151068
[Obsolete(Obsoletions.LegacyTitledEnumSchema_Message, DiagnosticId = Obsoletions.LegacyTitledEnumSchema_DiagnosticId, UrlFormat = Obsoletions.LegacyTitledEnumSchema_Url)]
1016-
public class LegacyTitledEnumSchema : PrimitiveSchemaDefinition
1069+
public sealed class LegacyTitledEnumSchema : PrimitiveSchemaDefinition
10171070
{
10181071
/// <inheritdoc/>
10191072
[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)

0 commit comments

Comments
 (0)