npx claudepluginhub dotnet/skills --plugin dotnet-aiThis skill uses the workspace's default tool permissions.
Test MCP servers at two levels: unit tests for individual tool methods, and integration tests that exercise the full MCP protocol in-memory.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Test MCP servers at two levels: unit tests for individual tool methods, and integration tests that exercise the full MCP protocol in-memory.
mcp-csharp-create firstmcp-csharp-debugmcp-csharp-debug for MCP Inspector| Input | Required | Description |
|---|---|---|
| MCP server project path | Yes | Path to the server .csproj being tested |
| Test framework | Recommended | Default: xUnit. Also supports NUnit or MSTest |
| Transport type | Recommended | Determines integration test approach (stdio vs HTTP) |
dotnet new xunit -n <ServerName>.Tests
cd <ServerName>.Tests
dotnet add reference ../<ServerName>/<ServerName>.csproj
dotnet add package ModelContextProtocol
dotnet add package Moq
dotnet add package FluentAssertions
Test tool methods directly — fastest and most isolated:
public class MyToolTests
{
[Fact]
public void Echo_ReturnsFormattedMessage()
{
var result = MyTools.Echo("Hello");
result.Should().Be("Echo: Hello");
}
[Theory]
[InlineData("")]
[InlineData(" ")]
public void Echo_HandlesEdgeCases(string input)
{
var result = MyTools.Echo(input);
result.Should().StartWith("Echo:");
}
}
For tools with DI dependencies, mock the dependency:
public class ApiToolTests
{
[Fact]
public async Task FetchData_ReturnsApiResponse()
{
var handler = new MockHttpMessageHandler("""{"id": 1}""");
var httpClient = new HttpClient(handler);
var result = await ApiTools.FetchData(httpClient, "resource-1");
result.Should().Contain("id");
}
}
Test the full MCP protocol using a client-server connection:
using ModelContextProtocol.Client;
public class ServerIntegrationTests : IAsyncLifetime
{
private McpClient _client = null!;
public async Task InitializeAsync()
{
var transport = new StdioClientTransport(new StdioClientTransportOptions
{
Name = "TestClient",
Command = "dotnet",
Arguments = ["run", "--project", "../<ServerName>/<ServerName>.csproj"]
});
_client = await McpClient.CreateAsync(transport);
}
public async Task DisposeAsync() => await _client.DisposeAsync();
[Fact]
public async Task Server_ListsExpectedTools()
{
var tools = await _client.ListToolsAsync();
tools.Should().Contain(t => t.Name == "echo");
}
[Fact]
public async Task Tool_ReturnsExpectedResult()
{
var result = await _client.CallToolAsync("echo",
new Dictionary<string, object?> { ["message"] = "Test" });
var text = result.Content.OfType<TextContentBlock>().First().Text;
text.Should().Contain("Test");
}
}
For the SDK's ClientServerTestBase (in-memory testing) and HTTP testing with WebApplicationFactory, see references/test-patterns.md.
# Run all tests
dotnet test
# Run a specific test class
dotnet test --filter "FullyQualifiedName~MyToolTests"
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
Evaluations measure how well an LLM uses your tools. Good evaluation questions should be:
For the evaluation format, example questions, and detailed guidance, see references/evaluations.md.
ListToolsAsync()CallToolAsync()dotnet test| Pitfall | Solution |
|---|---|
Integration test hangs on CreateAsync | Server fails to start. Verify dotnet build succeeds first. For stdio, ensure no stdout logging |
StdioClientTransport not finding project | Use the correct relative path to .csproj from the test project directory |
| Tests pass locally but fail in CI | Run dotnet build before test execution. Use --no-build only after an explicit build step |
Mocking HttpClient is awkward | Mock HttpMessageHandler, not HttpClient directly. See references/test-patterns.md |
| Full test suite runs are slow | Use --filter for development. Run the full suite only for CI verification |
mcp-csharp-create — Create a new MCP server projectmcp-csharp-debug — Running and interactive debuggingmcp-csharp-publish — NuGet, Docker, Azure deploymentClientServerTestBase in-memory pattern, WebApplicationFactory for HTTP, MockHttpMessageHandler helper, test categorization, coverage reporting. Load when: writing integration tests or need detailed mock patterns.