VirtualMCPCompositeToolDefinition
VirtualMCPCompositeToolDefinition defines a reusable composite tool workflow - a sequence of backend tool calls exposed to clients as a single high-level tool. Referenced by a VirtualMCPServer via spec.config.compositeToolRefs.
API: toolhive.stacklok.dev/v1beta1
· Scope: Namespaced · Short names: vmcpctd, compositetool
Example
apiVersion: toolhive.stacklok.dev/v1beta1
kind: VirtualMCPCompositeToolDefinition
metadata:
name: my-virtualmcpcompositetooldefinition
namespace: default
spec:
name: <string>
steps: []
Schema
spec
VirtualMCPCompositeToolDefinitionSpec defines the desired state of VirtualMCPCompositeToolDefinition. This embeds the CompositeToolConfig from pkg/vmcp/config to share the configuration model between CLI and operator usage.
| Field | Type | Description |
|---|---|---|
description | string | Description describes what the workflow does. |
namerequired | string | Name is the workflow name (unique identifier). |
output | object | Output defines the structured output schema for this workflow. If not specified, the workflow returns the last step's output (backward compatible). |
parameters | object | Parameters defines input parameter schema in JSON Schema format. Should be a JSON Schema object with "type": "object" and "properties". Example: { "type": "object", "properties": { "param1": {"type": "string", "default": "value"}, "param2": {"type": "integer"} }, "required": ["param2"] } We use json.Map rather than a typed struct because JSON Schema is highly flexible with many optional fields (default, enum, minimum, maximum, pattern, items, additionalProperties, oneOf, anyOf, allOf, etc.). Using json.Map allows full JSON Schema compatibility without needing to define every possible field, and matches how the MCP SDK handles inputSchema. |
stepsrequired | object[] | Steps are the workflow steps to execute. |
timeout | string | Timeout is the maximum workflow execution time. pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ |
spec.output
Output defines the structured output schema for this workflow. If not specified, the workflow returns the last step's output (backward compatible).
| Field | Type | Description |
|---|---|---|
propertiesrequired | map<string, object> | Properties defines the output properties. Map key is the property name, value is the property definition. |
required | string[] | Required lists property names that must be present in the output. |
spec.output.properties
Properties defines the output properties. Map key is the property name, value is the property definition.
| Field | Type | Description |
|---|---|---|
default | | Default is the fallback value if template expansion fails. Type coercion is applied to match the declared Type. |
description | string | Description is a human-readable description exposed to clients and models |
properties | object | Properties defines nested properties for object types. Each nested property has full metadata (type, description, value/properties). |
type | string | Type is the JSON Schema type: "string", "integer", "number", "boolean", "object", "array" enum: string | integer | number | boolean | object | array |
value | string | Value is a template string for constructing the runtime value. For object types, this can be a JSON string that will be deserialized. Supports template syntax: {{.steps.step_id.output.field}}, {{.params.param_name}} |
spec.steps[]
Steps are the workflow steps to execute.
| Field | Type | Description |
|---|---|---|
arguments | object | Arguments is a map of argument values with template expansion support. Supports Go template syntax with .params and .steps for string values. Non-string values (integers, booleans, arrays, objects) are passed as-is. Note: the templating is only supported on the first level of the key-value pairs. |
collection | string | Collection is a Go template expression that resolves to a JSON array or a slice. Only used when Type is "forEach". |
condition | string | Condition is a template expression that determines if the step should execute |
defaultResults | | DefaultResults provides fallback output values when this step is skipped (due to condition evaluating to false) or fails (when onError.action is "continue"). Each key corresponds to an output field name referenced by downstream steps. Required if the step may be skipped AND downstream steps reference this step's output. |
dependsOn | string[] | DependsOn lists step IDs that must complete before this step |
idrequired | string | ID is the unique identifier for this step. |
itemVar | string | ItemVar is the variable name used to reference the current item in forEach templates. Defaults to "item" if not specified. Only used when Type is "forEach". |
maxIterations | integer | MaxIterations limits the number of items that can be iterated over. Defaults to 100, hard cap at 1000. Only used when Type is "forEach". |
maxParallel | integer | MaxParallel limits the number of concurrent iterations in a forEach step. Defaults to the DAG executor's maxParallel (10). Only used when Type is "forEach". |
message | string | Message is the elicitation message Only used when Type is "elicitation" |
onCancel | object | OnCancel defines the action to take when the user cancels/dismisses the elicitation Only used when Type is "elicitation" |
onDecline | object | OnDecline defines the action to take when the user explicitly declines the elicitation Only used when Type is "elicitation" |
onError | object | OnError defines error handling behavior |
schema | object | Schema defines the expected response schema for elicitation |
step | object | InnerStep defines the step to execute for each item in the collection. Only used when Type is "forEach". Only tool-type inner steps are supported. |
timeout | string | Timeout is the maximum execution time for this step pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ |
tool | string | Tool is the tool to call (format: "workload.tool_name") Only used when Type is "tool" |
type | string | Type is the step type (tool, elicitation, etc.) default "tool" · enum: tool | elicitation | forEach |
spec.steps.onCancel
OnCancel defines the action to take when the user cancels/dismisses the elicitation Only used when Type is "elicitation"
| Field | Type | Description |
|---|---|---|
action | string | Action defines the action to take when the user declines or cancels - skip_remaining: Skip remaining steps in the workflow - abort: Abort the entire workflow execution - continue: Continue to the next step default "abort" · enum: skip_remaining | abort | continue |
spec.steps.onDecline
OnDecline defines the action to take when the user explicitly declines the elicitation Only used when Type is "elicitation"
| Field | Type | Description |
|---|---|---|
action | string | Action defines the action to take when the user declines or cancels - skip_remaining: Skip remaining steps in the workflow - abort: Abort the entire workflow execution - continue: Continue to the next step default "abort" · enum: skip_remaining | abort | continue |
spec.steps.onError
OnError defines error handling behavior
| Field | Type | Description |
|---|---|---|
action | string | Action defines the action to take on error default "abort" · enum: abort | continue | retry |
retryCount | integer | RetryCount is the maximum number of retries Only used when Action is "retry" |
retryDelay | string | RetryDelay is the delay between retry attempts Only used when Action is "retry" pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ |
status
VirtualMCPCompositeToolDefinitionStatus defines the observed state of VirtualMCPCompositeToolDefinition
| Field | Type | Description |
|---|---|---|
conditions | object[] | Conditions represent the latest available observations of the workflow's state |
observedGeneration | integer | ObservedGeneration is the most recent generation observed for this VirtualMCPCompositeToolDefinition It corresponds to the resource's generation, which is updated on mutation by the API Server format int64 |
referencingVirtualServers | string[] | ReferencingVirtualServers lists VirtualMCPServer resources that reference this workflow This helps track which servers need to be reconciled when this workflow changes |
validationErrors | string[] | ValidationErrors contains validation error messages if ValidationStatus is Invalid |
validationStatus | string | ValidationStatus indicates the validation state of the workflow - Valid: Workflow structure is valid - Invalid: Workflow has validation errors enum: Valid | Invalid | Unknown |
status.conditions[]
Conditions represent the latest available observations of the workflow's state
| Field | Type | Description |
|---|---|---|
lastTransitionTimerequired | string | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format date-time |
messagerequired | string | message is a human readable message indicating details about the transition. This may be an empty string. maxLength 32768 |
observedGeneration | integer | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. format int64 · min 0 |
reasonrequired | string | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. pattern ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ · minLength 1 · maxLength 1024 |
statusrequired | string | status of the condition, one of True, False, Unknown. enum: True | False | Unknown |
typerequired | string | type of condition in CamelCase or in foo.example.com/CamelCase. pattern ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ · maxLength 316 |
Related resources
Referenced by:
- VirtualMCPServer - via
spec.config.compositeToolRefs