cf-integration 0.3.1

Integration and conformance harness for ContextForge control-plane and data-plane services
Documentation

cf-integration

cf-integration manages ContextForge Docker stacks and runs probes, load tests, live gateway checks, and official MCP conformance. Routed traffic uses one of two lanes:

  • builtin: the Python dataplane in cf-controlplane.
  • external: the Rust cf-dataplane.

/servers/{virtual_host_id}/mcp routes to the external dataplane. Raw /mcp and control-plane UI/API traffic route to cf-controlplane; there is no fallback between them.

Install

cargo binstall cf-integration
# or
cargo install cf-integration --locked

Use cargo run -- before a command when running this checkout. Runtime use requires Docker Compose v2, Git, and Node.js 22.7.5 or newer. Rust 1.97 is needed only to compile the CLI or a local dataplane image.

Published images are the default. Set CF_DATAPLANE_REF to build and test a local dataplane ref.

Selection

Routed commands accept --lane builtin|external; external is the default. Conformance and protocol-only live tests also accept fixture-direct. stack down accepts all. No command accepts the old --topology option.

Commands that exercise MCP accept --protocol-version modern|legacy:

  • modern: current per-request, stateless MCP.
  • legacy: current initialization-based MCP.

The CLI deliberately does not expose dated wire revisions. Defaults may be set with CF_MCP_LANE and MCP_PROTOCOL_VERSION.

Add the global --standalone flag to run the external lane without any control plane. Standalone mode starts Redis, the Rust dataplane, nginx, and the required test fixture. It generates an ephemeral RSA key, obtains a test token from the dataplane's local tool endpoint, validates it through the dataplane's loopback JWKS endpoint, and publishes a fresh config through the dataplane serializer. Redis therefore always contains the schema understood by the image under test. Standalone commands also work from an installed binary without control-plane checkouts or generated control-plane secrets. Routes and tool schemas are discovered from every catalog page of the running fixture, including the selected protocol era's diagnostic tools and prompts.

Use cf-integration <command> --help for the complete interface.

Stack

Use a persistent stack for manual testing:

cf-integration stack up --lane builtin --protocol-version modern
cf-integration stack up --lane external --protocol-version legacy --fresh
cf-integration stack up --lane external --protocol-version legacy --standalone

cf-integration stack status --lane external --standalone
cf-integration stack logs --lane external --standalone
cf-integration stack logs --lane external --standalone dataplane nginx
cf-integration stack config --lane external --standalone

cf-integration stack down --lane external --standalone
cf-integration stack down --lane all
cf-integration stack down --lane all --volumes

up --fresh and down --volumes remove the selected stack's volumes. ClickStack has an independent lifecycle and is intentionally left running by all stack and managed-test cleanup.

Probe

Probe authentication, protocol lifecycle, backend identity, catalog selection, and a safe routed tool call:

cf-integration probe --lane builtin --protocol-version modern
cf-integration probe --lane external --protocol-version legacy
cf-integration probe --lane external --protocol-version legacy --standalone

For standalone external runs, the known catalog comes from the mocked Redis snapshot because the Rust dataplane intentionally does not implement fan-out tools/list.

Load

# Compare both lanes for two minutes
cf-integration load --lane builtin --protocol-version legacy \
  --users 10 --spawn-rate 2 --run-time 2m
cf-integration load --lane external --protocol-version legacy \
  --users 10 --spawn-rate 2 --run-time 2m

# Isolate the external dataplane and mocked Redis
cf-integration load --lane external --protocol-version legacy --standalone \
  --users 10 --spawn-rate 2 --run-time 2m

# Include telemetry when diagnostic value matters more than benchmark purity
cf-integration load --lane external --protocol-version modern --standalone \
  --observability --users 10 --spawn-rate 2 --run-time 2m

--smoke selects a short workload. Durations accept ordered positive h, m, and s groups such as 2m30s. Defaults are 100 users, 10 users/s, and 5m, overridable with LOCUST_USERS, LOCUST_SPAWN_RATE, and LOCUST_RUN_TIME. Observability is opt-in for load tests to avoid skew.

Live gateway checks

Groups are mcp, rbac, protocol, and all (default):

cf-integration live --lane builtin --protocol-version legacy --group all
cf-integration live --lane external --protocol-version modern --group all
cf-integration live --lane fixture-direct --protocol-version legacy --group protocol

Routed runs execute the upstream control-plane live suites. live --standalone is unsupported because these suites require the control plane. Use cf-integration probe --lane external --standalone for isolated authentication, protocol, and routed tool-call checks.

Conformance

run executes the pinned official MCP suite and compares results with checked-in baselines. With no selectors it runs all three lanes with a modern client against legacy and modern fixtures.

cf-integration conformance run

cf-integration conformance run \
  --lane fixture-direct --lane builtin --lane external \
  --client-era legacy --client-era modern \
  --server-era legacy --server-era modern

cf-integration conformance run --lane external --standalone \
  --client-era modern --server-era modern

cf-integration conformance run --lane external --standalone \
  --client-era modern --server-era modern --bless

--client-era and --server-era accept legacy, modern, or dual. --bless replaces only the selected baselines and only after every selected run succeeds. --standalone permits the external lane only. Ctrl-C finishes cleanup for the active run, skips the remaining matrix entries, and leaves baselines unchanged.

Regenerate Markdown from existing results without running tests:

cf-integration conformance report
cf-integration conformance report \
  --results-dir .integration/conformance --output-dir reports/conformance

Debug

cf-integration debug inspect --lane external \
  --protocol-version modern --method tools/list
cf-integration debug inspect --lane builtin \
  --protocol-version legacy --server-id <virtual-server-id>

cf-integration debug token --kind scoped
cf-integration debug token --kind scoped --server-id <virtual-server-id>
cf-integration debug token --kind admin

# Issue a token from an already-running standalone external stack
cf-integration debug token --kind scoped --standalone

inspect uses the official MCP Inspector. Control-plane tokens are revoked when the workflow owns them; caller-supplied MCPGATEWAY_BEARER_TOKEN values are never revoked.

Observability and artifacts

ClickStack starts by default for stack, probe, live, conformance, and Inspector workflows. Open the no-login HyperDX UI at http://127.0.0.1:3000. Logs open by default; for metrics use Chart Explorer, choose the Metrics source and a metric such as http.server.request.duration, then run the query. Allow at least 60 seconds of traffic for multiple 30-second cumulative exports. Telemetry storage is ephemeral inside ClickStack.

Load reports are written below CF_INTEGRATION_DIR/reports/load, conformance results below CF_INTEGRATION_DIR/conformance, and comparison Markdown below reports/conformance. Copy .env.example for the complete configuration list. Process environment values override .env.