Skip to content

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.