- 🖥️ UI - Affects StackOne Hub, Dashboard, or Connect flows
- 🤖 MCP - Used in MCP tool declarations (
list tools) - ⚙️ Runtime - Affects API request execution
File Structure
Connectors use a modular file structure:Why use partial files?
Why use partial files?
stackone push. The $ref syntax tells the merger which partials to include. File naming must follow the pattern {provider}.{resource}.s1.partial.yaml for auto-discovery.Example from BambooHR:bamboohr.connector.s1.yaml- Auth configbamboohr.employees.s1.partial.yaml- Employee actionsbamboohr.timeoff.s1.partial.yaml- Time-off actions
Root Properties
StackOne
Impact: ⚙️ Runtime
The schema version for the connector file format.
How version affects processing
How version affects processing
1.0.0 is supported. Future versions may introduce new properties or change behavior. Always use 1.0.0 for new connectors.info Section
Metadata about the connector displayed in the UI and used for identification.
info.title
Impact: 🖥️ UI
Human-readable provider name displayed in the Hub and Dashboard.
UI display locations
UI display locations
- Integration Hub provider list
- Dashboard connector cards
- Account connection screens
- Logs and audit trails
info.key
Impact: 🖥️ UI | 🤖 MCP | ⚙️ Runtime
Unique identifier for the connector. Used in API calls, MCP tool names, and internal routing.
How key is used throughout the system
How key is used throughout the system
bamboohr_list_employeesAPI: Used in account connections:Forking connectors and inheriting updates
Forking connectors and inheriting updates
info.title). However, if you want to inherit future StackOne updates to that connector, the info.key field must match the StackOne connector key.Example:
If you fork StackOne’s BambooHR connector:- ✅ You can change
info.titleto “Custom BambooHR” - ⚠️ Keep
info.key: bamboohrto receive future updates from StackOne - ❌ Changing
info.keytocustom_bamboohrprevents automatic update inheritance
info.key identical to the original StackOne connector key if you want to inherit future improvements and bug fixes.info.version
Impact: 🖥️ UI | ⚙️ Runtime
Connector version following semver format.
Version management best practices
Version management best practices
- Major (1.x.x): Breaking changes — auth changes, removed/renamed actions, changed response or request shape, or behavioural changes consumers may have relied on
- Minor (x.1.x): New actions, new optional parameters, or new optional response fields
- Patch (x.x.1): Bug fixes, description updates, internal refactors
info.assets.icon
Impact: 🖥️ UI
URL to the provider’s logo image. Displayed throughout the UI.
Logo requirements and hosting
Logo requirements and hosting
https://stackone-logos.com/api/{provider}/filled/pngRequirements:- 24x24 pixels minimum
- PNG or SVG format
- Transparent background preferred
- Hosted on HTTPS
info.description
Impact: 🖥️ UI | 🤖 MCP
Brief description of the connector’s purpose.
Where description appears
Where description appears
- Keep under 200 characters
- Mention key capabilities
- Include category context (HRIS, CRM, etc.)
baseUrl
Impact: ⚙️ Runtime
The root URL for all API requests. Supports static URLs and dynamic interpolation.
Static URL
Dynamic URL with credentials
Dynamic URL with config
URL interpolation and runtime resolution
URL interpolation and runtime resolution
${...} string interpolation:Available contexts:${credentials.*}- Values from setupFields/configFields${config.*}- Configuration values${env.*}- Environment variables (limited)
acme-corp, the runtime resolves to:rateLimit
Impact: ⚙️ Runtime
Configure rate limiting to respect provider API limits.
Rate limiting behavior
Rate limiting behavior
- Set slightly below provider’s documented limit
- Check provider API docs for per-endpoint limits
- Some providers have different limits for different endpoints
resources
Impact: 🖥️ UI
URL to the provider’s API documentation. Displayed as a help link in the UI.
Resource link usage
Resource link usage
- Connector configuration screens
- Troubleshooting guides
- Developer documentation references
documentation
Impact: 🖥️ UI · 🤖 Agent context
Structured external references for the connector. Each entry has a required title and url, and an optional description. Rendered as a card grid on the connector’s docs page and surfaced in the /actions API response.
documentation.references fields
documentation.references fields
documentation.references for links that benefit both developers reading the docs and agents consuming the /actions API. The resources field (plain string URL) remains valid for a single legacy link; use documentation.references for structured, multi-link documentation.authentication Section
Defines how end-users authenticate with the provider. Supports multiple auth methods per connector.
Authentication Array Structure
Multiple auth methods
Multiple auth methods
- Users see all options in the Hub during connection
- Each method has independent credentials and setup flows
- Linked accounts store which method was used
- Runtime uses the appropriate auth handler based on account config
- OAuth 2.0
- Custom Auth (API Key, Basic)
OAuth 2.0 Authentication
Impact: 🖥️ UI | ⚙️ Runtimetype
label
Impact: 🖥️ UIDisplay name for this auth method in the Hub.support
Impact: 🖥️ UIHelp text and links shown during connection flow.Support section display
Support section display
descriptionappears as instructional textlinkcreates a “Learn more” button
authorization
Impact: ⚙️ RuntimeOAuth flow configuration.OAuth flow internals
OAuth flow internals
- User clicks “Connect” in Hub
- Runtime builds authorization URL with
authorizationParams - User redirects to provider, logs in, grants permissions
- Provider redirects back with authorization code
- Runtime exchanges code for tokens via
tokenUrl - Tokens stored in credentials for linked account
$.credentials.*- JSONPath to credential values${apiHostUri}- StackOne callback URL base'{{expression ?? default}}'- JEXL with fallback
code_verifier and code_challenge automatically.Scopes: The example '{{$.credentials.scopes ?? "default:scope"}}' lets users customize scopes in setupFields while providing sensible defaults.setupFields
Impact: 🖥️ UI | ⚙️ RuntimeFields collected when configuring the connector (T1 - your app’s credentials).setupFields vs configFields
setupFields vs configFields
- OAuth Client ID/Secret
- API keys for your platform
- Application-level settings
- Their API keys
- Account-specific settings (subdomain, region)
- Personal access tokens
- setupFields → Stored per connector profile
- configFields → Stored per linked account
secret: true→ Encrypted at rest, never exposed in API responsestype: password→ Masked in UI during entry
configFields
Impact: 🖥️ UI | ⚙️ RuntimeFields collected from end-users during connection (T2 - their credentials).setupFields.refreshAuthentication
Impact: ⚙️ RuntimeEmbedded action for refreshing expired OAuth tokens.Token refresh mechanics
Token refresh mechanics
- An action fails with 401 Unauthorized
- Runtime checks if refreshAuthentication is configured
- Executes the embedded refresh action
- Updates stored credentials with new tokens
- Retries the original action
- Call the provider’s token refresh endpoint
- Map the response to credential format (accessToken, refreshToken, expiresIn)
- Return data in
result.data
categories: [internal] hides this from MCP tool listings.environments
Impact: 🖥️ UIAvailable deployment environments for this auth method.Multi-environment support
Multi-environment support
$.environment.key.testActions
Impact: 🖥️ UI | ⚙️ RuntimeActions executed to validate a connection after OAuth completes.Connection validation flow
Connection validation flow
- Runtime executes each testAction in order
- If
required: trueand action fails → connection marked as failed - If
required: falseand action fails → warning logged but connection succeeds
- Use a simple read action (list, get)
- Test the most common use case
- Avoid actions that modify data
actions Section
Actions define the operations available through the connector. Use $ref to include partials.
Action References
How $ref resolution works
How $ref resolution works
$ref at build time:$ref: bamboohr.employeeslooks forbamboohr.employees.s1.partial.yaml- Partial file must be in same directory as main connector
- Actions from partial are merged into main connector
- Multiple
$refstatements combine all partials
- (array items), not actions:.Action Properties
Each action defines a single operation.actionId
Impact: 🤖 MCP | ⚙️ Runtime
Unique identifier for the action. Becomes the MCP tool name with provider prefix.
bamboohr_list_employees
Action ID naming conventions
Action ID naming conventions
list_*- Get multiple records (paginated)get_*- Get single record by IDcreate_*- Create new recordupdate_*- Modify existing recorddelete_*- Remove recordsearch_*- Query with filters
list_employees- List all employeesget_employee- Get employee by IDcreate_employee- Create new employeesearch_employees_by_department- Filtered search
{provider_key}_{actionId}, so bamboohr + list_employees = bamboohr_list_employees.categories
Impact: 🖥️ UI
Categories for filtering in the UI. Does not affect MCP.
Category filtering behavior
Category filtering behavior
- Actions Explorer in Dashboard
- AI Playground action selection
- SDK
fetchTools({ categories: ['hris'] })
internal category: Actions with categories: [internal] are:- Hidden from UI listings
- Not returned in MCP
list tools - Still executable via direct API calls
- Used for token refresh and internal operations
actionType
Impact: 🤖 MCP | ⚙️ Runtime
Determines the action’s behavior pattern and response schema.
Unified vs Custom action types
Unified vs Custom action types
- Enforce consistent response schemas across providers
- Enable cross-provider compatibility
- Support automatic pagination handling
- Normalize error responses
- Returns raw provider response
- Use for provider-specific features
- No schema normalization
- Full flexibility for unique endpoints
list action always returns:custom action returns whatever the provider returns.label
Impact: 🖥️ UI
Human-readable name displayed in the UI.
Label display locations
Label display locations
- Actions Explorer
- AI Playground action selector
- Request logs
- Error messages
- Use title case
- Start with verb (List, Get, Create, etc.)
- Keep concise (under 30 characters)
description
Impact: 🖥️ UI | 🤖 MCP
Short description of what the action does. Used in both UI and MCP tool descriptions.
Description in MCP tool declarations
Description in MCP tool declarations
list tools, the description becomes the tool’s description:- Understand the action’s purpose
- Know what data it returns
- Decide which action fits the user’s request
- Keep under 200 characters
- Mention key capabilities
- Be specific about what’s returned
details
Impact: 🤖 MCP
Extended description with full context. Used as the complete tool description in MCP.
Details vs Description in MCP
Details vs Description in MCP
descriptionas a brief summarydetailsas the full tool description
description: One-line summary (~100 chars)details: Full context for AI agents (~500 chars)
- What fields are returned
- How pagination works
- What filters are available
- Edge cases and limitations
resources
Impact: 🖥️ UI
Link to provider documentation for this specific action.
Action-level resources
Action-level resources
inputs
Impact: 🤖 MCP | ⚙️ Runtime
Define parameters the action accepts. Become MCP tool input schema.
Input Properties
Input Types
Enum Type
MCP input schema generation
MCP input schema generation
- Generate valid tool calls
- Understand parameter types
- Apply default values
- Validate inputs before calling
Array inputs
Array inputs
array: true for parameters accepting multiple values:"type": "array", "items": { "type": "string" }Object type with nested properties
Object type with nested properties
type: object with a nested properties array to define the object’s structure:properties supports the same fields as top-level inputs (name, type, description, required, default, properties for deeper nesting).This generates proper JSON Schema for MCP, helping AI agents understand the expected object structure:Variant inputs
Variant inputs
variants instead of a single type. Each variant is a complete shape specification.- When
variantsis present, top-leveltype,array,properties,oneOf, andrulesmust be absent — each variant carries its own complete schema variantsmust contain at least 2 entries- Each variant must declare a
type
steps
Impact: ⚙️ Runtime
Define the execution flow for the action. Steps run sequentially.
Step Properties
Conditional Steps
Condition expressions
Condition expressions
Step Functions
request
Impact: ⚙️ Runtime
Make an HTTP request to the provider API.
Args Location (in)
Request construction internals
Request construction internals
- URL:
baseUrl+urlwith path params interpolated - Query: All
in: queryargs joined with& - Body: All
in: bodyargs merged into JSON object - Headers: Connector auth headers + custom headers +
in: headersargs
/employees/123/time-off/456Body construction:{ "firstName": "John", "lastName": "Doe" }Custom error handling
Custom error handling
customErrors to remap provider error responses. This is useful for:- GraphQL APIs that return errors with 200 status codes
- Provider-specific error formats that need normalization
- Custom error messages for better AI agent understanding
condition property is useful for GraphQL APIs where errors are returned in the response body with a 200 status code.paginated_request
Impact: ⚙️ Runtime
Automatically handle pagination for list endpoints.
Pagination Types
Pagination handling mechanics
Pagination handling mechanics
- Make initial request without cursor
- Read
cursor_pathfrom response - If cursor exists, make next request with cursor in
cursor_position - Repeat until no cursor returned
- Aggregate all
data_pathresults
next cursor allows fetching subsequent pages by passing it back as an input parameter.map_fields
Impact: ⚙️ Runtime
Transform data between formats.
Field mapping expressions
Field mapping expressions
type field ensures output matches expected type:string- Converts to stringnumber- Converts to numberboolean- Converts to booleandatetime_string- Formats as ISO 8601
group_data
Impact: ⚙️ Runtime
Group array data by a field.
Group data usage
Group data usage
typecast
Impact: ⚙️ Runtime
Convert data types.
soap_request
Impact: ⚙️ Runtime
Make SOAP API requests. Used primarily for enterprise providers like Workday.
SOAP namespace configuration
SOAP namespace configuration
@_ prefix for XML attributes and #text for text content.static_values
Impact: ⚙️ Runtime
Return predefined static values without making an API request. Useful for enum lookups or constant data.
Static values use cases
Static values use cases
static_values when:- Provider doesn’t have an API endpoint for enum values:
- Combining with dynamic data via multi-step actions:
merge_collections
Impact: ⚙️ Runtime
Merge multiple data collections into a single array.
Merge collections example
Merge collections example
code_execution_lambda
Impact: ⚙️ Runtime
Invoke an AWS Lambda function and use the response as the step output. Useful for offloading custom transformations, provider-specific logic, or computation that doesn’t fit other step functions.
Invocation Types
Output
Payload construction and response handling
Payload construction and response handling
args array is assembled into a single JSON object and sent as the Lambda payload:Input args:{ "result": { "score": 0.9 }, "meta": {...} }, then $.steps.{stepId}.output.data is { "score": 0.9 }.Iterator Steps
Impact: ⚙️ Runtime Iterator steps (foreach) execute step function(s) for each item in an array. Define by adding theiterator property to a step.
Iterator context variables
Iterator context variables
$.steps.{stepId}.output.data as an array.result
Impact: 🤖 MCP | ⚙️ Runtime
Define the action’s output. Becomes the tool’s return value.
Result in MCP responses
Result in MCP responses
Expression Formats
Three expression formats are available throughout connector YAML. For the complete reference including all built-in functions, see the Expression Language page.JSONPath ($.path)
Access data from context objects.
String Interpolation (${...})
Embed values in strings.
JEXL ('{{...}}')
Complex expressions with logic.
Expression format selection guide
Expression format selection guide
- Simple value access
- No transformation needed
- Used alone (not in string)
- Building URLs or strings
- Concatenating with static text
- Simple variable substitution
- Default values needed (
??operator) - Conditional logic required
- Complex transformations
- In
conditionfields
GraphQL Actions
For GraphQL APIs, use therequest function with POST method and query in body.
GraphQL best practices
GraphQL best practices
- Define variables for all dynamic values
- Use fragments for reusable field selections
- Keep queries focused (request only needed fields)
errors field in response:variables object, not inline in query: