Build, debug, and create LeanIX Calculations — populate computed fields from other fields and relations. Use when creating new calculations, debugging errors, understanding calculation capabilities, managing workspace calculations, or analyzing existing calculations. Covers target field types, field access patterns, relation data, templates, error patterns, and best practices.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Build, debug, and create LeanIX Calculations — populate computed fields from other fields and relations. Use when creating new calculations, debugging errors, understanding calculation capabilities, managing workspace calculations, or analyzing existing calculations. Covers target field types, field access patterns, relation data, templates, error patterns, and best practices.
license
Apache-2.0
compatibility
Requires LeanIX MCP server for API access (mcp__leanix__* tools)
Comprehensive help for LeanIX Calculations: create, debug, design, and manage.
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.
⚠️ WORKSPACE-SPECIFIC DATA MODEL
Do NOT assume standard fact sheet types, fields, or relations exist.
Every LeanIX workspace has custom configurations. Before creating or debugging calculations:
Fact sheet types are enumerated in the create_calculation tool schema — no discovery call needed
Fetch SDL using mcp__leanix__list_graphql_types + mcp__leanix__get_graphql_type_definitions for fields, relations, and enums
Present discovered options to the user (not hardcoded lists)
Validate all names exist before generating code
Reference files in this skill contain static examples only. Always use live workspace data.
CRITICAL: Calculations vs Automations
Calculations are fundamentally different from Automations:
Aspect
Calculations
Automations
Purpose
Populate computed fields
React to events with actions
Trigger
Auto-triggers on source field change
12 explicit trigger types
API calls
NOT allowed
Allowed (fetch, GraphQL)
Async
NOT supported
Supported
Output
Single value (string/number/array)
Object with field names
Creation
Single API call
Two calls (script + template)
Two Calculation Types
Type
Use Case
fact-sheet
Compute a field value on a fact sheet using its own data
relation
Compute a field value on a relation (the edge between two fact sheets) using data from either side
Anti-Patterns (Don't Do This)
Pattern
Why It Fails
async function main()
Async not supported
await fetch(...)
No API calls allowed
import statements
No imports allowed
return { field: value }
Must return single value
data.factSheet.field in fact-sheet calc
Use data.field directly
data.field in relation calc
Use data.factSheet.field
Reading target field
Circular dependency error
Using principal.id from technical user token as owner_id
Always use a real human user's userId from search_users
Greeting
When this skill is invoked, display this welcome message:
SAP LeanIX Calculation Assistant
Welcome! I help you build, debug, manage, and create LeanIX Calculations—computed fields that automatically populate from other fields and relations.
Reference Files (Progressive Disclosure)
Load these files only when needed for specific workflow steps:
File
Load When
Contains
references/API-REFERENCE.md
Creating calculations (Step 6)
API endpoints, CalculationDto
references/TEMPLATES.md
Generating code (Step 5)
Ready-to-use calculation templates
references/LEANIX-MODEL.md
Understanding field types
Fact sheet types, relations, field access
references/NAMING-CONVENTION.md
Standardizing names
Naming convention
references/ANALYSIS-RULES.md
Analyzing calculations
Code analysis rules, workspace checks
Workflow
Step 0: Determine Intent
First, check if the user's message already expresses clear intent. If it does, skip AskUserQuestion and branch directly:
If the user's message contains…
Branch to
"what can", "what does", "capabilities", "help me", "do for me"
[Understand Capabilities]
"create", "build", "new calculation", "add a calculation"
Only ask if intent is genuinely ambiguous. Use AskUserQuestion:
IMPORTANT: AskUserQuestion supports 2–4 options only. When there are more than 4 choices, list all options as a numbered list in plain text and ask the user to type their selection instead.
What do you need help with?
Option
Description
Create new calculation
Build a new calculated field
Debug failing calculation
Diagnose and fix a calculation that's not working
Understand capabilities
Learn what calculations can do
Manage workspace calculations
Query, analyze, fix, or reorganize existing calculations
Branch to the appropriate workflow based on response.
Step 0.1: Verify Calculations Toolset
Run immediately after determining intent (before any other MCP call):
Call mcp__leanix__list_calculations(). This is a lightweight check that confirms the calculations toolset is active.
If the call succeeds: Continue to the next step silently (no message needed).
If the tool is not found / not available:
The calculations toolset is optional and hidden by default. Display this message to the user:
Calculation tools are not available. Your MCP connection is missing the calculations toolset.
Fix: Add ?toolsets=inventory,calculations,custom_reports to your MCP server URL.
Claude Code (OAuth):
claude mcp remove leanix
claude mcp add --transport http leanix "https://mcp.leanix.net/services/mcp-server/v1/mcp?toolsets=inventory,calculations,custom_reports"
MCP handles authentication and workspace connection automatically. No credential extraction or token exchange needed.
Verify connection:
Call mcp__leanix__list_calculations() to confirm workspace access (already done in Step 0.1).
Display:Connected to LeanIX workspace - Ready to create calculations.
Fallback: If MCP not configured, offer to set up MCP.
Step 1.5: Discover Workspace Data Model
CRITICAL: Do NOT assume standard fact sheet types, fields, or relations exist.
Every workspace has custom configurations. ALWAYS discover before proceeding.
Fact sheet types are enumerated in the create_calculation tool schema — no discovery call needed.
Discover field keys, relation names, and enum values using the GraphQL SDL:
Step 1: mcp__leanix__list_graphql_types(filter="{FactSheetType}")
→ finds type names e.g. "Application", "ApplicationToBusinessCapabilityRelation"
Step 2: mcp__leanix__get_graphql_type_definitions(["Application", "ApplicationToBusinessCapabilityRelation"])
→ returns SDL with all fields, relations, and enum values
The SDL response gives you:
All fields with their types (e.g., functionalSuitability: ApplicationFunctionalSuitability)
All relations and what they connect (e.g., relApplicationToBusinessCapability: ApplicationToBusinessCapabilityRelationConnection)
All enum values for Single Select fields
Extract and store from the SDL:
Data
Use
Field names and types
Present as target field options in Step 2
Relation names
Present as source data options in Step 3
Enum values
Validate return type for Single Select targets
Display to user:
Found fact sheet types in your workspace.
Which fact sheet type should this calculation target?
Why this step is mandatory:
Workspaces have custom fields beyond the standard set
Relation names depend on how the workspace was configured
Enum options for Single Select fields are workspace-specific
Using wrong names causes configurationErrorCount errors
Store the data model for use in subsequent steps - do not re-query.
Step 2: Identify Target Field
Use data model from Step 1.5 - Do not ask for free-text field names.
Present fact sheet types from data model:
IMPORTANT: AskUserQuestion supports 2–4 options only. When there are more than 4 choices (e.g., fact sheet types), do NOT use AskUserQuestion. Instead, list all options as a numbered list in plain text and ask the user to type their choice. Wait for the user's text reply before proceeding.
After user selects fact sheet type, present fields from data model:
Tool: AskUserQuestion
"Which field should this calculation populate?"
Options: [Custom fields from data model for selected type]
[Show field types: Double, Integer, String, Single Select, etc.]
If the target field doesn't exist yet: The field must be created in the LeanIX UI before a calculation can populate it.
How to create a custom field:
Go to the fact sheet configuration page and select the subsection where you want the field
Click Add field
Configure the field parameters in the right-side panel
Based on the goal, determine the calculation pattern:
Goal
Pattern
Template
Count relations
data.rel.length
Template 1
Sum numeric field
reduce((a,b) => a+b, 0)
Template 2
Average
Sum / length
Template 3
Min/Max
Math.min/max(...values)
Template 4
Derive status
Map value to enum
Template 5-7
Days until date
Date difference
Template 8
Concatenate strings
Template literals
Template 9
Collect unique values
new Set()
Template 10
Conditional
If-then-else
Template 11
Scoring
Weighted calculation
Template 12
Completeness
Check required fields
Template 13
Default values
Null coalescing
Template 14
→ For templates: Load references/TEMPLATES.md
Step 5: Generate Calculation Code
Critical Rules Checklist:
NO imports - only data available
NO async/await - must be synchronous
NO fetch() - no API calls allowed
MUST read at least one data.* field (API rejects otherwise)
Use export function main() (never async)
Return single value matching target field type
Return null to clear field, undefined for no change
Add inline comments explaining non-obvious logic (e.g. why a fallback value is used, what a condition guards against)
Fact Sheet Calculation Template:
/**
* [CALCULATION NAME]
* Type: fact-sheet
* Fact Sheet: [TYPE]
* Target Field: [FIELD] ([TYPE])
* Logic: [DESCRIPTION]
*/exportfunctionmain() {
// Guard: return null to clear the field if required source data is missingif (!data.someRequiredField) returnnull;
// [Explain non-obvious logic, e.g. why a fallback value is used]const value = data.someField ?? 0;
// [Explain what this condition guards against]if (data.someRelation.length === 0) returnnull;
return value;
}
Relation Calculation Template:
/**
* [CALCULATION NAME]
* Type: relation
* Fact Sheet: [TYPE]
* Relation: [RELATION_NAME]
* Target Field: [FIELD] ([TYPE])
* Logic: [DESCRIPTION]
*/exportfunctionmain() {
// Guard: no value to compute if source field is unset on the related fact sheetconst sourceValue = data.factSheet.someField;
if (sourceValue == null) returnnull;
// [Explain distribution logic, weighting, or other non-obvious computation]const count = data.factSheet.someRelation.length;
// Avoid division by zero when no related items existif (count === 0) returnnull;
return sourceValue / count;
}
Step 5.5: Test Run
RECOMMENDED: Test calculation code against real data before creating it.
The test-run executes your code in a sandbox against a real fact sheet without creating or modifying any calculation. Use it to:
Validate logic - Confirm the code returns expected values
Test edge cases - Verify null/empty handling across different fact sheets
A relation calculation runs against a specific edge between two fact sheets. Identify the edge by passing the source and target fact sheet UUIDs along with the relation name — the MCP server resolves the underlying relation instance automatically.
Alternative: If you already have a relation instance UUID (e.g., from the LeanIX UI), pass it as affected_relation_id instead of the from/to pair.
Interpreting results:
Field
Meaning
success: true
Code ran and result is valid for the target field
success: false
Code ran but result is invalid (wrong type, etc.)
result
The actual return value from the code
data
The executor input — inspect to understand what data.* contains
Debugging tips:
Inspect executorInput.data in the test-run response to see available fields
Test with fact sheets that have different data (empty relations, missing fields)
If success: false, check that return type matches target field type
Proceed to creation only when:
Test returns success: true
Result value is the expected value
No unexpected null/undefined returns on edge-case fact sheets
Step 5.7: Select Calculation Owner
Every calculation requires an owner_id — the LeanIX user who owns the calculation in the workspace. The owner must be a real human user, not a technical user.
Ask the user using AskUserQuestion:
"Who should own this calculation?"
Option
Description
Assign me as owner
Look up the current user's email and use their userId
Search for another user
Look up a different user by name or email
If the user picks "Assign me as owner":
Ask for their email if not already known
Run mcp__leanix__search_users(email="...")
Use the userId field (NOT id) from the result as owner_id
If the user picks "Search for another user":
Ask: "What's the user's name or email?"
Run mcp__leanix__search_users(query="...") (or email="...")
If multiple matches, present them via AskUserQuestion and let the user pick
Use the userId field (NOT id) from the chosen result as owner_id
Validation: Verify displayName resolves to a real human (not blank, "? ?", or "null null"). If it doesn't, the result is likely a technical user — search again.
Step 5.8: Confirm Before Creating
Present the final calculation to the user before creating it:
Then ask using `AskUserQuestion`:
**"Create this calculation?"**
| Option | Description |
|--------|-------------|
| **Create** | Proceed with creation |
| **Edit code** | Go back and modify the code |
| **Cancel** | Abort |
Only proceed to Step 6 if the user confirms.
---
### Step 6: Create Calculation
Use the MCP tool to create the calculation. The `owner_id` was selected in Step 5.7.
**Fact-sheet calculation:**
Tool: mcp__leanix__create_calculation
Parameters:
name: "Calculation Name"
description: "What it calculates"
type: "fact-sheet"
affected_fact_sheet_type: "Application"
affected_field_key: "fieldName"
code: "export function main() { ... }"
status: "inactive"
owner_id: "{USER_UUID from Step 5.7}"
**Success:** Report the calculation ID and URL: `https://{INSTANCE}.leanix.net/{WORKSPACE}/admin/calculations/{id}`
> **Deriving INSTANCE and WORKSPACE:** If unknown, call `mcp__leanix__text_to_fact_sheets` with any query (e.g. `"Application"`) and extract the base URL from any fact sheet's `url` field — it will be in the form `https://{INSTANCE}.leanix.net/{WORKSPACE}/...`. All calculation URLs share the same base; only the `{id}` segment changes per calculation.
→ **For creation details:** Load `references/API-REFERENCE.md`
### Step 7: Enable Calculation
> **Rule:** Source fields (data.*) are extracted from the calculation code **only when it is enabled**, not when saved as inactive.
Ask the user using `AskUserQuestion`:
**"The calculation was created as inactive. Enable it now?"**
| Option | Description |
|--------|-------------|
| **Enable now** | Activate the calculation so it starts computing values |
| **Keep inactive** | Leave it inactive for manual review first |
If the user chooses **Enable now**, call:
### Step 6.5: Verify Creation
After creating the calculation, verify it works correctly:
1. **Check creation succeeded**
- Confirm calculation appears in LeanIX Admin → Calculations
- Verify target field and fact sheet type are correct
- Check `invalid` is not `true`
2. **Review calculated values**
- Activate the calculation and check field values on sample fact sheets in the UI
- Verify results match expected values
3. **Review for edge cases**
Before marking complete, consider:
- What happens if source data is null/empty?
- Does the return type match the target field type?
- What if relations have zero items?
- Can this calculation be simpler?
Ask: "Would you like me to review edge cases before we finalize?"
### Step 7: Ask for Refinements
Offer:
- Test the calculation
- Add edge case handling
- Create related calculations
---
## [Debug Failing Calculation] Workflow
### Step 1: Collect Information
Request: calculation code, error message (if any), expected vs actual behavior, calculation type.
### Step 2: Automated Diagnostic Checks
| Check | Issue | Fix |
|-------|-------|-----|
| `async` keyword | Calculation is async | Remove async - must be synchronous |
| `await` keyword | Using await | Remove - no async operations |
| `fetch` | API call attempted | Remove - not allowed in calculations |
| `import` | Import statement | Remove - no imports allowed |
| Export syntax | Missing `export` | Use `export function main()` |
| Return type | Returning object | Return single value |
| Data access (fact-sheet) | Using `data.factSheet` | Use `data.field` directly |
| Data access (relation) | Using `data.field` | Use `data.factSheet.field` |
### Step 3: Check Common Errors
| Error | Cause | Fix |
|-------|-------|-----|
| `invalid: true` | Syntax error in code | Check JS syntax |
| High `errorCount` | Runtime errors | Check null handling |
| High `configurationErrorCount` | Bad field/relation names | Verify against data model |
| No updates happening | Returning `undefined` | Return actual value or `null` |
| Wrong value type | Type mismatch | Return correct type for field |
### Step 4: Provide Diagnosis
Generate diagnostic report with issues found and recommended fixes.
### Step 5: Offer Corrected Code
Ask if user wants fully corrected calculation code generated.
---
## [Understand Capabilities] Workflow
**Can calculate:**
- Field values from same fact sheet (fact-sheet type)
- Field values from related fact sheet (relation type)
- Values from related fact sheets via relations
- Relation attributes
- Aggregations (count, sum, average, min, max)
- String operations
- Date calculations (days until/since)
- Conditional logic
- Multi-select collections
**Cannot calculate:**
- Values requiring API calls
- Values from fact sheets not directly related
- Real-time external data
- Values requiring async operations
**Target field types supported:**
- Double (decimal numbers)
- Integer (whole numbers)
- String (text)
- Single Select (enum)
- Multiple Select (array of enum)
- External ID (string)
**Target field limitations:**
- Base fields (built-in) cannot be targets
- Each field can have only ONE calculation
- Cannot create circular dependencies
→ **For detailed capabilities:** Load `references/LEANIX-MODEL.md`
---
## [Manage Workspace Calculations] Workflow
Use this workflow to query, analyze, fix, or reorganize existing calculations.
### Step 1: Connect to Workspace
Reuse workspace connection from "Create New Calculation" Step 1.
### Step 2: Discover Data Model
> **CRITICAL:** Query data model BEFORE fetching calculations to enable validation.
Tool: mcp__leanix__get_fact_sheet_types
Then inspect a sample fact sheet for each type of interest:
Store the data model for validation in subsequent steps.
### Step 3: Fetch All Calculations
Tool: mcp__leanix__list_calculations
Returns all calculations in the workspace with their metadata, status, and error counts.
> **Display rule:** Never surface raw API response metadata (`hasNextPage`, `nextCursor`, pagination counts) to the user. Only present calculation data itself.
### Step 4: Analyze Calculations
For each calculation, **validate against data model**:
| Check | Field | Issue If |
|-------|-------|----------|
| Naming convention | `name` | Doesn't follow pattern |
| Description | `description` | Empty or generic |
| Code quality | `code` | Contains debug statements, etc. |
| Target field exists | `affectedFieldKey` | Not in data model |
| Has errors | `errorCount` | > 0 |
| Has config errors | `configurationErrorCount` | > 0 |
| Has owner | `ownerId` | null |
| Is active | `status` | "inactive" when should be active |
**Report categories:**
- **Critical:** High error counts, invalid calculations
- **Warning:** Missing owners, empty descriptions
- **Info:** Naming convention suggestions
### Step 5: Fix Issues (Validating Against Data Model)
For each issue found:
**Update name/description/code:**
Tool: mcp__leanix__update_calculation
Parameters:
id: "{UUID}"
name: "New Name" (optional)
description: "New desc" (optional)
code: "..." (optional)
**Set owner (lookup user ID first via MCP):**
Tool: mcp__leanix__search_users
Parameters: { "query": "user name or email" }
Use the `userId` field (not `id`) from the result, then:
**Create new calculations as needed:**
Follow the "Create New Calculation" workflow.
### Step 7: Present Report
Summarize:
- Total calculations analyzed
- Issues found by category
- Actions taken
- Recommendations for manual review
---
## Debugging with Execution Logs
Use execution logs to audit calculation behavior, diagnose failures, and inspect exactly what ran and why.
### When to Use
| Scenario | Tool |
|----------|------|
| Show recent runs for a calculation | `list_execution_logs` with `calculation_id` |
| Find all failures in the last week | `list_execution_logs(status=["failed"], date_from=<date>, date_to=<date>)` |
| Inspect why a specific fact sheet has an unexpected value | `list_execution_logs` with `fact_sheet_id` |
| Understand what triggered a recalculation | `list_execution_logs` — inspect `trigger` in results |
| See the exact code and context data that ran | `get_execution_log` with the log entry `id` |
### Common Workflows
**Diagnose a failed run:**
Inspect `input.contextData` (what data the code saw) and `output` (what it wrote).
---
## Quick Reference
**Data Access Patterns:**
```javascript
// FACT-SHEET CALCULATIONS (type: "fact-sheet")
// Target: field on the fact sheet itself
data.fieldName // Direct field access
data.lifecycle.currentPhase // Lifecycle phase ("plan", "phaseIn", "active", "phaseOut", "endOfLife")
data.naFields // string[] of field keys intentionally left blank (NA)
data.relationName // Relation array
data.relationName[0].factsheet // Related fact sheet
data.relationName[0].factsheet.fieldName // Field on related FS
// RELATION CALCULATIONS (type: "relation")
// Target: field on a relation
data.factSheet.fieldName // Related fact sheet's field
data.factSheet.lifecycle.currentPhase // Related fact sheet's lifecycle
data.factSheet.naFields // NA fields on the related fact sheet
Return Values:
return42; // Numberreturn"text"; // Stringreturn"option1"; // Single selectreturn ["opt1", "opt2"]; // Multi-selectreturnnull; // Clear fieldreturnundefined; // No change (AVOID - usually indicates bug)
MCP Integration Points
Discover Data Model
Use the GraphQL schema tools to discover workspace configuration:
Step 1: List available fact sheet types
Tool: mcp__leanix__list_graphql_types
Parameters: { "filter": "{FactSheetType}" }
Step 2: Fetch SDL for the relevant types
Tool: mcp__leanix__get_graphql_type_definitions
Parameters: { "type_names": ["{FactSheetType}", "{RelationType}"] }
Returns SDL with all fields, relations, and enum values for each type.
Calculations CRUD
mcp__leanix__list_calculations - List all calculations
mcp__leanix__get_calculation - Get single calculation by ID
mcp__leanix__create_calculation - Create new calculation
mcp__leanix__update_calculation - Update existing calculation
mcp__leanix__delete_calculation - Delete calculation
mcp__leanix__enable_calculation - Set status to active
mcp__leanix__disable_calculation - Set status to inactive
mcp__leanix__test_run_calculation - Test code against a fact sheet/relation without saving
Execution Logs
mcp__leanix__list_execution_logs - List execution logs; filter by date_from/date_to, status[], trigger[], calculation_id[], fact_sheet_id[]
mcp__leanix__get_execution_log - Get full detail of a single log entry: input.code, input.contextData, output, previousValue, codeVersionStatus
Search Users
Tool: mcp__leanix__search_users
Use: Get owner ID for new calculations (use userId field, not id)
Parameters: { "email": "user@example.com" }
External Documentation
CLAUDE.md - Critical rules (root level)
.claude/docs/field-access-patterns.md - Data access patterns
.claude/docs/supported-fields.md - Target field types