CLI Integration
The TraceCov CLI generates coverage reports from recorded API traffic and can act as a proxy to capture live traffic.
Installation
curl -sL https://cli.tracecov.sh/install/ | sh
chmod +x tracecov
Verify the installation:
tracecov --version
Basic Usage
Generate an HTML report from JSON traffic data:
tracecov report openapi.json traffic.json
This creates coverage.html by default and prints a summary:
TraceCov v0.24.2
Report saved to: coverage.html
Operations 1/2 (50%)
Parameters 0/2 (0%)
Keywords 1/3 (33%)
Responses 1/3 (33%)
Response Keywords 5/5 (100%)
Use -o to specify a different path.
If the report shows 0% operations while the traffic file has requests, the request URLs carry a prefix the schema paths do not. Pass it with -b/--base-path:
# Schema has paths like /users; requests go to https://api.example.com/v1/users
tracecov report openapi.json traffic.json --base-path https://api.example.com/v1
Traffic Format
Example traffic file:
{
"interactions": [
{
"request": {
"method": "GET",
"url": "https://api.example.com/users/1",
"headers": {}
},
"response": {
"status_code": 200,
"elapsed": 0.05,
"body": "{\"id\": 1, \"name\": \"Alice\"}",
"headers": {"Content-Type": "application/json"}
},
"timestamp": 1700000000.0
}
]
}
Each interaction contains a request, an optional response, and an optional timestamp:
| Field | Type | Required | Description |
|---|---|---|---|
request.method |
string | Yes | HTTP method (GET, POST, PUT, DELETE, etc.) |
request.url |
string | Yes | Full URL including query parameters |
request.headers |
object | Yes | HTTP headers as key-value pairs; {} when there are none |
request.body |
string | No | Request body as UTF-8 text |
request.body_base64 |
string | No | Request body as base64-encoded binary |
response.status_code |
integer | Yes, when response is present |
HTTP status code |
response.elapsed |
float | No | Response time in seconds |
response.body |
string | No | Response body as UTF-8 text |
response.body_base64 |
string | No | Response body as base64-encoded binary |
response.headers |
object | No | HTTP headers as key-value pairs |
timestamp |
float | No | Unix timestamp in seconds |
Response keyword coverage needs both response.body and a Content-Type in response.headers.
Body Encoding
Use body for text content (JSON, XML, form data):
{
"request": {
"method": "POST",
"url": "https://api.example.com/users",
"body": "{\"name\": \"Alice\", \"email\": \"alice@example.com\"}",
"headers": {"Content-Type": "application/json"}
}
}
Use body_base64 for binary content (images, files):
{
"request": {
"method": "POST",
"url": "https://api.example.com/upload",
"body_base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
"headers": {"Content-Type": "image/png"}
}
}
Omit both fields for requests without a body (GET, DELETE).
Output Formats
HTML (default) - Interactive coverage report, writes to coverage.html:
tracecov report openapi.json traffic.json
JSON - Machine-readable output for CI (see JSON Report Format for schema and jq recipes):
# Output to stdout (for piping to jq)
tracecov report openapi.json traffic.json --format json
# Use in CI scripts
tracecov report openapi.json traffic.json --format json | jq '.summary.operations'
# Save to file
tracecov report openapi.json traffic.json --format json -o coverage.json
--suggestions (Professional) adds suggested requests that close coverage gaps under suggestions. It works with --format json only and takes extra time:
tracecov report openapi.json traffic.json --format json --suggestions
Markdown - Summary tables for CI job summaries and pull request comments; writes to stdout unless -o is given:
tracecov report openapi.json traffic.json --format markdown -o coverage.md
--markdown-columns picks the columns: any of parameters, keywords, responses, examples, comma-separated.
Coverage Thresholds
Fail the build if coverage is below a threshold:
# Fail if any metric is below 80%
tracecov report openapi.json traffic.json --fail-under 80
# Per-metric thresholds
tracecov report openapi.json traffic.json \
--fail-under-operations 90 \
--fail-under-parameters 70
# Base threshold with override
tracecov report openapi.json traffic.json --fail-under 80 --fail-under-operations 95
Available flags:
--fail-under--fail-under-operations--fail-under-parameters--fail-under-keywords--fail-under-examples--fail-under-responses--fail-under-response-keywords- not set by--fail-under; pass it explicitly
Also works with tracecov proxy.
Exit codes: 0 = success, 1 = threshold not met or error.
Professional Features
Professional Edition
The following features require TraceCov Professional.
Proxy Mode
Capture traffic from any HTTP client by running a local proxy:
# Start the proxy (runs until Ctrl+C)
tracecov proxy openapi.json -p 8080
Configure your HTTP client to use the proxy, then run your tests. Most clients respect standard environment variables:
# Set proxy for all HTTP clients
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
# Run your tests
pytest tests/
Or configure directly in your code:
# httpx
httpx.get("https://api.example.com/users", proxy="http://localhost:8080", verify="/tmp/tracecov-ca.pem")
# requests
requests.get(
"https://api.example.com/users",
proxies={"all": "http://localhost:8080"},
verify="/tmp/tracecov-ca.pem",
)
HTTPS requests need the proxy's CA certificate; see HTTPS Traffic.
Or per-request in shell:
# curl (use -k to skip certificate verification, or --cacert for the CA)
curl -k --proxy http://localhost:8080 https://api.example.com/users
Press Ctrl+C to stop the proxy. TraceCov generates coverage.html with all captured traffic.
Use -v to see each request as it's proxied:
tracecov proxy openapi.json -v
HTTPS Traffic
Trust the proxy's CA certificate, or HTTPS requests fail with TLS errors.
The proxy writes the certificate to tracecov-ca.pem in the system temp directory (/tmp/tracecov-ca.pem on Linux) and prints its path at startup as CA cert. Use --export-ca for a custom path.
# curl: trust the CA
curl --cacert /tmp/tracecov-ca.pem --proxy http://localhost:8080 https://api.example.com
# curl: skip verification
curl -k --proxy http://localhost:8080 https://api.example.com
# Python requests
session.verify = "/tmp/tracecov-ca.pem"
# Python httpx
client = httpx.Client(verify="/tmp/tracecov-ca.pem", proxy="http://localhost:8080")
Base Path Matching
Use --base-path to specify the URL prefix that maps to your schema's root. This is needed when requests go to a full URL but your schema paths are relative:
# Schema has paths like /users, /pets
# Requests go to https://api.example.com/v1/users
tracecov proxy openapi.json --base-path https://api.example.com/v1
Without --base-path, the proxy matches request paths directly against schema paths.
Forwarding to One Upstream
--upstream turns the proxy around: it listens, forwards everything to that origin, and your tests point at the proxy's own address. No proxy settings, no CA, and it works with any HTTP client in any language.
tracecov proxy openapi.json -p 9000 --upstream http://localhost:8000
BASE_URL=http://localhost:9000 pytest tests/
--run goes further and takes the port your tests already use, starting the app on a free one:
tracecov proxy openapi.json -p 8000 --run "uvicorn app:app --port {upstream_port}"
{upstream_port} is replaced with the port the app should listen on, and PORT is set to it. The command stops when the proxy stops. Nothing in the test suite changes.
Neither mode sees requests that never reach a socket - Django's test client, flask.test_client(), FastAPI's TestClient and supertest all bypass the network. Use the Python integrations for those.
Labels
Send X-TraceCov-Labels with a request to credit what it covers to those labels, comma-separated:
curl -H "X-TraceCov-Labels: orders, PAYMENT-42" http://localhost:9000/orders
The proxy removes the header before forwarding, and the JSON report lists coverage per label under labels. --traffic-output does not keep labels. See Which Tests Cover What.
MCP Server
tracecov mcp records traffic exactly like proxy and answers tool calls from a coding agent over stdio:
claude mcp add tracecov -- tracecov mcp openapi.json
Clients without an mcp add command take a mcpServers entry: .cursor/mcp.json for Cursor, claude_desktop_config.json for Claude Desktop.
{
"mcpServers": {
"tracecov": {
"command": "tracecov",
"args": ["mcp", "openapi.json", "--upstream", "http://127.0.0.1:8000"]
}
}
}
It forwards to the origin in servers[0].url, so a schema naming one needs nothing else. --upstream, --run and --base-path work as they do for proxy; --forward acts as a forward proxy instead, with --export-ca for HTTPS.
The agent's tests must send requests to the proxy, http://127.0.0.1:8080 by default (-p changes the port), not to the app. The tool reports this address as service_url. Requests that never reach a socket are not seen, as for proxy above.
--request-budget 100 answers 429 after 100 forwarded requests, bounding the agent's run.
--scope /api/orders limits the gaps and their totals to the operations under that path prefix. Pick a scope small enough for the budget to request every operation in it.
One tool:
| Tool | Answers |
|---|---|
tracecov_gaps |
Coverage totals per metric, then unseen operations, uncovered parameters and responses, and keywords that need a valid or an invalid value, each with its satisfiability, and the paths sent that match no operation. budget caps how many gaps are listed. |
The agent writes tests, runs them through the proxy, and calls tracecov_gaps again to see what closed. A report is written on disconnect only when --output names one.
Traffic Imports
Professional Edition
The Professional edition supports HAR files, Postman collections, and VCR cassettes out of the box. The format is detected from the file contents, so the command is the same for each:
# Browser or proxy capture
tracecov report openapi.json traffic.har
# Postman collection export (v1.0, v2.0, v2.1); saved example responses count toward response coverage
tracecov report openapi.json collection.postman_collection.json
# VCR or Schemathesis cassette
tracecov report openapi.json cassette.yaml
# Several files at once, in any mix of formats
tracecov report openapi.json collection.postman_collection.json traffic.har
Each file may be JSON or YAML.