Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ protected DelegatingMcpServerPrompt(McpServerPrompt innerPrompt)
/// <inheritdoc />
public override Prompt ProtocolPrompt => _innerPrompt.ProtocolPrompt;

/// <inheritdoc />
public override IReadOnlyList<object> Metadata => _innerPrompt.Metadata;

/// <inheritdoc />
public override ValueTask<GetPromptResult> GetAsync(
RequestContext<GetPromptRequestParams> request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ protected DelegatingMcpServerResource(McpServerResource innerResource)
/// <inheritdoc />
public override ResourceTemplate ProtocolResourceTemplate => _innerResource.ProtocolResourceTemplate;

/// <inheritdoc />
public override IReadOnlyList<object> Metadata => _innerResource.Metadata;

/// <inheritdoc />
public override bool IsMatch(string uri) => _innerResource.IsMatch(uri);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ protected DelegatingMcpServerTool(McpServerTool innerTool)
/// <inheritdoc />
public override Tool ProtocolTool => _innerTool.ProtocolTool;

/// <inheritdoc />
public override IReadOnlyList<object> Metadata => _innerTool.Metadata;

/// <inheritdoc />
public override ValueTask<CallToolResult> InvokeAsync(
RequestContext<CallToolRequestParams> request,
Expand Down
22 changes: 22 additions & 0 deletions tests/ModelContextProtocol.Tests/Server/McpServerPromptTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -547,4 +547,26 @@ public void SupportsPromptWithoutIcons()

Assert.Null(prompt.ProtocolPrompt.Icons);
}

[Fact]
public void DelegatingMcpServerPrompt_OverridesAllVirtualAndAbstractMembers()
{
MethodInfo[] baseMethods = typeof(McpServerPrompt).GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => (m.IsVirtual || m.IsAbstract) && m.DeclaringType == typeof(McpServerPrompt))
.ToArray();

Assert.NotEmpty(baseMethods);

foreach (MethodInfo baseMethod in baseMethods)
{
MethodInfo? overriddenMethod = typeof(DelegatingMcpServerPrompt).GetMethod(
baseMethod.Name,
BindingFlags.Public | BindingFlags.Instance,
baseMethod.GetParameters().Select(p => p.ParameterType).ToArray());

Assert.True(
overriddenMethod is not null && overriddenMethod.DeclaringType == typeof(DelegatingMcpServerPrompt),
$"DelegatingMcpServerPrompt does not override {baseMethod.Name} from McpServerPrompt.");
}
}
}
22 changes: 22 additions & 0 deletions tests/ModelContextProtocol.Tests/Server/McpServerResourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,28 @@ public void SupportsResourceWithoutIcons()
Assert.Null(resource.ProtocolResourceTemplate.Icons);
}

[Fact]
public void DelegatingMcpServerResource_OverridesAllVirtualAndAbstractMembers()
{
MethodInfo[] baseMethods = typeof(McpServerResource).GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => (m.IsVirtual || m.IsAbstract) && m.DeclaringType == typeof(McpServerResource))
.ToArray();

Assert.NotEmpty(baseMethods);

foreach (MethodInfo baseMethod in baseMethods)
{
MethodInfo? overriddenMethod = typeof(DelegatingMcpServerResource).GetMethod(
baseMethod.Name,
BindingFlags.Public | BindingFlags.Instance,
baseMethod.GetParameters().Select(p => p.ParameterType).ToArray());

Assert.True(
overriddenMethod is not null && overriddenMethod.DeclaringType == typeof(DelegatingMcpServerResource),
$"DelegatingMcpServerResource does not override {baseMethod.Name} from McpServerResource.");
}
}

[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(DisposableResourceType))]
[JsonSerializable(typeof(List<AIContent>))]
Expand Down
22 changes: 22 additions & 0 deletions tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,28 @@ private static string SyncTool()
[Description("Tool without return description.")]
private static string ToolWithoutReturnDescription() => "result";

[Fact]
public void DelegatingMcpServerTool_OverridesAllVirtualAndAbstractMembers()
{
MethodInfo[] baseMethods = typeof(McpServerTool).GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => (m.IsVirtual || m.IsAbstract) && m.DeclaringType == typeof(McpServerTool))
.ToArray();

Assert.NotEmpty(baseMethods);

foreach (MethodInfo baseMethod in baseMethods)
{
MethodInfo? overriddenMethod = typeof(DelegatingMcpServerTool).GetMethod(
baseMethod.Name,
BindingFlags.Public | BindingFlags.Instance,
baseMethod.GetParameters().Select(p => p.ParameterType).ToArray());

Assert.True(
overriddenMethod is not null && overriddenMethod.DeclaringType == typeof(DelegatingMcpServerTool),
$"DelegatingMcpServerTool does not override {baseMethod.Name} from McpServerTool.");
}
}

[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(JsonNode))]
[JsonSerializable(typeof(DisposableToolType))]
Expand Down