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: body, headers, method, timeout, url)
# Completely unknown key
scafctl run provider http unknown=value
# Error: provider "http" does not accept input "unknown" (valid inputs: body, headers, method, 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: body, headers, method, timeout, url)
# Completely unknown key
scafctl run provider http unknown=value
# Error: provider "http" does not accept input "unknown" (valid inputs: body, headers, method, 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/pluginsSee the Provider Development Guide for creating custom providers (including plugin delivery ).
Discovering Providers#
List All Providers#
scafctl get providersscafctl get providersView Provider Details#
scafctl get provider httpscafctl get provider httpThis shows the provider’s schema, capabilities, examples, and auto-generated CLI usage examples.
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):
body string Request body for POST/PUT/PATCH requests
headers any HTTP headers as key-value pairs
method string HTTP method
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