MockServerClient 7.4.0
dotnet add package MockServerClient --version 7.4.0
NuGet\Install-Package MockServerClient -Version 7.4.0
<PackageReference Include="MockServerClient" Version="7.4.0" />
<PackageVersion Include="MockServerClient" Version="7.4.0" />
<PackageReference Include="MockServerClient" />
paket add MockServerClient --version 7.4.0
#r "nuget: MockServerClient, 7.4.0"
#:package MockServerClient@7.4.0
#addin nuget:?package=MockServerClient&version=7.4.0
#tool nuget:?package=MockServerClient&version=7.4.0
MockServerClient for .NET
A hand-written, idiomatic .NET client for MockServer's control-plane REST API.
Installation
The NuGet package is MockServerClient (the assembly and namespace remain MockServer.Client):
dotnet add package MockServerClient
Or via PackageReference in your .csproj:
<PackageReference Include="MockServerClient" Version="7.3.0" />
Supported Targets
- .NET Standard 2.0 (for broad compatibility: .NET Framework 4.6.1+, .NET Core 2.0+, Mono 5.4+)
- .NET 8.0 (for modern APIs and best performance)
Usage
using MockServer.Client;
using MockServer.Client.Models;
// Create client
using var client = new MockServerClient("localhost", 1080);
// Create an expectation with fluent API
client.When(
HttpRequest.Request()
.WithMethod("GET")
.WithPath("/hello")
.WithQueryStringParameter("name", "world")
).Respond(
HttpResponse.Response()
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json")
.WithBody("{\"message\":\"hello world\"}")
);
// Verify the request was received
client.Verify(
HttpRequest.Request().WithPath("/hello"),
VerificationTimes.AtLeastTimes(1)
);
// Reset all expectations
client.Reset();
Forward Expectations
client.When(
HttpRequest.Request().WithPath("/proxy")
).Forward(
HttpForward.Forward()
.WithHost("backend.example.com")
.WithPort(443)
.WithScheme("HTTPS")
);
Verify Sequence
client.VerifySequence(
HttpRequest.Request().WithPath("/first"),
HttpRequest.Request().WithPath("/second")
);
Retrieve Recorded Requests
var requests = client.RetrieveRecordedRequests(
HttpRequest.Request().WithPath("/api")
);
JWT Request Matcher
Match a bearer token's claims (exact or regex; a leading ! negates), plus optional
issuer/audience/algorithm/header/scheme constraints. Unset properties are omitted from the wire.
client.When(
HttpRequest.Request()
.WithPath("/secure")
.WithJwt(new Jwt
{
Claims = new Dictionary<string, string>
{
["sub"] = "user-123",
["role"] = "!admin", // negated: any role except admin
["email"] = "^.+@example.com$" // regex match
},
Issuer = "https://issuer.example.com",
Audience = "my-api",
Algorithm = "RS256"
})
).Respond(
HttpResponse.Response().WithStatusCode(200)
);
ALL_OF Body Matcher
Require the request body to satisfy every sub-matcher. Combine any typed body matchers
(e.g. JSON path and regex) via BodyMatcher:
client.When(
HttpRequest.Request()
.WithPath("/api")
.WithAllOfBody(
BodyMatcher.OfJsonPath("$.name"),
BodyMatcher.OfRegex(".*active.*"))
).Respond(
HttpResponse.Response().WithStatusCode(200)
);
Async API
All operations have async variants:
await client.VerifyAsync(
HttpRequest.Request().WithPath("/hello"),
VerificationTimes.AtLeastTimes(1)
);
Interactive Breakpoints
Register breakpoint matchers to pause forwarded/proxied traffic at REQUEST, RESPONSE, RESPONSE_STREAM, or INBOUND_STREAM phases. A callback WebSocket connection is opened automatically.
using MockServer.Client.Models;
using System.Text.Json.Nodes;
// REQUEST-only breakpoint
var id = client.AddRequestBreakpoint(
HttpRequest.Request().WithPath("/api/.*").Build(),
request => request // continue with original
);
// REQUEST + RESPONSE breakpoint
var id2 = client.AddRequestResponseBreakpoint(
HttpRequest.Request().WithPath("/api/.*").Build(),
request => request,
(request, response) => response
);
// Streaming breakpoint
var id3 = client.AddStreamBreakpoint(
HttpRequest.Request().WithPath("/stream/.*").Build(),
new[] { BreakpointPhase.ResponseStream },
frame => StreamFrameDecision.Continue(frame.CorrelationId!)
);
// Manage matchers
var list = client.ListBreakpointMatchers();
client.RemoveBreakpointMatcher(id);
client.ClearBreakpointMatchers();
Stream frame decisions: StreamFrameDecision.Continue, .Modify, .Drop, .Inject, .Close.
Mocking LLM providers
The MockServer.Client.Llm namespace provides fluent builders that mock LLM provider
APIs (Anthropic, OpenAI, Gemini, Bedrock, Azure OpenAI, Ollama). They build
expectations carrying an httpLlmResponse action; the produced wire JSON is
equivalent to the Java/Node/Python clients, so a mock scripted here behaves
identically to one scripted elsewhere.
Single completion / embedding
using MockServer.Client.Llm;
// A single chat completion mock.
LlmMockBuilder.LlmMock("/v1/chat/completions")
.WithProvider(Provider.OPENAI)
.WithModel("gpt-4o")
.RespondingWith(Completion.Create()
.WithText("Hello! How can I help?")
.WithStopReason("stop")
.WithUsage(Usage.Create().WithInputTokens(12).WithOutputTokens(8)))
.ApplyTo(client);
// An embedding mock.
LlmMockBuilder.LlmMock("/v1/embeddings")
.WithProvider(Provider.OPENAI)
.RespondingWith(EmbeddingResponse.Create().WithDimensions(1536).WithDeterministicFromInput(true))
.ApplyTo(client);
Completions also support tool calls (WithToolCall(ToolUse.Of("name")...)), structured
output (WithOutputSchema), and streaming physics (Stream().WithStreamingPhysics( StreamingPhysics.Create().WithTokensPerSecond(50).WithJitter(0.2))).
Multi-turn conversations
Conversation mocks advance MockServer scenario state turn-by-turn (Started → turn_1
→ ... → __done). Optionally isolate concurrent sessions by a request header,
query parameter, or cookie.
LlmConversationBuilder.Conversation()
.WithPath("/v1/chat/completions")
.WithProvider(Provider.ANTHROPIC)
.WithModel("claude-3-5-sonnet")
.IsolateBy(IsolationSource.Header("x-session-id"))
.Turn().RespondingWith(Completion.Create().WithText("Hi, I'm your assistant."))
.Turn().WhenLatestMessageContains("weather")
.RespondingWith(Completion.Create().WithText("It's sunny."))
.Turn().RespondingWith(Completion.Create().WithText("Anything else?"))
.ApplyTo(client);
Failover / retry scenarios
Emit N failing responses (consumed first) followed by a success. Consecutive identical
failures are coalesced into a single limited-times expectation; each failure gets a
provider-shaped default error body unless you supply one.
LlmFailoverBuilder.LlmFailover()
.WithPath("/v1/chat/completions")
.WithProvider(Provider.OPENAI)
.WithModel("gpt-4o")
.FailWith(429, count: 2) // two rate-limit responses
.FailWith(503) // then one service-unavailable
.ThenRespondWith(Completion.Create().WithText("recovered"))
.ApplyTo(client);
Mocking an MCP server
The MockServer.Client.Mcp namespace builds the expectation set needed to emulate a
Streamable-HTTP MCP (Model Context Protocol) server speaking JSON-RPC 2.0. It wires up
initialize, ping, notifications/initialized, and per-capability */list and
*/call (or */read / */get) handlers.
using MockServer.Client.Mcp;
McpMockBuilder.McpMock("/mcp")
.WithServerName("WeatherServer")
.WithTool("get_weather")
.WithDescription("Get the weather for a city")
.WithInputSchema("{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}}}")
.RespondingWith("72F and sunny")
.And()
.WithResource("file:///config.json")
.WithName("config")
.WithMimeType("application/json")
.WithContent("{\"debug\":true}")
.And()
.WithPrompt("greeting")
.WithArgument("name", "the name to greet", required: true)
.RespondingWith("user", "Hello!")
.And()
.ApplyTo(client);
Each builder also exposes Build() returning the raw List<Expectation> if you want to
inspect or register them yourself.
Mocking an A2A agent
The MockServer.Client.A2a namespace builds the expectation set needed to emulate an
A2A (Agent2Agent) server. It serves a GET agent-card document at /.well-known/agent.json
plus JSON-RPC 2.0 tasks/send, tasks/get, and tasks/cancel handlers, and can optionally
advertise and mock streaming (SSE) and push notifications.
using MockServer.Client.A2a;
A2aMockBuilder.A2aMock("/a2a")
.WithAgentName("WeatherAgent")
.WithAgentDescription("Knows the weather")
.WithSkill("get_weather")
.WithName("Get Weather")
.WithDescription("Returns the weather for a city")
.WithTag("weather")
.WithExample("What is the weather in London?")
.And()
.OnTaskSend()
.MatchingMessage("hello.*")
.RespondingWith("Hi there!")
.And()
.WithStreaming()
.WithPushNotifications("http://localhost:1234/a2a/callback")
.ApplyTo(client);
When streaming is enabled the agent card reports capabilities.streaming: true and the
streaming method (default message/stream) returns an SSE stream of status-update and
artifact-update events. When push notifications are configured the agent card reports
capabilities.pushNotifications: true, tasks/pushNotificationConfig/set echoes the
registered config, and each tasks/send both returns the JSON-RPC response to the caller
and POSTs the completed task to the configured webhook. As with the MCP builder, Build()
returns the raw List<Expectation> if you want to inspect or register them yourself.
Start / Launch MockServer
The .NET client can download and launch a local MockServer instance directly -- no Java installation and no Docker required. The launcher downloads a self-contained platform bundle (mockserver-<version>-<os>-<arch>) from the GitHub Release, verifies its SHA-256, caches it per-user, and starts it.
Quick start
using MockServer.Client;
// Download (first run) and start MockServer on port 1080
using var launcher = MockServerBinaryLauncher.Start(port: 1080);
Console.WriteLine($"MockServer started, PID {launcher.Process?.Id}");
// ... use MockServer ...
launcher.Stop();
// or let the using statement dispose and stop it automatically
Async API
using var launcher = await MockServerBinaryLauncher.StartAsync(port: 1080);
Just ensure the binary is present
string launcherPath = await MockServerBinaryLauncher.EnsureBinaryAsync();
// or synchronously:
string launcherPath = MockServerBinaryLauncher.EnsureBinary();
Specify a version
using var launcher = MockServerBinaryLauncher.Start(port: 1080, version: "7.3.0");
API reference
| Method / Class | Description |
|---|---|
MockServerBinaryLauncher.EnsureBinaryAsync(version?, options?) |
Download, verify, cache, and return the launcher path. Defaults to DefaultVersion. |
MockServerBinaryLauncher.EnsureBinary(version?, options?) |
Synchronous wrapper for EnsureBinaryAsync. |
MockServerBinaryLauncher.StartAsync(port, version?, options?) |
Ensure the binary and start MockServer. Returns a MockServerBinaryLauncher instance. |
MockServerBinaryLauncher.Start(port, version?, options?) |
Synchronous wrapper for StartAsync. |
MockServerBinaryLauncher |
Implements IDisposable. Properties: Process. Methods: Stop(), Dispose(). |
MockServerBinaryLauncher.DefaultVersion |
The default MockServer version, derived from the NuGet package version at runtime. |
Supported platforms
| OS | Architecture |
|---|---|
| Linux | x86_64, aarch64 |
| macOS (darwin) | x86_64, aarch64 |
| Windows | x86_64, aarch64 |
Environment variables
| Variable | Purpose |
|---|---|
MOCKSERVER_BINARY_BASE_URL |
Mirror host for the release assets (corporate / air-gapped networks) |
MOCKSERVER_BINARY_CACHE |
Override the cache directory (default: ~/.cache/mockserver/binaries on Unix, %LOCALAPPDATA% on Windows) |
MOCKSERVER_SKIP_BINARY_DOWNLOAD |
Fail instead of downloading (use with a pre-seeded cache in CI) |
Version
By default the launcher downloads the MockServer version matching this NuGet package (derived from the <Version> property in the .csproj at build time). Pass an explicit version argument to override.
Building
cd mockserver-client-dotnet
dotnet build
dotnet test
Using in tests (xUnit)
MockServerFixture is a reusable xUnit IAsyncLifetime fixture that creates a
MockServerClient and resets the server before and after each test, so recorded
requests, expectations and logs never leak between tests. Derive your test class
from it, or use it as an IClassFixture / collection fixture for a shared
instance:
public class MyTests : MockServerFixture
{
[SkippableFact]
public void RecordsRequest()
{
SkipIfNoServer();
// Client is reset before this test and again after it finishes.
Client!.MockAnyResponse(/* ... */);
}
}
The server URL is read from the MOCKSERVER_URL environment variable (for
example http://localhost:1080); when it is unset the fixture's lifecycle hooks
are no-ops and tests are skipped via SkipIfNoServer().
Requirements
- .NET SDK 8.0+ (for building)
System.Net.WebSockets.ClientWebSocket(built-in, for breakpoint callback WebSocket)- No external runtime dependencies beyond
System.Text.Json(included via .NET or NuGet for netstandard2.0)
License
Apache 2.0 - see LICENSE
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 8.0.0)
- System.Net.Http (>= 4.3.4)
- System.Text.Json (>= 8.0.5)
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on MockServerClient:
| Package | Downloads |
|---|---|
|
MockServer.Testcontainers
Testcontainers module for MockServer — starts a mockserver/mockserver Docker container, waits for readiness, and exposes connection helpers. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 7.4.0 | 61 | 7/4/2026 |
| 7.3.0 | 62 | 7/1/2026 |
| 7.2.0 | 71 | 6/22/2026 |
| 7.1.0 | 234 | 6/16/2026 |
| 7.0.0-alpha.1 | 50 | 6/11/2026 |