Restructure IMcpEndpoint, IMcpClient, and IMcpServer (#723)

* Remove `McpEndpoint` & `IMcpClient`

* Revise naming, add abstract classes

* Fix missing renames

* Move extension methods to instance methods

* Add back old API, but obsoleted

* Add back obsoleted factory classes

* Move deprecation attributes

* `SseClientTransport` -> `HttpClientTransport`

* Update src/ModelContextProtocol.Core/Server/AugmentedServiceProvider.cs

Co-authored-by: Stephen Halter <halter73@gmail.com>

* PR feedback

* PR feedback

* Add back dispose lock

* Fix docs projects

* PR feedback

* Undo `docs/*.md` changes

---------

Co-authored-by: Stephen Halter <halter73@gmail.com>
This commit is contained in:
Mackinnon Buck 2025-09-16 13:22:10 -04:00 • committed by GitHub
commit 38b4a26998
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 5169 additions and 3786 deletions

View file

@ -0,0 +1,195 @@
using Microsoft.Extensions.AI;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
using Moq;
using System.Text.Json;
namespace ModelContextProtocol.Tests.Server;
#pragma warning disable CS0618 // Type or member is obsolete
public class McpServerExtensionsTests
{
[Fact]
public async Task SampleAsync_Request_Throws_When_Not_McpServer()
{
var server = new Mock<IMcpServer>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await server.SampleAsync(
new CreateMessageRequestParams { Messages = [new SamplingMessage { Role = Role.User, Content = new TextContentBlock { Text = "hi" } }] },
TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.SampleAsync' instead", ex.Message);
}
[Fact]
public async Task SampleAsync_Messages_Throws_When_Not_McpServer()
{
var server = new Mock<IMcpServer>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await server.SampleAsync(
[new ChatMessage(ChatRole.User, "hi")], cancellationToken: TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.SampleAsync' instead", ex.Message);
}
[Fact]
public void AsSamplingChatClient_Throws_When_Not_McpServer()
{
var server = new Mock<IMcpServer>(MockBehavior.Strict).Object;
var ex = Assert.Throws<InvalidOperationException>(server.AsSamplingChatClient);
Assert.Contains("Prefer using 'McpServer.AsSamplingChatClient' instead", ex.Message);
}
[Fact]
public void AsClientLoggerProvider_Throws_When_Not_McpServer()
{
var server = new Mock<IMcpServer>(MockBehavior.Strict).Object;
var ex = Assert.Throws<InvalidOperationException>(server.AsClientLoggerProvider);
Assert.Contains("Prefer using 'McpServer.AsClientLoggerProvider' instead", ex.Message);
}
[Fact]
public async Task RequestRootsAsync_Throws_When_Not_McpServer()
{
var server = new Mock<IMcpServer>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await server.RequestRootsAsync(
new ListRootsRequestParams(), TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.RequestRootsAsync' instead", ex.Message);
}
[Fact]
public async Task ElicitAsync_Throws_When_Not_McpServer()
{
var server = new Mock<IMcpServer>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await server.ElicitAsync(
new ElicitRequestParams { Message = "hello" }, TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.ElicitAsync' instead", ex.Message);
}
[Fact]
public async Task SampleAsync_Request_Forwards_To_McpServer_SendRequestAsync()
{
var mockServer = new Mock<McpServer> { CallBase = true };
var resultPayload = new CreateMessageResult
{
Content = new TextContentBlock { Text = "resp" },
Model = "test-model",
Role = Role.Assistant,
StopReason = "endTurn",
};
mockServer
.Setup(s => s.ClientCapabilities)
.Returns(new ClientCapabilities() { Sampling = new() });
mockServer
.Setup(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new JsonRpcResponse
{
Result = JsonSerializer.SerializeToNode(resultPayload, McpJsonUtilities.DefaultOptions),
});
IMcpServer server = mockServer.Object;
var result = await server.SampleAsync(new CreateMessageRequestParams
{
Messages = [new SamplingMessage { Role = Role.User, Content = new TextContentBlock { Text = "hi" } }]
}, TestContext.Current.CancellationToken);
Assert.Equal("test-model", result.Model);
Assert.Equal(Role.Assistant, result.Role);
Assert.Equal("resp", Assert.IsType<TextContentBlock>(result.Content).Text);
mockServer.Verify(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task SampleAsync_Messages_Forwards_To_McpServer_SendRequestAsync()
{
var mockServer = new Mock<McpServer> { CallBase = true };
var resultPayload = new CreateMessageResult
{
Content = new TextContentBlock { Text = "resp" },
Model = "test-model",
Role = Role.Assistant,
StopReason = "endTurn",
};
mockServer
.Setup(s => s.ClientCapabilities)
.Returns(new ClientCapabilities() { Sampling = new() });
mockServer
.Setup(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new JsonRpcResponse
{
Result = JsonSerializer.SerializeToNode(resultPayload, McpJsonUtilities.DefaultOptions),
});
IMcpServer server = mockServer.Object;
var chatResponse = await server.SampleAsync([new ChatMessage(ChatRole.User, "hi")], cancellationToken: TestContext.Current.CancellationToken);
Assert.Equal("test-model", chatResponse.ModelId);
var last = chatResponse.Messages.Last();
Assert.Equal(ChatRole.Assistant, last.Role);
Assert.Equal("resp", last.Text);
mockServer.Verify(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task RequestRootsAsync_Forwards_To_McpServer_SendRequestAsync()
{
var mockServer = new Mock<McpServer> { CallBase = true };
var resultPayload = new ListRootsResult { Roots = [new Root { Uri = "root://a" }] };
mockServer
.Setup(s => s.ClientCapabilities)
.Returns(new ClientCapabilities() { Roots = new() });
mockServer
.Setup(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new JsonRpcResponse
{
Result = JsonSerializer.SerializeToNode(resultPayload, McpJsonUtilities.DefaultOptions),
});
IMcpServer server = mockServer.Object;
var result = await server.RequestRootsAsync(new ListRootsRequestParams(), TestContext.Current.CancellationToken);
Assert.Equal("root://a", result.Roots[0].Uri);
mockServer.Verify(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task ElicitAsync_Forwards_To_McpServer_SendRequestAsync()
{
var mockServer = new Mock<McpServer> { CallBase = true };
var resultPayload = new ElicitResult { Action = "accept" };
mockServer
.Setup(s => s.ClientCapabilities)
.Returns(new ClientCapabilities() { Elicitation = new() });
mockServer
.Setup(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new JsonRpcResponse
{
Result = JsonSerializer.SerializeToNode(resultPayload, McpJsonUtilities.DefaultOptions),
});
IMcpServer server = mockServer.Object;
var result = await server.ElicitAsync(new ElicitRequestParams { Message = "hi" }, TestContext.Current.CancellationToken);
Assert.Equal("accept", result.Action);
mockServer.Verify(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()), Times.Once);
}
}

View file

@ -1,45 +0,0 @@
using ModelContextProtocol.Server;
using ModelContextProtocol.Tests.Utils;
namespace ModelContextProtocol.Tests.Server;
public class McpServerFactoryTests : LoggedTest
{
private readonly McpServerOptions _options;
public McpServerFactoryTests(ITestOutputHelper testOutputHelper)
: base(testOutputHelper)
{
_options = new McpServerOptions
{
ProtocolVersion = "1.0",
InitializationTimeout = TimeSpan.FromSeconds(30)
};
}
[Fact]
public async Task Create_Should_Initialize_With_Valid_Parameters()
{
// Arrange & Act
await using var transport = new TestServerTransport();
await using IMcpServer server = McpServerFactory.Create(transport, _options, LoggerFactory);
// Assert
Assert.NotNull(server);
}
[Fact]
public void Create_Throws_For_Null_ServerTransport()
{
// Arrange, Act & Assert
Assert.Throws<ArgumentNullException>("transport", () => McpServerFactory.Create(null!, _options, LoggerFactory));
}
[Fact]
public async Task Create_Throws_For_Null_Options()
{
// Arrange, Act & Assert
await using var transport = new TestServerTransport();
Assert.Throws<ArgumentNullException>("serverOptions", () => McpServerFactory.Create(transport, null!, LoggerFactory));
}
}

View file

@ -25,7 +25,7 @@ public class McpServerLoggingLevelTests
var provider = services.BuildServiceProvider();
provider.GetRequiredService<IMcpServer>();
provider.GetRequiredService<McpServer>();
}
[Fact]
@ -39,7 +39,7 @@ public class McpServerLoggingLevelTests
var provider = services.BuildServiceProvider();
var server = provider.GetRequiredService<IMcpServer>();
var server = provider.GetRequiredService<McpServer>();
Assert.NotNull(server.ServerOptions.Capabilities?.Logging);
Assert.NotNull(server.ServerOptions.Capabilities.Logging.SetLoggingLevelHandler);
@ -52,7 +52,7 @@ public class McpServerLoggingLevelTests
services.AddMcpServer()
.WithStdioServerTransport();
var provider = services.BuildServiceProvider();
var server = provider.GetRequiredService<IMcpServer>();
var server = provider.GetRequiredService<McpServer>();
Assert.Null(server.ServerOptions.Capabilities?.Logging);
}
}

View file

@ -1,11 +1,9 @@
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
using Moq;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.Json;
@ -43,11 +41,11 @@ public class McpServerPromptTests
}
[Fact]
public async Task SupportsIMcpServer()
public async Task SupportsMcpServer()
{
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
McpServerPrompt prompt = McpServerPrompt.Create((IMcpServer server) =>
McpServerPrompt prompt = McpServerPrompt.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new ChatMessage(ChatRole.User, "Hello");
@ -73,7 +71,7 @@ public class McpServerPromptTests
sc.AddSingleton(expectedMyService);
IServiceProvider services = sc.BuildServiceProvider();
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
mockServer.SetupGet(s => s.Services).Returns(services);
MethodInfo? testMethod = typeof(HasCtorWithSpecialParameters).GetMethod(nameof(HasCtorWithSpecialParameters.TestPrompt));
@ -96,11 +94,11 @@ public class McpServerPromptTests
private sealed class HasCtorWithSpecialParameters
{
private readonly MyService _ms;
private readonly IMcpServer _server;
private readonly McpServer _server;
private readonly RequestContext<GetPromptRequestParams> _request;
private readonly IProgress<ProgressNotificationValue> _progress;
public HasCtorWithSpecialParameters(MyService ms, IMcpServer server, RequestContext<GetPromptRequestParams> request, IProgress<ProgressNotificationValue> progress)
public HasCtorWithSpecialParameters(MyService ms, McpServer server, RequestContext<GetPromptRequestParams> request, IProgress<ProgressNotificationValue> progress)
{
Assert.NotNull(ms);
Assert.NotNull(server);
@ -135,11 +133,11 @@ public class McpServerPromptTests
Assert.DoesNotContain("actualMyService", prompt.ProtocolPrompt.Arguments?.Select(a => a.Name) ?? []);
await Assert.ThrowsAnyAsync<ArgumentException>(async () => await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken));
var result = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Services = services },
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Services = services },
TestContext.Current.CancellationToken);
Assert.Equal("Hello", Assert.IsType<TextContentBlock>(result.Messages[0].Content).Text);
}
@ -160,7 +158,7 @@ public class McpServerPromptTests
}, new() { Services = services });
var result = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("Hello", Assert.IsType<TextContentBlock>(result.Messages[0].Content).Text);
}
@ -173,7 +171,7 @@ public class McpServerPromptTests
_ => new DisposablePromptType());
var result = await prompt1.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("disposals:1", Assert.IsType<TextContentBlock>(result.Messages[0].Content).Text);
}
@ -186,7 +184,7 @@ public class McpServerPromptTests
_ => new AsyncDisposablePromptType());
var result = await prompt1.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("asyncDisposals:1", Assert.IsType<TextContentBlock>(result.Messages[0].Content).Text);
}
@ -199,7 +197,7 @@ public class McpServerPromptTests
_ => new AsyncDisposableAndDisposablePromptType());
var result = await prompt1.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("disposals:0, asyncDisposals:1", Assert.IsType<TextContentBlock>(result.Messages[0].Content).Text);
}
@ -215,7 +213,7 @@ public class McpServerPromptTests
});
var actual = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Same(expected, actual);
@ -232,7 +230,7 @@ public class McpServerPromptTests
});
var actual = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.NotNull(actual);
@ -258,7 +256,7 @@ public class McpServerPromptTests
});
var actual = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.NotNull(actual);
@ -290,7 +288,7 @@ public class McpServerPromptTests
});
var actual = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.NotNull(actual);
@ -317,7 +315,7 @@ public class McpServerPromptTests
});
var actual = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.NotNull(actual);
@ -349,7 +347,7 @@ public class McpServerPromptTests
});
var actual = await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.NotNull(actual);
@ -370,7 +368,7 @@ public class McpServerPromptTests
});
await Assert.ThrowsAsync<InvalidOperationException>(async () => await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken));
}
@ -383,7 +381,7 @@ public class McpServerPromptTests
});
await Assert.ThrowsAsync<InvalidOperationException>(async () => await prompt.GetAsync(
new RequestContext<GetPromptRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<GetPromptRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken));
}

