- 🖥️ 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 — authentication changes, removed/renamed actions, changed response or request shape, or behavioral 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.scopeDefinitions
Impact: 🖥️ UI · ⚙️ Runtime
Declares the requirements an action can depend on, keyed by scope name. Commonly OAuth or API scopes, but the same mechanism represents any prerequisite: a pricing tier, a platform feature, a configuration flag.
requiredScopes, and guide sections through applicableScopes. Both are validated against the keys defined here, so a reference to an undeclared scope fails validation.
Hierarchical scopes and naming
Hierarchical scopes and naming
includes should only reflect relationships the provider actually documents. A write scope typically includes its read counterpart, and a broader scope includes a narrower one, but a read-only scope must never include a write scope.authentication Section
Defines how end-users authenticate with the provider. Supports multiple authentication methods per connector.
Authentication Array Structure
Multiple authentication methods
Multiple authentication 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 authentication 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 authentication 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 (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 (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 authentication 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
support and Guides
Impact: 🖥️ UI
Each authentication method can carry its own instructions as structured data, under support.guides. For StackOne authored connectors, these are published as the guide pages under Connectors. You can also fetch the same content from the API and render it in your own product, which is covered in Rendering Guides.
Which guide to write
guides.config with no configFields documents inputs nobody is asked for.
events.guides.setup, for instructions on configuring a webhook in the provider.Section and step fields
Both guides take awarning and a required array of sections. Sections and steps share the same shape, and steps nest one level inside a section.
Scope-aware guide content
Scope-aware guide content
applicableScopes filters instructions down to the configuration the user actually chose, so a read-only integration doesn’t get told to grant write permissions:scopeDefinitions, and validation fails if it doesn’t.displayScopes: true on a step renders badges for the actions those scopes unlock, which is useful on the step where a user picks scopes in the provider’s consent screen:support.link and where the Hub sends users
support.link and where the Hub sends users
support.link points at your own rendered version of these guides. The Hub sends users there instead of to StackOne’s pages.guides.config has sections, StackOne fills it in with that connector’s own generated guide page, built from the connector key and the authentication label:link when you want users in your product rather than in StackOne’s docs.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 and Step Functions
The steps array and the available step functions (request, paginated_request, map_fields, group_data, typecast, soap_request, static_values, merge_collections, code_execution_lambda, and Iterator Steps) are documented on a dedicated page. See Step Functions.
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: