Getting Started Proxying

To use MockServer to analysis an existing system:
- Start MockServer
- Configure Clients
- Run Scenarios
- Analyse Behaviour

To use MockServer to verify requests:
- Start MockServer
- Configure Clients
- Run Your Test Scenarios
- Verify Requests

For example code see the code examples folder in the git repository.
Inspecting AI agent traffic? If you want to see the HTTPS calls that Claude Code, OpenCode, or Python AI libraries send to LLM APIs and MCP servers, see Inspect AI Agent Traffic. It covers proxy setup, CA trust, and per-tool configuration for AI tools.
0. Start MockServer
MockServer is flexible and support numerous usage patterns.
MockServer can be run:
- programmatically via a Java API in an @Before or @After method
- using a JUnit 4 @Rule via a @Rule annotated field in a JUnit 4 test
- using a JUnit 5 Test Extension via a @ExtendWith annotated JUnit 5 class
- using a Spring Test Execution Listener via a @MockServerTest annotated test class
- as a Docker container in any Docker enabled environment
- via a Helm chart in any Kubernetes environment
- from the command line as a stand-alone process in a test environment
- via a Maven Plugin as part of a Maven build cycle
- as a Node.js (npm) module from any Node.js code
- as a Grunt plugin as part of a Grunt build cycle
- as a deployable WAR to an existing application server
To simplify configuration all versions (except the deployable WAR) use a single port to support the control plane and data plane in HTTP, HTTPS or SOCKS.
MockServer is available in the following formats:
- java dependency
- Docker container
- Helm chart for Kubernetes
- executable jar
- Homebrew package
- maven plugin
- npm plugin
- Grunt plugin
- deployable WAR that runs on JEE web servers
It is also possible to build and run MockServer directly from source code
MockServer UI:
MockServer has a UI that can be used to view the internal state within MockServer, including:
1. Configure Clients
The page on configuring clients gives full details on how to configure clients to proxy requests via MockServer and includes code examples for the following clients:
- Java JDK HttpURLConnection
- Apache HttpClient
- Spring RestTemplate
- Google HTTP Client
- Jetty HttpClient
- Jersey Client
- Grizzly AsyncHttpClient
- Java Virtual Machine Network Stack
- Apple Mac HTTP & HTTPS (i.e. Chrome, Safari, Firefox, etc)
- Apple Mac Network Stack (i.e. SOCKS)
3. Analysing Behaviour
To analyse the requests that a system makes the proxy can be used to record all requests and their corresponding responses.
All requests and responses can be retrieved as expectations (called recorded expectations) in Java code or JSON. This allows an easy way to replay a recording from the proxy.
Unlike conventional record-replay approaches typically provided by other proxies, MockServer allows easy editing of the recorded requests because the recording is provided as Java code or JSON. This ensures that if minor changes are made to an API the recording can easily be modified and no re-recording required avoiding the need to update test assertions.
HAR Export
Recorded requests and responses can be exported as a HAR (HTTP Archive) 1.2 file, which is a standard format supported by browser DevTools and other HTTP analysis tools.
To export as HAR, use the retrieve API with type=REQUEST_RESPONSES and format=HAR:
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES&format=HAR"
Automatic Persistence of Recorded Expectations
By default, recorded proxy traffic is only held in memory and lost when MockServer restarts. To automatically persist recorded expectations to a JSON file, configure the following properties:
- persistRecordedExpectations - set to true to enable automatic persistence of recorded expectations
- persistedRecordedExpectationsPath - file path for saving the recorded expectations (default: persistedRecordedExpectations.json)
The file is updated whenever a new request is forwarded through the proxy. The saved file can be loaded back into MockServer using the initializationJsonPath property to replay the recorded traffic.
Retrieving Recorded Expectations
All proxied requests including those proxied using a forward actions are recorded containing the request received and response returned.
It is possible to retrieve the recorded requests and responses as expectations so that they can be easily used as expectations to simulation a system.
Expectations are returned in the order they have been recorded. The expectations are returned can be filter using a request matcher.
Expectation[] recordedExpectations = new MockServerClient("localhost", 1080)
.retrieveRecordedExpectations(
request()
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.retrieveRecordedExpectations({})
.then(
function (recordedExpectations) {
console.log(JSON.stringify(recordedExpectations));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS"
See REST API for full JSON specification
Expectation[] recordedExpectations = new MockServerClient("localhost", 1080)
.retrieveRecordedExpectations(
request()
.withPath("/some/path")
.withMethod("POST")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedExpectations({
"path": "/some/path",
"method": "POST"
}).then(
function (recordedExpectations) {
console.log(JSON.stringify(recordedExpectations));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS" -d '{
"path": "/some/path",
"method": "POST"
}'
See REST API for full JSON specification
String recordedExpectations = new MockServerClient("localhost", 1080)
.retrieveRecordedExpectations(
request()
.withPath("/some/path")
.withMethod("POST"),
Format.JAVA
);
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS&format=JAVA" -d '{
"path": "/some/path"
}'
See REST API for full JSON specification
String recordedExpectations = new MockServerClient("localhost", 1080)
.retrieveRecordedExpectations(
request()
.withPath("/some/path")
.withMethod("POST"),
Format.JSON
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedExpectations({
"path": "/some/path",
"method": "POST"
}).then(
function (recordedExpectations) {
console.log(JSON.stringify(recordedExpectations));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS&format=JSON" -d '{
"path": "/some/path"
}'
See REST API for full JSON specification
Retrieving Recorded Requests
All requests the MockServer receives are recorded, including both proxied requests and requests that have matched an expectation.
It is possible to retrieve the recorded requests, as show below in the code examples.
Requests are returned in the order they have been recorded. Which requests are returned can be filter using a request matcher.
HttpRequest[] recordedRequests = new MockServerClient("localhost", 1080)
.retrieveRecordedRequests(
request()
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.retrieveRecordedRequests({})
.then(
function (recordedRequests) {
console.log(JSON.stringify(recordedRequests));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS"
See REST API for full JSON specification
HttpRequest[] recordedRequests = new MockServerClient("localhost", 1080)
.retrieveRecordedRequests(
request()
.withPath("/some/path")
.withMethod("POST")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequests({
"path": "/some/path",
"method": "POST"
}).then(
function (recordedRequests) {
console.log(JSON.stringify(recordedRequests));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS" -d '{
"path": "/some/path",
"method": "POST"
}'
See REST API for full JSON specification
String recordedRequests = new MockServerClient("localhost", 1080)
.retrieveRecordedRequests(
request()
.withPath("/some/path")
.withMethod("POST"),
Format.JAVA
);
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS&format=JAVA" -d '{
"path": "/some/path"
}'
See REST API for full JSON specification
String recordedRequests = new MockServerClient("localhost", 1080)
.retrieveRecordedRequests(
request()
.withPath("/some/path")
.withMethod("POST"),
Format.JSON
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequests({
"path": "/some/path",
"method": "POST"
}).then(
function (recordedRequests) {
console.log(JSON.stringify(recordedRequests));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS&format=JSON" -d '{
"path": "/some/path"
}'
See REST API for full JSON specification
Retrieve Recorded Requests & Responses
All requests the MockServer receives are recorded, including both proxied requests and requests that have matched an expectation.
It is possible to retrieve the recorded requests and their responses, as show below in the code examples.
Requests and responses are returned in the order they have been recorded. Which requests are returned can be filter using a request matcher.
HttpRequestAndHttpResponse[] httpRequestAndHttpResponse = new MockServerClient("localhost", 1080)
.retrieveRecordedRequestsAndResponses(
request()
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.retrieveRecordedRequestsAndResponses({})
.then(
function (recordedRequestsAndResponses) {
console.log(JSON.stringify(recordedRequestsAndResponses));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES"
See REST API for full JSON specification
HttpRequestAndHttpResponse[] httpRequestAndHttpResponse = new MockServerClient("localhost", 1080)
.retrieveRecordedRequestsAndResponses(
request()
.withPath("/some/path")
.withMethod("POST")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequestsAndResponses({
"path": "/some/path",
"method": "POST"
}).then(
function (recordedRequestsAndResponses) {
console.log(JSON.stringify(recordedRequestsAndResponses));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES" -d '{
"path": "/some/path",
"method": "POST"
}'
See REST API for full JSON specification
String har = new MockServerClient("localhost", 1080)
.retrieveRecordedRequestsAndResponses(
request(),
Format.HAR
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.retrieveRecordedRequestsAndResponsesAsHar({})
.then(
function (har) {
console.log(JSON.stringify(har));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES&format=HAR"
See REST API for full JSON specification
String har = new MockServerClient("localhost", 1080)
.retrieveRecordedRequestsAndResponses(
request()
.withPath("/some/path")
.withMethod("POST"),
Format.HAR
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequestsAndResponsesAsHar({
"path": "/some/path",
"method": "POST"
}).then(
function (har) {
console.log(JSON.stringify(har));
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES&format=HAR" -d '{
"path": "/some/path",
"method": "POST"
}'
See REST API for full JSON specification
3. Verify Requests
MockServer supports verification of requests it has received, including both proxied requests and requests that have matched an expectation.
Verification can be specified as follows:
- a request matcher and a condition indicating the number of times the request should be matched
- a sequence of request matchers that is matched in order
How Verification Works
MockServer records all received requests in an in-memory event log (separate from application logs). Verification checks this event log:
For request matcher count verification: MockServer filters the event log to find all RECEIVED_REQUEST entries matching your request matcher, counts them, and compares the count against your constraint (atLeast(n), exactly(n), etc.). Returns HTTP 202 if the count matches, or HTTP 406 with an error message if it does not.
For expectation ID verification: MockServer retrieves all events associated with the specified expectation ID (including EXPECTATION_RESPONSE and FORWARDED_REQUEST entries) and verifies the count.
For sequence verification: MockServer scans recorded requests in order, checking that each expected request appears after the previous match. This is not a simple count comparison—order matters.
Important notes for parallel testing:
- The event log size is bounded by the
maxLogEntriesconfiguration property (default: minimum of free heap KB / 8 and 100,000 entries—see configuration). When this limit is reached, the oldest entries are evicted. If you run many parallel tests generating thousands of requests, consider increasing this value. - Event recording uses an asynchronous ring buffer. However, verification operations are serialized through the same ring buffer in FIFO order, so a request that has reached MockServer and been recorded will be visible to subsequent verification calls. Intermittent failures are more commonly caused by:
- Your application under test sending requests asynchronously—ensure the application has completed sending before you verify
- Cross-test interference—one test's requests appearing in another test's verification
- Log eviction due to high request volume exceeding
maxLogEntries
- Best practices for parallel tests:
- Use separate MockServer instances (different ports or containers) per test for complete isolation
- If sharing an instance, use unique paths per test (e.g.,
/test/{testId}/...) or unique headers/query parameters in matchers - Avoid broad matchers like only
path("/api")in parallel tests - Be careful with
clear()orreset()—they affect all tests sharing the instance - If verification fails intermittently because your system under test is asynchronous, use retry-with-backoff to wait for requests to arrive (not to wait for MockServer to process already-received requests)
- To retrieve recorded requests for debugging, use
PUT /mockserver/retrieve?type=REQUESTSormockServerClient.retrieveRecordedRequests(null).
For more details on the internal architecture, see the Event System documentation.
Verification Timing
Note: MockServer processes log entries asynchronously using a ring buffer. When calling verify() immediately after sending requests, there may be a brief delay before log entries are available for verification. If verification fails unexpectedly right after requests are sent, add a small delay (e.g., 100ms) before retrying. This is most commonly needed in high-throughput scenarios or when the system under test sends requests asynchronously.
Verifying Repeating Requests
Verify that a request has been received by MockServer a specific number of times using a Verification
new MockServerClient("localhost", 1080)
.verify(
request()
.withPath("/some/path"),
VerificationTimes.atLeast(2)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
'path': '/some/path'
}, 2)
.then(
function () {
console.log("request found at least 2 times");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"httpRequest": {
"path": "/simple"
},
"times": {
"atLeast": 2
}
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
request()
.withPath("/some/path"),
VerificationTimes.atMost(2)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
'path': '/some/path'
}, 0, 2)
.then(
function () {
console.log("request found at most 2 times");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"httpRequest": {
"path": "/simple"
},
"times": {
"atMost": 2
}
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
request()
.withPath("/some/path"),
VerificationTimes.exactly(2)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
'path': '/some/path'
}, 2, 2)
.then(
function () {
console.log("request found exactly 1 time");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"httpRequest": {
"path": "/simple"
},
"times": {
"atLeast": 2,
"atMost": 2
}
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
openAPI(
"https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
),
VerificationTimes.atLeast(2)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
'specUrlOrPayload': 'https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json'
}, 2)
.then(
function () {
console.log("request found exactly 2 times");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"httpRequest": {
"specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
},
"times": {
"atLeast": 2
}
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
openAPI(
"org/mockserver/openapi/openapi_petstore_example.json",
"showPetById"
),
VerificationTimes.once()
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
'specUrlOrPayload': 'org/mockserver/openapi/openapi_petstore_example.json',
'operationId': 'showPetById'
}, 1, 1)
.then(
function () {
console.log("request found exactly 2 times");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"httpRequest": {
"specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json",
"operationId": "showPetById"
},
"times": {
"atLeast": 1,
"atMost": 1
}
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
"31e4ca35-66c6-4645-afeb-6e66c4ca0559",
VerificationTimes.once()
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verifyById(
{
'id': '31e4ca35-66c6-4645-afeb-6e66c4ca0559'
}, 1, 1)
.then(
function () {
console.log("request found exactly 1 time");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"id": "31e4ca35-66c6-4645-afeb-6e66c4ca0559"
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
request()
.withPath("/some/path"),
VerificationTimes.exactly(0)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
'path': '/some/path'
}, 0, true)
.then(
function () {
console.log("request found zero times");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
"httpRequest": {
"path": "/simple"
},
"times": {
"atMost": 0
}
}'
See REST API for full JSON specification
Verifying Request Sequences
Verify that a sequence of requests has been received by MockServer in the specified order using a VerificationSequence
The each request in the sequence will be verified to have been received at least once, in the exact order specified.
new MockServerClient("localhost", 1080)
.verify(
request()
.withPath("/some/path/one"),
request()
.withPath("/some/path/two"),
request()
.withPath("/some/path/three")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verifySequence(
{
'path': '/some/path/one'
},
{
'path': '/some/path/two'
},
{
'path': '/some/path/three'
}
)
.then(
function () {
console.log("request sequence found in the order specified");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verifySequence" -d '{
"httpRequests":[
{
"path":"/some/path/one"
},
{
"path":"/some/path/two"
},
{
"path":"/some/path/three"
}
]
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
request()
.withPath("/status"),
openAPI(
"org/mockserver/openapi/openapi_petstore_example.json",
"listPets"
),
openAPI(
"org/mockserver/openapi/openapi_petstore_example.json",
"showPetById"
)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verifySequence(
{
'path': '/status'
},
{
'specUrlOrPayload': 'org/mockserver/openapi/openapi_petstore_example.json',
'operationId': 'listPets'
},
{
'specUrlOrPayload': 'org/mockserver/openapi/openapi_petstore_example.json',
'operationId': 'showPetById'
}
)
.then(
function () {
console.log("request sequence found in the order specified");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verifySequence" -d '{
"httpRequests":[
{
"path": "/status"
},
{
"specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json",
"operationId": "listPets"
},
{
"specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json",
"operationId": "showPetById"
}
]
}'
See REST API for full JSON specification
new MockServerClient("localhost", 1080)
.verify(
"31e4ca35-66c6-4645-afeb-6e66c4ca0559",
"66c6ca35-ca35-66f5-8feb-5e6ac7ca0559",
"ca3531e4-23c8-ff45-88f5-4ca0c7ca0559"
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verifySequenceById(
{
'id': '31e4ca35-66c6-4645-afeb-6e66c4ca0559'
},
{
'id': '66c6ca35-ca35-66f5-8feb-5e6ac7ca0559'
},
{
'id': 'ca3531e4-23c8-ff45-88f5-4ca0c7ca0559'
}
)
.then(
function () {
console.log("request sequence found in the order specified");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
curl -v -X PUT "http://localhost:1080/mockserver/verifySequence" -d '{
"httpRequests": [
{
"id": "31e4ca35-66c6-4645-afeb-6e66c4ca0559"
},
{
"id": "66c6ca35-ca35-66f5-8feb-5e6ac7ca0559"
},
{
"id": "ca3531e4-23c8-ff45-88f5-4ca0c7ca0559"
}
]
}'
See REST API for full JSON specification