View file

@ -60,7 +60,7 @@ public partial class McpServerResourceTests
var provider = services.BuildServiceProvider();
provider.GetRequiredService<IMcpServer>();
provider.GetRequiredService<McpServer>();
}
@ -96,7 +96,7 @@ public partial class McpServerResourceTests
var provider = services.BuildServiceProvider();
provider.GetRequiredService<IMcpServer>();
provider.GetRequiredService<McpServer>();
}
[Fact]
@ -119,7 +119,7 @@ public partial class McpServerResourceTests
});
var sp = services.BuildServiceProvider();
sp.GetRequiredService<IMcpServer>();
sp.GetRequiredService<McpServer>();
}
[Fact]
@ -143,7 +143,7 @@ public partial class McpServerResourceTests
McpServerResource t;
ReadResourceResult? result;
IMcpServer server = new Mock<IMcpServer>().Object;
McpServer server = new Mock<McpServer>().Object;
t = McpServerResource.Create(() => "42", new() { Name = Name });
Assert.Equal("resource://mcp/Hello", t.ProtocolResourceTemplate.UriTemplate);
@ -153,7 +153,7 @@ public partial class McpServerResourceTests
Assert.NotNull(result);
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
t = McpServerResource.Create((IMcpServer server) => "42", new() { Name = Name });
t = McpServerResource.Create((McpServer server) => "42", new() { Name = Name });
Assert.Equal("resource://mcp/Hello", t.ProtocolResourceTemplate.UriTemplate);
result = await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(server, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello" } },
@ -287,7 +287,7 @@ public partial class McpServerResourceTests
McpServerResource t = McpServerResource.Create((string arg1) => arg1, new() { Name = "Hello" });
Assert.Equal("resource://mcp/Hello{?arg1}", t.ProtocolResourceTemplate.UriTemplate);
Assert.Null(await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = uri } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = uri } },
TestContext.Current.CancellationToken));
}
@ -298,7 +298,7 @@ public partial class McpServerResourceTests
{
McpServerResource t = McpServerResource.Create(() => "resource", new() { UriTemplate = actualUri });
Assert.NotNull(await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = queriedUri } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = queriedUri } },
TestContext.Current.CancellationToken));
}
@ -327,7 +327,7 @@ public partial class McpServerResourceTests
McpServerResource t = McpServerResource.Create((string arg1, int arg2) => arg1, new() { Name = "Hello" });
Assert.Equal("resource://mcp/Hello{?arg1,arg2}", t.ProtocolResourceTemplate.UriTemplate);
await Assert.ThrowsAsync<ArgumentException>(async () => await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = uri } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = uri } },
TestContext.Current.CancellationToken));
}
@ -340,36 +340,36 @@ public partial class McpServerResourceTests
ReadResourceResult? result;
result = await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello" } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello" } },
TestContext.Current.CancellationToken);
Assert.NotNull(result);
Assert.Equal("", ((TextResourceContents)result.Contents[0]).Text);
result = await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello?arg1=first" } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello?arg1=first" } },
TestContext.Current.CancellationToken);
Assert.NotNull(result);
Assert.Equal("first", ((TextResourceContents)result.Contents[0]).Text);
result = await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello?arg2=42" } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello?arg2=42" } },
TestContext.Current.CancellationToken);
Assert.NotNull(result);
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
result = await t.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello?arg1=first&arg2=42" } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Hello?arg1=first&arg2=42" } },
TestContext.Current.CancellationToken);
Assert.NotNull(result);
Assert.Equal("first42", ((TextResourceContents)result.Contents[0]).Text);
}
[Fact]
public async Task SupportsIMcpServer()
public async Task SupportsMcpServer()
{
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return "42";
@ -391,7 +391,7 @@ public partial class McpServerResourceTests
sc.AddSingleton(expectedMyService);
IServiceProvider services = sc.BuildServiceProvider();
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
mockServer.SetupGet(s => s.Services).Returns(services);
MethodInfo? testMethod = typeof(HasCtorWithSpecialParameters).GetMethod(nameof(HasCtorWithSpecialParameters.TestResource));
@ -414,11 +414,11 @@ public partial class McpServerResourceTests
private sealed class HasCtorWithSpecialParameters
{
private readonly MyService _ms;
private readonly IMcpServer _server;
private readonly McpServer _server;
private readonly RequestContext<ReadResourceRequestParams> _request;
private readonly IProgress<ProgressNotificationValue> _progress;
public HasCtorWithSpecialParameters(MyService ms, IMcpServer server, RequestContext<ReadResourceRequestParams> request, IProgress<ProgressNotificationValue> progress)
public HasCtorWithSpecialParameters(MyService ms, McpServer server, RequestContext<ReadResourceRequestParams> request, IProgress<ProgressNotificationValue> progress)
{
Assert.NotNull(ms);
Assert.NotNull(server);
@ -477,7 +477,7 @@ public partial class McpServerResourceTests
McpServerResource resource = services.GetRequiredService<McpServerResource>();
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
await Assert.ThrowsAnyAsync<ArgumentException>(async () => await resource.ReadAsync(
new RequestContext<ReadResourceRequestParams>(mockServer.Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Test" } },
@ -506,7 +506,7 @@ public partial class McpServerResourceTests
}, new() { Services = services, Name = "Test" });
var result = await resource.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Test" } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "resource://mcp/Test" } },
TestContext.Current.CancellationToken);
Assert.NotNull(result);
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
@ -522,7 +522,7 @@ public partial class McpServerResourceTests
_ => new DisposableResourceType());
var result = await resource1.ReadAsync(
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "test://static/resource/instanceMethod" } },
new RequestContext<ReadResourceRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Params = new() { Uri = "test://static/resource/instanceMethod" } },
TestContext.Current.CancellationToken);
Assert.NotNull(result);
Assert.Equal("0", ((TextResourceContents)result.Contents[0]).Text);
@ -533,8 +533,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnReadResult()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new ReadResourceResult { Contents = new List<ResourceContents> { new TextResourceContents { Text = "hello" } } };
@ -550,8 +550,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnResourceContents()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new TextResourceContents { Text = "hello" };
@ -567,8 +567,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnCollectionOfResourceContents()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return (IList<ResourceContents>)
@ -589,8 +589,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnString()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return "42";
@ -606,8 +606,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnCollectionOfStrings()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new List<string> { "42", "43" };
@ -624,8 +624,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnDataContent()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new DataContent(new byte[] { 0, 1, 2 }, "application/octet-stream");
@ -642,8 +642,8 @@ public partial class McpServerResourceTests
[Fact]
public async Task CanReturnCollectionOfAIContent()
{
Mock<IMcpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerResource resource = McpServerResource.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new List<AIContent>

View file

@ -32,12 +32,38 @@ public class McpServerTests : LoggedTest
};
}
[Fact]
public async Task Create_Should_Initialize_With_Valid_Parameters()
{
// Arrange & Act
await using var transport = new TestServerTransport();
await using McpServer server = McpServer.Create(transport, _options, LoggerFactory);
// Assert
Assert.NotNull(server);
}
[Fact]
public void Create_Throws_For_Null_ServerTransport()
{
// Arrange, Act & Assert
Assert.Throws<ArgumentNullException>("transport", () => McpServer.Create(null!, _options, LoggerFactory));
}
[Fact]
public async Task Create_Throws_For_Null_Options()
{
// Arrange, Act & Assert
await using var transport = new TestServerTransport();
Assert.Throws<ArgumentNullException>("serverOptions", () => McpServer.Create(transport, null!, LoggerFactory));
}
[Fact]
public async Task Constructor_Should_Initialize_With_Valid_Parameters()
{
// Arrange & Act
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
// Assert
Assert.NotNull(server);
@ -47,7 +73,7 @@ public class McpServerTests : LoggedTest
public void Constructor_Throws_For_Null_Transport()
{
// Arrange, Act & Assert
Assert.Throws<ArgumentNullException>(() => McpServerFactory.Create(null!, _options, LoggerFactory));
Assert.Throws<ArgumentNullException>(() => McpServer.Create(null!, _options, LoggerFactory));
}
[Fact]
@ -55,7 +81,7 @@ public class McpServerTests : LoggedTest
{
// Arrange, Act & Assert
await using var transport = new TestServerTransport();
Assert.Throws<ArgumentNullException>(() => McpServerFactory.Create(transport, null!, LoggerFactory));
Assert.Throws<ArgumentNullException>(() => McpServer.Create(transport, null!, LoggerFactory));
}
[Fact]
@ -63,7 +89,7 @@ public class McpServerTests : LoggedTest
{
// Arrange & Act
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, null);
await using var server = McpServer.Create(transport, _options, null);
// Assert
Assert.NotNull(server);
@ -74,7 +100,7 @@ public class McpServerTests : LoggedTest
{
// Arrange & Act
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory, null);
await using var server = McpServer.Create(transport, _options, LoggerFactory, null);
// Assert
Assert.NotNull(server);
@ -85,7 +111,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
var runTask = server.RunAsync(TestContext.Current.CancellationToken);
// Act & Assert
@ -100,7 +126,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
SetClientCapabilities(server, new ClientCapabilities());
var action = async () => await server.SampleAsync(new CreateMessageRequestParams { Messages = [] }, CancellationToken.None);
@ -114,7 +140,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
SetClientCapabilities(server, new ClientCapabilities { Sampling = new SamplingCapability() });
var runTask = server.RunAsync(TestContext.Current.CancellationToken);
@ -136,7 +162,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
SetClientCapabilities(server, new ClientCapabilities());
// Act & Assert
@ -148,7 +174,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
SetClientCapabilities(server, new ClientCapabilities { Roots = new RootsCapability() });
var runTask = server.RunAsync(TestContext.Current.CancellationToken);
@ -170,7 +196,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
SetClientCapabilities(server, new ClientCapabilities());
// Act & Assert
@ -182,7 +208,7 @@ public class McpServerTests : LoggedTest
{
// Arrange
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
SetClientCapabilities(server, new ClientCapabilities { Elicitation = new ElicitationCapability() });
var runTask = server.RunAsync(TestContext.Current.CancellationToken);
@ -216,7 +242,7 @@ public class McpServerTests : LoggedTest
[Fact]
public async Task Can_Handle_Initialize_Requests()
{
AssemblyName expectedAssemblyName = (Assembly.GetEntryAssembly() ?? typeof(IMcpServer).Assembly).GetName();
AssemblyName expectedAssemblyName = (Assembly.GetEntryAssembly() ?? typeof(McpServer).Assembly).GetName();
await Can_Handle_Requests(
serverCapabilities: null,
method: RequestMethods.Initialize,
@ -510,7 +536,7 @@ public class McpServerTests : LoggedTest
var options = CreateOptions(serverCapabilities);
configureOptions?.Invoke(options);
await using var server = McpServerFactory.Create(transport, options, LoggerFactory);
await using var server = McpServer.Create(transport, options, LoggerFactory);
var runTask = server.RunAsync(TestContext.Current.CancellationToken);
@ -544,7 +570,7 @@ public class McpServerTests : LoggedTest
await using var transport = new TestServerTransport();
var options = CreateOptions(serverCapabilities);
var server = McpServerFactory.Create(transport, options, LoggerFactory);
var server = McpServer.Create(transport, options, LoggerFactory);
await server.DisposeAsync();
}
@ -589,7 +615,7 @@ public class McpServerTests : LoggedTest
public async Task Can_SendMessage_Before_RunAsync()
{
await using var transport = new TestServerTransport();
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
await using var server = McpServer.Create(transport, _options, LoggerFactory);
var logNotification = new JsonRpcNotification
{
@ -605,22 +631,22 @@ public class McpServerTests : LoggedTest
Assert.Same(logNotification, transport.SentMessages[0]);
}
private static void SetClientCapabilities(IMcpServer server, ClientCapabilities capabilities)
private static void SetClientCapabilities(McpServer server, ClientCapabilities capabilities)
{
PropertyInfo? property = server.GetType().GetProperty("ClientCapabilities", BindingFlags.Public | BindingFlags.Instance);
Assert.NotNull(property);
property.SetValue(server, capabilities);
FieldInfo? field = server.GetType().GetField("_clientCapabilities", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(field);
field.SetValue(server, capabilities);
}
private sealed class TestServerForIChatClient(bool supportsSampling) : IMcpServer
private sealed class TestServerForIChatClient(bool supportsSampling) : McpServer
{
public ClientCapabilities? ClientCapabilities =>
public override ClientCapabilities? ClientCapabilities =>
supportsSampling ? new ClientCapabilities { Sampling = new SamplingCapability() } :
null;
public McpServerOptions ServerOptions => new();
public override McpServerOptions ServerOptions => new();
public Task<JsonRpcResponse> SendRequestAsync(JsonRpcRequest request, CancellationToken cancellationToken)
public override Task<JsonRpcResponse> SendRequestAsync(JsonRpcRequest request, CancellationToken cancellationToken)
{
CreateMessageRequestParams? rp = JsonSerializer.Deserialize<CreateMessageRequestParams>(request.Params, McpJsonUtilities.DefaultOptions);
@ -653,17 +679,17 @@ public class McpServerTests : LoggedTest
});
}
public ValueTask DisposeAsync() => default;
public override ValueTask DisposeAsync() => default;
public string? SessionId => throw new NotImplementedException();
public Implementation? ClientInfo => throw new NotImplementedException();
public IServiceProvider? Services => throw new NotImplementedException();
public LoggingLevel? LoggingLevel => throw new NotImplementedException();
public Task SendMessageAsync(JsonRpcMessage message, CancellationToken cancellationToken = default) =>
public override string? SessionId => throw new NotImplementedException();
public override Implementation? ClientInfo => throw new NotImplementedException();
public override IServiceProvider? Services => throw new NotImplementedException();
public override LoggingLevel? LoggingLevel => throw new NotImplementedException();
public override Task SendMessageAsync(JsonRpcMessage message, CancellationToken cancellationToken = default) =>
throw new NotImplementedException();
public Task RunAsync(CancellationToken cancellationToken = default) =>
public override Task RunAsync(CancellationToken cancellationToken = default) =>
throw new NotImplementedException();
public IAsyncDisposable RegisterNotificationHandler(string method, Func<JsonRpcNotification, CancellationToken, ValueTask> handler) =>
public override IAsyncDisposable RegisterNotificationHandler(string method, Func<JsonRpcNotification, CancellationToken, ValueTask> handler) =>
throw new NotImplementedException();
}
@ -683,7 +709,7 @@ public class McpServerTests : LoggedTest
})],
};
var server = McpServerFactory.Create(transport, options, LoggerFactory);
var server = McpServer.Create(transport, options, LoggerFactory);
Task serverTask = server.RunAsync(TestContext.Current.CancellationToken);

