wxctl takes an opinionated, declarative approach to managing IBM product resources. Describe a scenario (demo, POC, project, use case, etc.) in plain language. wxctl discovers the prerequisites, resolves every cross-service identifier, and executes in dependency order. It starts with watsonx and extends to the full IBM portfolio. Think Terraform for IBM, but broader, and it goes further. From Hybrid Cloud to Data and AI to Automation: plan previews, apply converges, destroy tears down, test verifies the live system. It applies to product resources (agents, tools, knowledge bases, models, deployments, AI use cases, quality monitors, governance policies, catalogs, buckets), not VMs and networks. One declarative model across the portfolio, with a uniform interface to each product. wxctl builds an internal resource graph across the IBM portfolio. From that graph it discovers the transitive prerequisites a scenario needs and the recommended path to deploy them, so you wire nothing by hand. It resolves each ${kind.ref_name} into the exact identifier the consuming service expects (UUID, GUID, href, CRN) at call time, so the same config runs unchanged across environments. wxctl is the engine, not the intelligence. It ships no AI or LLM of its own. Bring any model or MCP client: Claude Code, Cursor, or Claude Desktop. Your AI coding agent turns the scenario into config; wxctl validates, plans, and executes it deterministically.

The problem

A single scenario spans several IBM products. Deploying it means discovering every prerequisite, calling APIs in dependency order, and translating each resource’s identifier into the format the next service expects (UUID, GUID, href, CRN). Those identifiers are server-generated and environment-specific, so a deployment built for one environment does not carry to the next.

How wxctl solves it

Describe what you want in plain language. wxctl does the discovery: it determines which resources the scenario needs and resolves their dependencies.
Describe your scenarioin plain language
1Your AI coding agent generates the config
Identify kindsagents, tools, connectionsResolve dependenciestransitive prerequisitesGenerate configrefs + kind: test suite
validated + auto-fixed
config.yaml
$kind.ref_name references, never hardcoded ids
2wxctl runs it deterministically
Validateschema + refsReconcilediff vs live statePlancreate · update · deleteApplyin dependency order
$ref → UUID · GUID · href · CRNresolved at call time, per service
3wxctl backs the whole lifecycle
applyprovision resourcestestrun kind: test suitere-runonly what drifteddestroyreverse-dependency order
one pipeline backs the whole lifecycle: re-runs change only what drifted
1

Your AI coding agent generates the config

Describe your scenario in plain language: a sentence or a short brief, like “a customer-churn model, governed and monitored, with an agent that pulls customers from the lakehouse and scores each one.” Your AI coding agent maps it to the resource kinds it implies (agents, tools, connections), pulls every transitive prerequisite and the recommended deployment path from wxctl, then writes a complete config.yaml (${kind.ref_name} references, never a hardcoded id, plus a kind: test suite) and validates and auto-fixes it. Point any MCP client at wxctl; it asks for anything it can’t infer (account ids, credentials, resource names) instead of guessing.
2

wxctl runs it deterministically

wxctl validates the config against each kind’s schema, reconciles it against live state, plans the create, update, and delete operations, and applies them in dependency order, resolving each ${kind.ref_name} into the identifier the next service expects (UUID, GUID, href, or CRN) at call time.
3

wxctl backs the whole lifecycle

apply provisions the resources, and test runs the generated kind: test suite to prove the deployment works, not just that it was created. Re-running changes only what drifted, and destroy tears everything down in reverse-dependency order.
The four-product customer-churn scenario becomes one config.yaml, one profile. A single wxctl apply self-provisions a watsonx.data Presto engine, deploys the churn model on watsonx.ai, puts it under watsonx.governance OpenScale quality, fairness, and drift monitors, and gives a watsonx Orchestrate agent the tools to query the lakehouse and score each customer. Every cross-resource link, including server-generated values like the engine’s host and the deployment’s scoring URL, is a ${kind.ref_name} reference, never a hardcoded id (abridged):
# one profile; cross-env via a per-service `deployment` override:
#   watsonx_data → CP4D cluster · watsonx.ai · OpenScale · Orchestrate → SaaS

# watsonx.data: self-provision a Presto engine, no manual infra setup
kind: presto_engine
ref_name: churn_engine
associated_catalogs:
  - ${env:LAKEHOUSE_CATALOG}
status: running
---
# watsonx.ai: deploy the churn model online
kind: wml_function
ref_name: churn_model
source_path: score.py
---
kind: wml_deployment
ref_name: churn_deployment
asset: ${wml_function.churn_model}
online: {}
---
# watsonx.governance · OpenScale: quality, fairness, and drift over the deployment
kind: subscription
ref_name: churn_sub
asset:
  url: ${wml_deployment.churn_deployment.scoring_url}   # computed at apply, wired by ref
deployment:
  deployment_id: ${wml_deployment.churn_deployment}
---
kind: monitor_instance
monitor_definition_id: quality
target:
  target_id: ${subscription.churn_sub}
thresholds:
  - metric_id: area_under_roc
    type: lower_limit
    value: 0.8
---
# watsonx Orchestrate: an agent queries the self-provisioned lakehouse and scores each customer
kind: orchestrate_connection
ref_name: lakehouse_conn
credentials:
  host: ${presto_engine.churn_engine.external_host_name}   # computed at apply, wired by ref
---
kind: agent
ref_name: churn_analyst
tools:
  - ${tool.query_lakehouse}
  - ${tool.score_churn}
Point any MCP client (Claude Code, Cursor, or Claude Desktop) at wxctl. Your AI coding agent does the generation passes; wxctl resolves the dependencies and runs the engine. See Generate a config from a scenario.
One config drives the whole lifecycle. End to end, the scenario runs in six stages:
  1. Provision the data layer. wxctl self-provisions a watsonx.data Presto engine and attaches the lakehouse catalog holding the customers table. The engine’s server-generated hostname wires itself into the agent’s lakehouse connection.
  2. Train. A platform job runs the training notebook inside a watsonx.ai project and stores a native scikit-learn churn model.
  3. Promote and deploy. wxctl promotes the trained model into a deployment space and stands up an online deployment.
  4. Govern. An AI use case tracks the deployment, and an OpenScale subscription attaches quality, fairness, and drift monitors. The deployment’s scoring URL resolves into the subscription at call time.
  5. Act. A watsonx Orchestrate agent, with its LLM served through the AI gateway, gets two tools: query customers from the lakehouse, and score each one against the governed deployment.
  6. Prove. The generated kind: test asks the agent which customers are most likely to churn and expects the ranked table.
  • plan previews exactly what will change before anything runs.
  • apply converges reality to the config, creating every resource in dependency order and resolving each ${ref} into the identifier the next service expects at call time.
  • test runs the generated kind: test suite against the live deployment, proving it works, not just that it was created.
  • destroy tears everything down in reverse-dependency order.
Re-running reconciles against live state, changing only what drifted, so applying twice is safe.
Not infrastructure-as-code. Terraform provisions VMs and networks. wxctl manages product resources (AI agents, governance policies, data catalogs, object storage) across services with incompatible identifier schemes.
The result: your entire deployment lives in one file you can version, review in a pull request, and replay anywhere. One source of truth, not a runbook of manual API calls.

Next steps

Installation

Build the wxctl binary and configure a profile.

Generate a config from a scenario

Describe what you want. Your MCP client generates the config, then deploys and tests it.