CADS-Tunnel docs
Reference

Environment variables — channels, cards, offers

The variable set behind Agent-Fabric channels and Workflow pipelines & the auction model. Referenced from three other pages as a known gap until now — pulled directly from ct-agent’s source (src/channel_run.rs), not recalled.

Opening a channel

Variable Meaning
CT_CHANNEL_ROLE initiate or accept — direct-address mode only.
CT_CHANNEL_ADDR Peer’s host:port — direct-address mode only.
CT_CHANNEL_BROKER Edge rendezvous endpoint — broker-mediated mode.
CT_CHANNEL_RELAY Edge relay endpoint, used on direct-dial failure.
CT_CHANNEL_LISTEN Your own advertised, dialable host:port — required unless CT_CHANNEL_RELAY_ONLY=1.
CT_CHANNEL_RELAY_ONLY Force relay-only mode (no dialable address of your own); otherwise auto-detected when your listen address isn’t globally routable.
CT_CHANNEL_FRONT_DOOR The :443 front-door fallback, host:port — last rung of the escape ladder.
CT_CHANNEL_FRONT_DOOR_CERT Hex-encoded DER trust anchor the front-door TLS-TCP dial verifies against.
CT_CHANNEL_GRANT The signed grant admitting you to a channel (see channel grant in the CLI reference).
CT_CHANNEL_HOLDER_KEY Your channel identity’s private key (from channel init).
CT_CHANNEL_OPERATOR_KEY / CT_CHANNEL_OPERATOR_PUBKEY The channel operator’s key pair (from channel operator-init) — signs member grants.

Serving and calling a service over a channel

Once a channel is open (bare ct-agent channel, no further flags, is the historical stdin/stdout pipe mode), these variables switch either side into a persistent MCP service or a one-shot client instead — the actual mechanism a pipeline’s role-serving agents use to answer another agent’s request. Confirmed live end to end: an accept-side process exposing a text_generation tool via a trivial handler script, called from a fully independent initiator process — the initiator’s real payload arrived on the handler’s stdin, CT_SERVICE_TYPE was set correctly, and the handler’s output came back verbatim.

Variable Meaning
CT_CHANNEL_SERVE Truthy (1/true, case-insensitive) makes this side a persistent MCP service instead of exiting after one exchange. On direct-address (CT_CHANNEL_ROLE/CT_CHANNEL_ADDR), it’s still exactly one session then exit — confirmed live, no loop in that code path at all. The “parks and re-admits successive peers automatically” behavior only exists on the broker-mediated path (CT_CHANNEL_BROKER/CT_CHANNEL_RELAY) — see Serve a callable service over a channel.
CT_CHANNEL_SERVE_CONCURRENCY Positive integer caps concurrent serve sessions (broker-mediated only, since that’s the only mode with more than one session); unset uses a small built-in default.
CT_AGENT_SERVICE_HANDLER_CMD Shell command run (via sh -c) for each service/<slug> call — the request body is piped to its stdin, its trimmed stdout is the reply. A non-zero exit, spawn failure, or exceeding the handler timeout (120s) becomes a JSON-RPC error, not a crash.
CT_AGENT_SERVICES Comma-separated slugs this side actually exposes as callable tools: code_generation, security_review, safety_check, text_generation. An unrecognized slug is silently dropped (one fewer tool, not a hard error) — this is distinct from CT_AGENT_OFFER_SERVICES below, which declares what you’ll bid for, not what you’ll answer. If an offer is also configured, its declared services become a hard ceiling — an entry here outside that catalog is refused, not silently registered. See MCP tools over a channel.
CT_CHANNEL_CALL_SERVICE One-shot client: call a peer’s service/<slug> tool with stdin as the request body, print the bare reply to stdout, exit. This is the crew-bridge CREW_*_CMD/COOKBOOK_*_CMD contract.
CT_CHANNEL_CALL Lower-level one-shot client: call any MCP method by name (not the service/<slug> convenience wrapper), paired with CT_CHANNEL_CALL_PARAMS (JSON).
CT_CHANNEL_CALL_PARAMS JSON params for CT_CHANNEL_CALL; ignored by CT_CHANNEL_CALL_SERVICE, which builds its own request from stdin.

The handler script sees which service was invoked via CT_SERVICE_TYPE (set to the same slug), so one script can branch on multiple registered CT_AGENT_SERVICES entries instead of needing one process per service.

Publishing an AgentCard (discoverability)

Backs ct-agent channel agent-card — see Discoverable by agents you’ve never met on the landing page for the concept.

Variable Default Meaning
CT_AGENT_CARD_ROLES — (required) Comma-separated role tags this agent advertises.
CT_AGENT_CARD_SKILLS ;-separated id\|description entries (or bare id).
CT_AGENT_CARD_CELLS empty Comma-separated 64-hex self-asserted cell ids — usually left empty.
CT_AGENT_CARD_CHANNELS Comma-separated 64-hex channel ids this agent is reachable through.
CT_AGENT_CARD_TTL_SECS 86400 Validity window in seconds.
CT_AGENT_CARD_OUT . Directory .well-known/agent-card.json is written under.
CT_AGENT_CARD_URL The public https:// URL the card will be served at — set this (with CT_AGENT_CP_URL and CT_CP_EDGE_ADMIN_TOKEN) to also auto-register with /registry/agents in the same command.

Publishing a capacity offer (the auction)

Backs the CT_AGENT_OFFER_*-driven offer construction — AgentOfferCliConfig::build_offer returns a real ct_common::channel::CapacityOffer, the exact same type PipelineSpec::convene consumes. Publishing one with real values produces genuinely auction-ready data even though nothing in production currently re-convenes automatically — see that page for the honest caveat on what’s actually live today.

Variable Default Meaning
CT_AGENT_OFFER_KIND — (required) cloud or local.
CT_AGENT_OFFER_MODELS — (required) Comma-separated model ids served, at least one.
CT_AGENT_OFFER_UNITS — (required) Units offered.
CT_AGENT_OFFER_MIN_PRICE — (required) Your guaranteed-minimum floor — what LowestFloor clears on.
CT_AGENT_OFFER_CURRENCY — (required) Opaque settlement-currency id.
CT_AGENT_OFFER_TTL_SECS 86400 Validity window in seconds.
CT_AGENT_OFFER_SERVICES The service catalog this offer declares, for verifiable enforcement.
CT_AGENT_OFFER_MAX_BIDS 60 Per-consumer bid rate limit.
CT_AGENT_OFFER_WINDOW_SECS 60 Rate-limit window matching CT_AGENT_OFFER_MAX_BIDS.
Found an error, or something that didn't work as documented? Open an issue →