View file

@ -48,11 +48,11 @@ public partial class McpServerToolTests
}
[Fact]
public async Task SupportsIMcpServer()
public async Task SupportsMcpServer()
{
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return "42";
@ -75,7 +75,7 @@ public partial class McpServerToolTests
sc.AddSingleton(expectedMyService);
IServiceProvider services = sc.BuildServiceProvider();
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
mockServer.SetupGet(s => s.Services).Returns(services);
MethodInfo? testMethod = typeof(HasCtorWithSpecialParameters).GetMethod(nameof(HasCtorWithSpecialParameters.TestTool));
@ -98,11 +98,11 @@ public partial class McpServerToolTests
private sealed class HasCtorWithSpecialParameters
{
private readonly MyService _ms;
private readonly IMcpServer _server;
private readonly McpServer _server;
private readonly RequestContext<CallToolRequestParams> _request;
private readonly IProgress<ProgressNotificationValue> _progress;
public HasCtorWithSpecialParameters(MyService ms, IMcpServer server, RequestContext<CallToolRequestParams> request, IProgress<ProgressNotificationValue> progress)
public HasCtorWithSpecialParameters(MyService ms, McpServer server, RequestContext<CallToolRequestParams> request, IProgress<ProgressNotificationValue> progress)
{
Assert.NotNull(ms);
Assert.NotNull(server);
@ -162,7 +162,7 @@ public partial class McpServerToolTests
Assert.DoesNotContain("actualMyService", JsonSerializer.Serialize(tool.ProtocolTool.InputSchema, McpJsonUtilities.DefaultOptions));
Mock<IMcpServer> mockServer = new();
Mock<McpServer> mockServer = new();
var ex = await Assert.ThrowsAsync<ArgumentException>(async () => await tool.InvokeAsync(
new RequestContext<CallToolRequestParams>(mockServer.Object, CreateTestJsonRpcRequest()),
@ -192,7 +192,7 @@ public partial class McpServerToolTests
}, new() { Services = services });
var result = await tool.InvokeAsync(
new RequestContext<CallToolRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<CallToolRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("42", (result.Content[0] as TextContentBlock)?.Text);
}
@ -207,7 +207,7 @@ public partial class McpServerToolTests
options);
var result = await tool1.InvokeAsync(
new RequestContext<CallToolRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<CallToolRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("""{"disposals":1}""", (result.Content[0] as TextContentBlock)?.Text);
}
@ -222,7 +222,7 @@ public partial class McpServerToolTests
options);
var result = await tool1.InvokeAsync(
new RequestContext<CallToolRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()),
new RequestContext<CallToolRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()),
TestContext.Current.CancellationToken);
Assert.Equal("""{"asyncDisposals":1}""", (result.Content[0] as TextContentBlock)?.Text);
}
@ -241,7 +241,7 @@ public partial class McpServerToolTests
options);
var result = await tool1.InvokeAsync(
new RequestContext<CallToolRequestParams>(new Mock<IMcpServer>().Object, CreateTestJsonRpcRequest()) { Services = services },
new RequestContext<CallToolRequestParams>(new Mock<McpServer>().Object, CreateTestJsonRpcRequest()) { Services = services },
TestContext.Current.CancellationToken);
Assert.Equal("""{"asyncDisposals":1,"disposals":0}""", (result.Content[0] as TextContentBlock)?.Text);
}
@ -250,8 +250,8 @@ public partial class McpServerToolTests
[Fact]
public async Task CanReturnCollectionOfAIContent()
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new List<AIContent> {
@ -282,8 +282,8 @@ public partial class McpServerToolTests
[InlineData("data:audio/wav;base64,1234", "audio")]
public async Task CanReturnSingleAIContent(string data, string type)
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return type switch
@ -325,8 +325,8 @@ public partial class McpServerToolTests
[Fact]
public async Task CanReturnNullAIContent()
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return (string?)null;
@ -340,8 +340,8 @@ public partial class McpServerToolTests
[Fact]
public async Task CanReturnString()
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return "42";
@ -356,8 +356,8 @@ public partial class McpServerToolTests
[Fact]
public async Task CanReturnCollectionOfStrings()
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new List<string> { "42", "43" };
@ -372,8 +372,8 @@ public partial class McpServerToolTests
[Fact]
public async Task CanReturnMcpContent()
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return new TextContentBlock { Text = "42" };
@ -389,8 +389,8 @@ public partial class McpServerToolTests
[Fact]
public async Task CanReturnCollectionOfMcpContent()
{
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return (IList<ContentBlock>)
@ -416,8 +416,8 @@ public partial class McpServerToolTests
Content = new List<ContentBlock> { new TextContentBlock { Text = "text" }, new ImageContentBlock { Data = "1234", MimeType = "image/png" } }
};
Mock<IMcpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((IMcpServer server) =>
Mock<McpServer> mockServer = new();
McpServerTool tool = McpServerTool.Create((McpServer server) =>
{
Assert.Same(mockServer.Object, server);
return response;
@ -436,7 +436,7 @@ public partial class McpServerToolTests
[Fact]
public async Task SupportsSchemaCreateOptions()
{
AIJsonSchemaCreateOptions schemaCreateOptions = new ()
AIJsonSchemaCreateOptions schemaCreateOptions = new()
{
TransformSchemaNode = (context, node) =>
{
@ -462,7 +462,7 @@ public partial class McpServerToolTests
{
JsonSerializerOptions options = new() { TypeInfoResolver = new DefaultJsonTypeInfoResolver() };
McpServerTool tool = McpServerTool.Create(() => value, new() { Name = "tool", UseStructuredContent = true, SerializerOptions = options });
var mockServer = new Mock<IMcpServer>();
var mockServer = new Mock<McpServer>();
var request = new RequestContext<CallToolRequestParams>(mockServer.Object, CreateTestJsonRpcRequest())
{
Params = new CallToolRequestParams { Name = "tool" },
@ -480,7 +480,7 @@ public partial class McpServerToolTests
public async Task StructuredOutput_Enabled_VoidReturningTools_ReturnsExpectedSchema()
{
McpServerTool tool = McpServerTool.Create(() => { });
var mockServer = new Mock<IMcpServer>();
var mockServer = new Mock<McpServer>();
var request = new RequestContext<CallToolRequestParams>(mockServer.Object, CreateTestJsonRpcRequest())
{
Params = new CallToolRequestParams { Name = "tool" },
@ -520,7 +520,7 @@ public partial class McpServerToolTests
{
JsonSerializerOptions options = new() { TypeInfoResolver = new DefaultJsonTypeInfoResolver() };
McpServerTool tool = McpServerTool.Create(() => value, new() { UseStructuredContent = false, SerializerOptions = options });
var mockServer = new Mock<IMcpServer>();
var mockServer = new Mock<McpServer>();
var request = new RequestContext<CallToolRequestParams>(mockServer.Object, CreateTestJsonRpcRequest())
{
Params = new CallToolRequestParams { Name = "tool" },