This skill should be used when the user asks to "build a Workato connector", "create a custom connector", "improve connector UX", "add input fields to connector", "make fields sticky", "use extends_schema", "add dynamic fields", or is working with Workato SDK Ruby DSL for custom connectors. Also use proactively when implementing connector actions or configuring input field visibility.
From workato-connector-sdknpx claudepluginhub grailautomation/claude-plugins --plugin workato-connector-sdkThis skill uses the workspace's default tool permissions.
references/control-types.mdreferences/field-patterns.mdreferences/schema-patterns.mdGuide for building Workato custom connectors with excellent recipe developer experience. Focus on field visibility, dynamic schemas, and input patterns that make connectors intuitive to configure.
Connector inputs must be designed from the recipe developer's perspective. Every field must be:
sticky: true for primary inputsdefault: for common choicesngIf and extends_schema for conditional fieldsMark fields as sticky to keep them visible in the recipe editor. Without sticky, optional fields collapse into "Show optional fields".
When to use:
type + budget_tokens){
name: 'message',
label: 'Text to send',
type: 'string',
control_type: 'text-area',
sticky: true, # Always visible
optional: true,
hint: 'The message content.'
}
Pre-populate selectors so users see input fields immediately without making a selection first.
When to use:
{
name: 'message_type',
control_type: 'select',
pick_list: 'message_types',
optional: false,
default: 'single_message', # Most common choice
hint: 'Choose message type.'
}
For the best UX, combine both patterns:
{
name: 'temperature',
control_type: 'number',
convert_input: 'float_conversion',
sticky: true, # Always visible
default: 1.0, # Sensible starting value
hint: 'Controls randomness (0.0-2.0).'
}
Use extends_schema: true when a field selection should reveal additional fields. Workato re-evaluates the schema when this field changes.
{
name: 'source_type',
control_type: 'select',
pick_list: 'source_types',
extends_schema: true, # Triggers schema refresh
sticky: true,
hint: 'How to provide the data.'
}
Show fields only when relevant using ngIf with input path expressions:
# Show URL field only when source_type is 'url'
{
name: 'image_url',
label: 'Image URL',
type: 'string',
ngIf: 'input.source_type == "url"',
hint: 'Public URL of the image.'
},
# Show base64 fields only when source_type is 'base64'
{
name: 'image_data',
label: 'Image data (Base64)',
type: 'string',
control_type: 'text-area',
ngIf: 'input.source_type == "base64"',
hint: 'Base64-encoded image data.'
}
For fields inside objects or arrays, use dot notation:
ngIf: 'input.tool_choice.type == "tool"'
ngIf: 'input.block_type == "document" && input.document_source_type == "file"'
Allow both dropdown selection and custom text input:
{
name: 'model',
control_type: 'select',
pick_list: 'model_list',
toggle_hint: 'Select from list',
toggle_field: {
name: 'model',
label: 'Model ID',
type: 'string',
control_type: 'text',
toggle_hint: 'Enter model ID',
hint: 'Enter model ID directly, e.g. custom-model-v1'
}
}
| control_type | Use For | Notes |
|---|---|---|
text | Short strings | Default for string type |
text-area | Long text, JSON | Multi-line input |
select | Single choice | Requires pick_list or options |
multiselect | Multiple choices | Returns array, needs delimiter |
number | Decimals | Use with float_conversion |
integer | Whole numbers | Use with integer_conversion |
checkbox | Boolean | Use with boolean_conversion |
password | Secrets | Masked input |
schema-designer | JSON schema | Visual schema builder |
Always pair control types with appropriate conversions:
{ control_type: 'integer', convert_input: 'integer_conversion' }
{ control_type: 'number', convert_input: 'float_conversion' }
{ control_type: 'checkbox', convert_input: 'boolean_conversion' }
Use for small, bounded collections:
{
name: 'items',
type: 'array',
of: 'object',
list_mode: 'static',
list_mode_toggle: true, # Allow switching to dynamic
properties: [...]
}
Use when items come from upstream data:
{
name: 'messages',
type: 'array',
of: 'object',
list_mode: 'dynamic',
list_mode_toggle: true,
properties: [...]
}
Define reusable schemas in object_definitions: block:
object_definitions: {
message_input: {
fields: lambda do |_connection, config_fields, _object_definitions|
# Dynamic field generation based on config_fields
is_single = config_fields['mode'] == 'single'
if is_single
[{ name: 'text', type: 'string', sticky: true }]
else
[{ name: 'messages', type: 'array', of: 'object', properties: [...] }]
end
end
}
}
Reference in actions:
input_fields: lambda do |object_definitions|
object_definitions['message_input']
end
Define in pick_lists: block:
pick_lists: {
source_types: lambda do
[['Base64 encoded', 'base64'], ['URL', 'url']]
end
}
Fetch options from API:
pick_lists: {
model_list: lambda do
get('v1/models')&.[]('data')&.map do |model|
[model['display_name'], model['id']]
end
end
}
Connection fields cannot reference pick_lists: (authentication not yet available). Use inline options: instead:
# In connection: fields:
{
name: 'version',
control_type: 'select',
options: [['2023-06-01', '2023-06-01']], # Inline, not pick_list
default: '2023-06-01'
}
Define reusable logic in methods: block:
methods: {
get_content_block_properties: lambda do
[
{ name: 'block_type', control_type: 'select', ... },
{ name: 'url', ngIf: 'input.block_type == "url"', ... }
]
end
}
Call methods with call('method_name', args):
content_props = call('get_content_block_properties')
Hints must be crafted from the recipe developer's perspective:
<a href="..." target="_blank">docs</a> for complex topicshint: 'Maximum tokens to generate. See <a href="https://docs.example.com/models" ' \
'target="_blank">models</a> for limits. Defaults to 4096.'
For detailed patterns and complete examples, consult:
references/field-patterns.md — Complete sticky, default, optional patterns with examplesreferences/control-types.md — All control types with conversion requirementsreferences/schema-patterns.md — Object definitions, methods, config_fields patterns