Builds, debugs, and optimizes LeanIX automations using built-in actions when possible and scripts only when needed. Covers trigger types, action configuration, script templates, API deployment via MCP, error patterns, and multi-automation strategies. Use when creating new automations, debugging failing scripts, understanding automation triggers, deploying via API, converting Azure Functions, syncing subscriptions between fact sheets, managing tags based on relations, working with GraphQL mutations, auditing workspace automations, or transferring automation ownership.
Builds, debugs, and optimizes LeanIX automations using built-in actions when possible and scripts only when needed. Covers trigger types, action configuration, script templates, API deployment via MCP, error patterns, and multi-automation strategies. Use when creating new automations, debugging failing scripts, understanding automation triggers, deploying via API, converting Azure Functions, syncing subscriptions between fact sheets, managing tags based on relations, working with GraphQL mutations, auditing workspace automations, or transferring automation ownership.
argument-hint
[goal or script to debug]
license
Apache-2.0
compatibility
Requires LeanIX MCP server for API access (mcp__leanix__* tools)
Comprehensive help for LeanIX Run Script automations: create, debug, design, optimize, and learn.
CRITICAL: API Access
All LeanIX API calls use MCP tools. No shell commands, no token exchange, no curl.
Authentication is handled internally by the MCP server
No bearer tokens need to be managed in the skill workflow
No .mcp.json parsing is required — MCP handles credentials automatically
Before any LeanIX tool call: if only mcp__leanix__authenticate and mcp__leanix__complete_authentication are available, tell the user to run /mcp and authenticate the leanix server (browser opens automatically). Do NOT call authenticate yourself or suggest claude mcp add — the former returns a URL without triggering the browser flow (copy-paste UX), the latter would shadow the plugin's bundled server. If /mcp doesn't surface tools after auth, treat it as a plugin bug.
Anti-Patterns (Don't Do This)
Pattern
Why It Fails
function main(data) or function main(context)
main() takes zero parameters. data and context are injected globals at runtime.
function main(){}; export { main } (re-export) or export default function main()
The save-time validator requires direct export: export function main(), export async function main(), or export const main = ....
async function main() with no await inside
require-await lint rule blocks save. Drop async if no await.
Top-level await outside main()
Rejected by TS1308. await only works inside the async main() body.
import statements
Runner is --frozen --no-remote; rejected by TS2307. Only fetch, data, context, and standard JS built-ins are available.
TS-style type annotations in .js (e.g. function f(x: string))
These globals are deleted at runtime. ReferenceError at execute time.
Relying on console.log for visible output
Captured to stdout (returned in execution result), but NOT shown prominently in the Automations UI. For visible failure, throw new Error(...).
relApplicationToITComponent without wrapper
Must use ... on Application { relApplicationToITComponent { } }
Mutations without currentRev tracking
Revision conflict errors
No idempotency check
Infinite loop when automation re-triggers itself
Using name for ITComponent matching
Use displayName to include Provider prefix
Returning relations/subscriptions
Return object can't update these - use GraphQL
Using principal.id from technical user token as ownerId
Shows "null null" in UI — use set_owner_to_current_user=True or a real human user's ID
Guessing API endpoints (e.g., /scripts/{id}, /technicalUsers)
Use MCP tools — they handle endpoints internally
Setting creatorId on template update
Immutable; silently ignored (API returns 200 but no change)
Investigating UUIDs before comparing with working automations
Slow; comparison-first debugging is faster
Re-fetching templates without caching
Redundant MCP calls; cache list_automations() result in context for the session
Building the secret key dynamically ("default_" + "auto...")
Service auto-injection is a literal substring match on "default_automations_secret". Dynamic construction means no match — context.secrets ends up empty.
LIFECYCLE_PHASE_CHANGE trigger combined with IGNORE_TECHNICAL_USERS condition
Service rejects: technical-user condition is not allowed on job-type triggers.
Multiple actions with startsAfter: null (or zero such actions)
Exactly one first action is allowed per template. All others must chain via startsAfter.
Inline script: "..." field on an action payload
Service strips it. Always create scripts separately via POST /scripts and reference by scriptId.
Using console.warn / console.info / console.debug for diagnostics
Not captured by the runner; output is silently dropped. Only console.log and console.error are captured (to stdout / stderr).
Mutating data or context in place
The runner process is reused across executions and globals are restored between runs. Treat both as read-only.
Quick Reference
Trigger limitations:
Relation is removed - Can't see removed relation (use reconciliation)
Lifecycle state reached - Nightly only
Completion score changed - Fires on almost any edit
After the user selects a workflow, optionally verify schema awareness:
Run:mcp__leanix__get_automation_schema()
This returns the live trigger, condition, and action type reference from the API. Compare against references/API-REFERENCE.md if discrepancies are suspected.
Key principle: Never block the user. Schema checking is informational only.
[Create New Automation] Workflow
Step 1: Workspace Context (Automatic)
MCP handles authentication and workspace connection automatically. No credential extraction or token exchange needed.
Verify connection:
Call mcp__leanix__get_overview() to confirm workspace access and get basic statistics
Get owner ID (when needed for deployment):
Use mcp__leanix__search_users(email=...) to find a specific user's UUID
Or use set_owner_to_current_user=True on create_automation / update_automation to assign the authenticated user as owner
Display:Connected to LeanIX workspace - Ready for automatic deployment.
Step 2: Understand the Goal
Ask using AskUserQuestion:
"What do you want this automation to accomplish?"
Option
Likely Approach
Add/remove tags
Built-in
Set field value
Built-in
Change quality state
Built-in
Add subscription
Built-in
Create to-do/approval
Built-in
Send notification
Built-in
Multiple simple actions
Built-in
Tag based on relations
Script
Sync subscriptions
Script
Update relation attributes
Script
Calculate/aggregate
Script
Field from relations
Script
Custom conditional logic
Script
Other
Varies
Step 2.5: Evaluate Action Strategy
Decision Tree:
1. Does goal require reading data from OTHER fact sheets? → Script required
2. Does goal require modifying OTHER fact sheets? → Script required
3. Does goal require conditional logic based on related data? → Script required
4. Can goal be achieved with built-in actions? → Proceed to Step 3
5. Otherwise → Skip to Step 4 (Trigger Strategy for scripts)
Built-in Actions Available:
Action
What It Does
ADD_TAG / REMOVE_TAG
Add/remove tag
SET_FIELD
Set single-select field
SET_FIELD (fieldType: QUALITY_SEAL)
Set quality seal
ADD_SUBSCRIPTION / SET_SUBSCRIPTION
Manage subscribers
CREATE_ACTION_ITEM / CREATE_APPROVAL
Create to-dos/approvals
SEND_EMAIL_V2 / SEND_USER_WEBHOOK
Send notifications
If built-in actions suffice → Step 3
If script needed → Step 4
Step 3: Configure Actions (Built-in Only)
Use AskUserQuestion with multiSelect to select actions, then gather parameters for each.
Email placeholders use triple braces:{{{factsheet.displayName}}}, {{{link.factsheet}}}
Action ordering: Use startsAfter to chain actions. For approvals, use onResolution: "ACCEPTED" or "REJECTED".
See API Reference for detailed action configuration.
After configuring → Select trigger → Step 7.5 (Deploy)
Step 4: Recommend Trigger Strategy
Goal → Trigger Mapping (Common Patterns):
Goal
# Automations
Triggers
Sync subscriptions
4
Sub added, Sub removed, Rel added [source], Rel removed [target]
Tag based on relations
2
Relation added, Relation removed
Update field from relations
2-3
Rel added, Rel removed, Field changed [optional]
Initialize new FS
1
Fact sheet is created
Validate and block
1-2
Field changed OR Completion score changed
Key insight: "Relation is removed" trigger on source FS can't see the removed relation. Put cleanup on target FS.
Document the configuration for manual setup if needed.
Step 7.5: Deploy Action-Only Automation
When no script needed, create automation directly via POST /templates. Requires name, description, factSheetType, ownerId, trigger, conditions, actions, and active: false.
See API Reference for action payload examples and complete DTO structure.
Step 8.5: Pre-Deployment Checklist
Before deploying, verify ALL items:
#
Check
How to Verify
1
ownerId is a real human user
Use mcp__leanix__search_users(email=...) and verify display name
2
ownerId is NOT from technical user JWT
Verify it resolves to a human name (not "? ?" or "null null")
references/API-REFERENCE.md - API endpoints & deployment
examples/INDEX.md - Production scripts
[Analyze Workspace Automations] Workflow
Audit existing automations, update descriptions, and standardize naming conventions.
Speed: Load references/WORKSPACE-ANALYSIS.md + references/NAMING-CONVENTION.md + call mcp__leanix__get_overview() + mcp__leanix__list_automations() all in one parallel message to avoid sequential round-trips.