cf-integration is the standalone Rust CLI for exercising cf-controlplane
with either its built-in Python data plane or the external Rust
cf-dataplane.
The routing contract is fixed:
/servers/{virtual_host_id}/mcproutes throughcf-dataplane.- Raw
/mcp, UI, and API traffic route tocf-controlplane. - The external dataplane fails closed and never falls back to the control plane.
The CLI owns Docker Compose overlays, nginx routing, source checkout orchestration, MCP probes, Locust load tests, upstream live tests, and official MCP conformance runs.
Release archives cover ARM64 and x86-64 Linux, macOS, and Windows.
cargo binstall cf-integration
cf-integration --helpTo compile from crates.io or this checkout:
cargo install cf-integration --locked
cargo install --path . --lockedThe installed binary is repository-independent. Required Compose overlays, runtime scripts, and conformance baselines are embedded in the executable.
The CLI resolves the action before initializing state. Runtime-backed actions resolve assets in this order:
- explicit
CF_INTEGRATION_ROOT, which must be a valid developer checkout; - the current directory, when it contains a valid checkout;
- a versioned embedded-asset tree beneath
CF_INTEGRATION_DIR.
Embedded assets are materialized atomically, verified byte-for-byte, marked read-only, and reused. Concurrent first runs converge on one complete tree. A corrupt or incomplete versioned tree fails closed.
.env is loaded from CF_INTEGRATION_ROOT when set, otherwise the current
directory. Relative paths resolve from that workspace. Generated checkouts,
assets, secrets, reports, and runtime state default to .integration/.
conformance report and debug token do not materialize assets or generate
local Compose secrets. Compose-backed actions initialize them lazily.
Runtime requirements depend on the command:
- Docker Engine with Docker Compose v2 for stack-backed workflows;
- Git for managed source checkouts;
- Node.js 22.7.5 or newer with
npxfor Inspector, live, and conformance; - the control-plane checkout's Python/Locust dependencies for load tests;
- Rust 1.97 only when compiling the CLI or local source images.
Published control-plane and data-plane images are used by default. Local
data-plane builds require an explicit CF_DATAPLANE_REF.
cf-integration
├── stack
│ ├── up
│ ├── down
│ ├── status
│ ├── logs
│ └── config
├── probe
├── load
├── live
├── conformance
│ ├── run
│ └── report
└── debug
├── inspect
└── token
Use --help at any level for the authoritative interface.
Every resolved command reports its lifecycle on standard error using the same
description: ⠋ while active, ✓ in green on success, and ✗ in red on
failure. Test results use aligned nextest-style labels: green PASS, yellow
XFAIL, red XPASS and FAIL, and yellow SKIP. NO_COLOR and
CARGO_TERM_COLOR control ANSI output. Command data such as tokens, Compose
configuration, and report paths remains on standard output for scripting.
Stack commands use physical --topology controlplane|dataplane:
cf-integration stack up --topology dataplane
cf-integration stack up --topology dataplane --fresh
cf-integration stack status --topology dataplane
cf-integration stack config --topology dataplane
cf-integration stack down --topology all
cf-integration stack down --topology all --volumesstack down --volumes is the explicit destructive reset. Managed workflows
preserve the primary failure, attempt every token and stack cleanup, and report
all cleanup failures.
Probe, load, and Inspector use physical lanes:
cf-integration probe --lane dataplane --protocol-version 2026-07-28
cf-integration load --lane dataplane --smoke
cf-integration debug inspect --lane dataplane --method tools/listLive and conformance share semantic lanes: fixture-direct,
built-in-data-plane, and external-data-plane.
cf-integration live --lane external-data-plane --group mcp
cf-integration live --lane fixture-direct --group protocol \
--protocol-version 2025-06-18
cf-integration conformance run
cf-integration conformance run \
--client-era legacy \
--client-era modern \
--server-era legacy \
--server-era modern
cf-integration conformance run --server-era dual --bless
cf-integration conformance report
cf-integration --versionWorkflows accept only --lane; --topology is reserved for stack commands.
The direct fixture spelling is only fixture-direct. Probe, load, live, and
Inspector use --protocol-version; conformance uses the explicit
--client-era and --server-era matrix axes.
One MCP client owns endpoint construction, authorization, sessions, stateful and stateless headers, JSON/SSE parsing, backend identity validation, response limits, timeouts, and secret redaction.
The session-oriented probe performs initialize, notifications/initialized,
tools/list, and one safe tools/call. The stateless probe performs
server/discover, attaches Mcp-Method and Mcp-Name routing headers, and
performs the same safe checks without a session. Both verify unauthenticated
rejection and external dataplane backend identity.
The official runner is pinned to
@modelcontextprotocol/conformance@0.2.0-alpha.11. Its TypeScript fixture is
built from revision c321dd32035556e6769d3724a8ee97d87c3faaac. A default run
starts workflow-owned stacks and runs both conformance directions. The server
suite sends the official client directly to the fixture and through the
built-in and external dataplane routes. For protocol 2026-07-28, the client
suite also makes the external dataplane send requests to the official scenario
servers. The four downstream scenarios are tools_call, request-metadata,
http-standard-headers, and http-custom-headers; they run automatically
whenever external-data-plane is selected. The workflow records raw official
results without suppression, writes deterministic comparisons, and continues
through every expanded client-revision/server-era combination before returning
one aggregated result. dual is supported only when selected explicitly.
The client and fixture-server era selections are independent:
cf-integration conformance run \
--client-era legacy \
--client-era modern \
--server-era legacy \
--server-era modernClient legacy expands to 2025-06-18 and 2025-11-25; modern expands to
2026-07-28; and dual expands to all three verified client revisions. The
expanded client revisions and selected server eras form a Cartesian product.
Artifacts default below CF_INTEGRATION_DIR/conformance/<client-version>/<server-era>/
and reports below reports/conformance/<client-version>/<server-era>/.
Server artifacts retain the lane directly below the era. Client artifacts and
reports use client/external-data-plane/ below the era. --results-dir,
--baseline-dir, and --output-dir override those roots.
Baselines use this strict layout:
tests/conformance/baselines/
<client-version>/
<server-era>/
fixture-direct.yml
built-in-data-plane.yml
external-data-plane.yml
client/
external-data-plane.yml
Each file contains sorted FAILURE and WARNING check identities. They are
required to distinguish expected failures from regressions and are embedded
for installed binaries. Every completed lane is printed in nextest style even
when a later lane fails operationally. The direct fixture is gated
independently; findings reproduced there are subtracted from routed lanes
before server comparison. Client findings are gated independently without
fixture subtraction. Unexpected, stale, unknown, malformed, incomplete,
missing, and operational results fail the matrix. --bless replaces all
selected server and client baselines in one directory transaction only after
every combination succeeds. Operational lane failures render as unconditional
FAIL rows, count in the nextest-style summary, and cannot be blessed. Outside
a developer checkout, an omitted
--baseline-dir writes blessed baselines beneath the current workspace rather
than modifying embedded assets. Server comparison regeneration discovers every
protocol/era partition beneath the selected result root and accepts
--results-dir and --output-dir.
Copy .env.example to .env. Process values override the file.
CF_INTEGRATION_ROOT=/path/to/contextforge-dev-tools
CF_INTEGRATION_DIR=.integration
CF_MCP_STACK_MODE=dataplane
CF_CONTROLPLANE_REPO=https://github.com/IBM/mcp-context-forge.git
CF_CONTROLPLANE_REF=main
CF_CONTROLPLANE_VERSION=main
CF_DATAPLANE_REPO=https://github.com/contextforge-org/contextforge-data-plane.git
CF_DATAPLANE_REF=
CF_DATAPLANE_IMAGE=ghcr.io/contextforge-org/contextforge-data-plane:latest
CF_DATAPLANE_PLATFORM=auto
CF_COMPOSE_BUILD=auto
CF_FAST_TIME_EXPECTED_IMAGE=ghcr.io/ibm/cfex-mcp-fast-time-server:latest
CF_FAST_TIME_SERVER_ID=9779b6698cbd4b4995ee04a4fab38737
MCP_CLI_BASE_URL=http://127.0.0.1:8080
MCP_PROTOCOL_VERSION=2026-07-28
MCP_SERVER_ID=9779b6698cbd4b4995ee04a4fab38737
PLATFORM_ADMIN_EMAIL=admin@example.com
PLATFORM_ADMIN_PASSWORD=<local-integration-password>
MCPGATEWAY_BEARER_TOKEN=<optional-pre-minted-token>CF_COMPOSE_BUILD=auto pulls or reuses prebuilt images and builds only an
explicit source data plane when required. true always builds; false never
builds. Published mode tracks both repositories' main-branch images. The
dataplane uses its floating :latest tag. The control plane uses the
commit-tagged image for the freshly fetched origin/main revision because
upstream reserves :latest for releases. Stack startup pulls changes;
incompatible main images make the workflow fail instead of selecting an older
pair.
CI jobs that package the code under test as a local image can opt out of
registry access with CF_CONTROLPLANE_PULL_POLICY=never or
CF_DATAPLANE_PULL_POLICY=never. This is never the default: the selected image
must already be loaded in Docker, and startup fails if it is absent.
Compose requires JWT_SECRET_KEY and AUTH_ENCRYPTION_SECRET. If either is
unset, a runtime-backed action generates stable values under
CF_INTEGRATION_DIR. Canonical configuration is exported internally as the
upstream Compose adapter names IMAGE_LOCAL and FAST_TIME_IMAGE; those names
are not accepted as inputs.
Without MCPGATEWAY_BEARER_TOKEN, dataplane workflows issue a one-day
server-scoped catalog token and revoke it during session cleanup. A caller
supplied token is never revoked by the harness.
One root package publishes exactly one binary, cf-integration. All concern
modules remain private implementation details:
src/infrastructure/ config, assets, processes, checkouts, Compose plans
src/mcp/ unified MCP client, protocol, auth proxy, probe
src/conformance/ fixture, strict baselines, results, comparisons
src/performance/ Locust settings, commands, and report auditing
src/runtime/live/ upstream live-test workflow
src/runtime/stack/ stack lifecycle and source ownership
src/runtime/conformance/ conformance orchestration and reports
src/runtime/performance/ performance workflow orchestration
src/runtime/probe.rs probe workflow orchestration
src/runtime/session.rs shared managed stack and credential scope
src/runtime/mod.rs thin action dispatcher
docker/ embedded Compose and nginx assets
scripts/ embedded runtime adapters
tests/conformance/ embedded expected-result baselines
The Bruno collection under manual-tests/mcp-manual-test-tools/ is an
intentional lower stack layer for manual diagnosis. It remains in the
repository and is excluded from the published crate payload.
cargo fmt --all --check
cargo clippy --all-targets -- -D warnings
cargo test --all-targets
cargo package --lockedPull requests run this quality gate plus native tests on Linux, macOS, and Windows. Releases build and smoke-test all six ARM64/x86-64 Linux, macOS, and Windows candidates before publishing the crate or tag. Prevalidated archives, SHA-256 files, and GitHub artifact attestations are published afterward.