Run Provider Tutorial#
This tutorial covers the scafctl run provider command — a tool for executing individual providers directly without a solution or resolver file. This is useful for testing, debugging, and exploring providers in isolation.
Prerequisites#
- scafctl installed and available in your PATH
- Familiarity with providers
Table of Contents#
- Basic Usage
- Passing Inputs
- File-Based Inputs
- Capabilities
- Dry Run
- Output Formats
- Plugin Providers
- Discovering Providers
- Common Examples
Basic Usage#
The scafctl run provider command takes a provider name as its first argument. Provider inputs can be passed as positional key=value arguments or via the traditional --input flag:
# Positional key=value (recommended)
scafctl run provider <provider-name> <key>=<value>
# Explicit --input flag
scafctl run provider <provider-name> --input <key>=<value># Positional key=value (recommended)
scafctl run provider <provider-name> <key>=<value>
# Explicit --input flag
scafctl run provider <provider-name> --input <key>=<value>Both forms can be mixed freely. When the same key appears multiple times, later values override earlier ones.
Your First Provider Execution#
Run the static provider to return a simple value:
scafctl run provider static value=helloscafctl run provider static value=helloOutput:
{
"data": "hello"
}The output always contains a data field with the provider’s return value. Additional fields like warnings and metadata appear when relevant.
Passing Inputs#
Inputs can be passed as positional key=value arguments or via the --input flag. Both forms can be combined.
Simple Key-Value Pairs#
# Positional key=value (recommended)
scafctl run provider http url=https://httpbin.org/get method=GET
# Explicit --input flag
scafctl run provider http --input url=https://httpbin.org/get --input method=GET# Positional key=value (recommended)
scafctl run provider http url=https://httpbin.org/get method=GET
# Explicit --input flag
scafctl run provider http --input url=https://httpbin.org/get --input method=GETOutput:
{
"data": {
"body": "{...}",
"headers": {
"Content-Type": "application/json",
"...": "..."
},
"statusCode": 200
}
}Array Values#
Comma-separated values are automatically converted to arrays:
scafctl run provider exec command=echo args=hello,worldscafctl run provider exec shell=pwsh command=Write-Output "args=hello,world"Values Containing Commas#
If a value itself contains commas (not intended as array separators), wrap it in quotes inside the flag value. Use single quotes around the entire flag to prevent shell interpretation:
scafctl run provider cel 'expression="[1,2,3].map(x, x * 2)"'scafctl run provider cel 'expression="[1,2,3].map(x, x * 2)"'Multiple Values for the Same Key#
Repeating the same key creates an array:
scafctl run provider exec command=echo args=hello args=worldscafctl run provider exec shell=pwsh command=Write-Output "args=hello args=world"File-Based Inputs#
For complex inputs, load them from a YAML or JSON file using the @ prefix:
Create an Input File#
Create inputs.yaml:
url: https://httpbin.org/post
method: POST
body: '{"message": "hello"}'
headers:
Content-Type: application/jsonRun with File Input#
scafctl run provider http --input @inputs.yaml# Wrap @file in single quotes to avoid splatting operator
scafctl run provider http --input '@inputs.yaml'Read Inputs from Stdin#
Use @- to pipe inputs from stdin as YAML or JSON:
echo '{"url": "https://api.example.com", "method": "GET"}' | scafctl run provider http --input @-
cat inputs.yaml | scafctl run provider http @-'{"url": "https://api.example.com", "method": "GET"}' | scafctl run provider http --input '@-'
Get-Content inputs.yaml | scafctl run provider http '@-'Pipe Raw Content into a Single Input#
Use key=@- to read raw stdin into a specific input key, or key=@file to read a file’s content:
# Pipe raw text into the message input
echo hello | scafctl run provider message message=@-
# Pipe a request body from stdin
cat body.json | scafctl run provider http url=https://api.example.com body=@-
# Read a file's raw content into an input
scafctl run provider message message=@greeting.txt
scafctl run provider http url=https://api.example.com body=@request.json# Pipe raw text into the message input
'hello' | scafctl run provider message 'message=@-'
# Pipe a request body from stdin
Get-Content body.json | scafctl run provider http 'url=https://api.example.com' 'body=@-'
# Read a file's raw content into an input
scafctl run provider message 'message=@greeting.txt'
scafctl run provider http 'url=https://api.example.com' 'body=@request.json'Note: A single trailing newline is trimmed automatically.
key=@-reads raw text — it does not parse YAML/JSON.
Output:
{
"data": {
"body": "{...}",
"headers": { "...": "..." },
"statusCode": 200
}
}Mix File and Inline Inputs#
File and inline inputs are merged. When the same key appears in both, the values are combined into an array. To override a file value, omit that key from the file:
scafctl run provider http --input @inputs.yaml timeout=30scafctl run provider http --input '@inputs.yaml' timeout=30This loads all values from inputs.yaml and adds timeout=30.
Input Key Validation#
When you pass inputs, scafctl validates the input keys against the provider’s schema. Unknown keys are rejected early with a helpful error message. If the key is close to a valid one (a likely typo), a suggestion is included:
# Typo in key name
scafctl run provider http urll=https://example.com
# Error: provider "http" does not accept input "urll" — did you mean "url"? (valid inputs: acceptableStatusCodes, authProvider, autoParseJson, body, headers, method, pagination, poll, retry, scope, timeout, url)
# Completely unknown key
scafctl run provider http unknown=value
# Error: provider "http" does not accept input "unknown" (valid inputs: acceptableStatusCodes, authProvider, autoParseJson, body, headers, method, pagination, poll, retry, scope, timeout, url)# Typo in key name
scafctl run provider http urll=https://example.com
# Error: provider "http" does not accept input "urll" — did you mean "url"? (valid inputs: acceptableStatusCodes, authProvider, autoParseJson, body, headers, method, pagination, poll, retry, scope, timeout, url)
# Completely unknown key
scafctl run provider http unknown=value
# Error: provider "http" does not accept input "unknown" (valid inputs: acceptableStatusCodes, authProvider, autoParseJson, body, headers, method, pagination, poll, retry, scope, timeout, url)This validation also applies to resolver and solution parameters:
# Typo in parameter name
scafctl run resolver -f solution.yaml envrionment=prod
# Error: solution does not accept input "envrionment" — did you mean "environment"? (valid inputs: environment, region)# Typo in parameter name
scafctl run resolver -f solution.yaml envrionment=prod
# Error: solution does not accept input "envrionment" — did you mean "environment"? (valid inputs: environment, region)Capabilities#
Providers declare capabilities that define what kind of operation they perform:
| Capability | Description |
|---|---|
from | Data sourcing (default for most providers) |
transform | Data transformation |
validation | Input validation |
authentication | Authentication flows |
action | Side-effecting operations |
By default, scafctl run provider uses the provider’s first declared capability. Use --capability to select a specific one:
# Run a provider with a specific capability
scafctl run provider cel expression="1 + 2" --capability transform# Run a provider with a specific capability
scafctl run provider cel expression="1 + 2" --capability transformViewing Available Capabilities#
Use scafctl get provider <name> to see which capabilities a provider supports:
scafctl get provider celscafctl get provider celDry Run#
Use --dry-run to see what would be executed without actually running the provider:
scafctl run provider http url=https://example.com --dry-runscafctl run provider http url=https://example.com --dry-runThe provider will return simulated output without performing any side effects (no HTTP request, no command execution, etc.).
Provider vs solution dry-run:
run provider --dry-runinvokes the provider’sExecute()method with a dry-run context flag, so the provider returns mock data.run solution --dry-runis different — it uses the WhatIf model where resolvers run normally and actions are never executed. See Dry-Run & WhatIf design for details.
Output Formats#
The default output format is JSON. Use -o to change it:
# JSON output (default)
scafctl run provider static value=hello -o json
# YAML output
scafctl run provider static value=hello -o yaml
# Table output
scafctl run provider static value=hello -o table
# Quiet mode (exit code only)
scafctl run provider static value=hello -o quiet# JSON output (default)
scafctl run provider static value=hello -o json
# YAML output
scafctl run provider static value=hello -o yaml
# Table output
scafctl run provider static value=hello -o table
# Quiet mode (exit code only)
scafctl run provider static value=hello -o quietInteractive Mode#
Explore complex output in an interactive TUI:
scafctl run provider http --input url=https://httpbin.org/get -iscafctl run provider http --input url=https://httpbin.org/get -iCEL Expressions#
Filter or transform output using CEL expressions:
scafctl run provider http url=https://httpbin.org/get -e "_.data"scafctl run provider http url=https://httpbin.org/get -e '_.data'Execution Metrics#
Use --show-metrics to display timing information:
scafctl run provider http url=https://httpbin.org/get --show-metricsscafctl run provider http url=https://httpbin.org/get --show-metricsPlugin Providers#
Load providers from plugin executables using --plugin-dir:
# Load plugins from a directory
scafctl run provider echo message=hello --plugin-dir ./plugins
# Multiple plugin directories
scafctl run provider my-plugin key=value --plugin-dir ./plugins --plugin-dir /opt/plugins# Load plugins from a directory
scafctl run provider Write-Output "message=hello --plugin-dir ./plugins"
# Multiple plugin directories
scafctl run provider my-plugin key=value --plugin-dir ./plugins --plugin-dir /opt/pluginsVersion Pinning#
When multiple versions of a plugin provider are cached locally, you can pin a
specific version using name@version syntax or the --plugin-version flag:
# Pin via @version syntax (recommended)
scafctl run provider exec@0.5.0 command="echo hello"
# Pin via --plugin-version flag
scafctl run provider exec --plugin-version 0.5.0 command="echo hello"# Pin via @version syntax (recommended)
scafctl run provider exec@0.5.0 command="echo hello"
# Pin via --plugin-version flag
scafctl run provider exec --plugin-version 0.5.0 command="echo hello"Without version pinning, the latest cached version is used automatically.
See the Provider Development Guide for creating custom providers (including plugin delivery ).
Discovering Providers#
List All Providers#
scafctl get providersscafctl get providersThis lists all available providers with their source (builtin or official), category, capabilities, and version. Official providers are auto-fetched from the OCI catalog on first use – no manual installation required.
Note: When
--capabilityor--categoryfilters are active, only built-in providers are shown since official providers do not expose this metadata.
View Provider Details#
scafctl get provider httpscafctl get provider httpThis shows the provider’s schema, capabilities, examples, and auto-generated CLI usage examples. If the provider is not found in the built-in registry, scafctl falls back to the official provider registry and displays catalog information.
Dynamic Help for Provider Inputs#
When you run --help with a specific provider name, the help output automatically includes the provider’s input parameters with types, required/optional status, defaults, and descriptions:
scafctl run provider http --helpscafctl run provider http --helpAt the end of the standard help text, you’ll see a section like:
Provider Inputs (http):
acceptableStatusCodes array Status codes treated as successful (e.g. [200, 404], "2xx", "200-204")
authProvider string Authentication provider to use for this request
autoParseJson boolean When true and the response Content-Type is application/json, automatically parse the body into a structured object
body any Request body for POST/PUT/PATCH requests (string sent verbatim; object/array serialized to JSON)
headers any HTTP headers as key-value pairs
method string HTTP method
pagination object Pagination configuration for automatically following paginated API responses
poll object Polling configuration for re-executing the request until a condition is met
retry any Retry configuration for transient failures
scope string OAuth scope for authentication
timeout integer Request timeout in seconds
url string (required) The URL to requestThis works for any provider — just include the provider name before --help:
scafctl run provider env --help
scafctl run provider static --help
scafctl run provider file --helpscafctl run provider env --help
scafctl run provider static --help
scafctl run provider file --helpFilter by Capability#
scafctl get providers --capability=validationscafctl get providers --capability=validationBrowse Interactively#
scafctl get providers -iscafctl get providers -iCommon Examples#
Read an Environment Variable#
scafctl run provider env operation=get name=HOMEscafctl run provider env operation=get name=HOMEExecute a Shell Command#
scafctl run provider exec command=datescafctl run provider exec command=dateRead a File#
scafctl run provider file operation=read path=README.mdscafctl run provider file operation=read path=README.mdList a Directory#
scafctl run provider directory operation=list path=./pkgscafctl run provider directory operation=list path=./pkgEvaluate a CEL Expression#
# Simple expression (no commas)
scafctl run provider cel expression="1 + 2"
# Expressions with commas must be quoted to avoid CSV splitting
scafctl run provider cel 'expression="[1,2,3].map(x, x * 2)"'# Simple expression (no commas)
scafctl run provider cel expression="1 + 2"
# Expressions with commas must be quoted to avoid CSV splitting
scafctl run provider cel 'expression="[1,2,3].map(x, x * 2)"'Make an HTTP Request#
scafctl run provider http url=https://httpbin.org/get method=GETscafctl run provider http url=https://httpbin.org/get method=GETGet Git Repository Status#
scafctl run provider git operation=status path=.scafctl run provider git operation=status path=.Render a Go Template#
scafctl run provider go-template name=greeting 'template=Hello World'scafctl run provider go-template name=greeting 'template=Hello World'Redact Sensitive Output#
Use --redact to mask sensitive values in the output. This example retrieves
a secret (which must already exist in the scafctl secrets store):
scafctl run provider secret operation=get name=my-secret --redactscafctl run provider secret operation=get name=my-secret --redactNext Steps#
- Actions Tutorial — Learn about workflows
- Provider Reference — Full provider documentation
- Resolver Tutorial — Using providers within resolvers
- Provider Development — Creating custom providers