striketheviol

make-com-mastery

Build and debug Make.com scenarios with Claude Code or Claude Desktop. Covers blueprint structure, MCP tool safety (context overflow prevention), IML expressions, and working module patterns for HubSpot, Brevo, Discord, and OpenAI. Use when creating automations, debugging "successful" scenarios that produce wrong output, or integrating services through Make.com.

striketheviol 2 Updated 4mo ago

Resources

4
GitHub

Install

npx skillscat add striketheviol/make-com-mastery

Install via the SkillsCat registry.

SKILL.md

Make.com Mastery

A battle-tested skill for building and debugging Make.com scenarios with AI assistance.

Why This Skill Exists

Make.com's MCP integration is powerful but has hidden gotchas:

  • scenarios_get can return 200KB+ blueprints that overflow context windows
  • Scenarios report "success" while modules silently fail behind error handlers
  • IML syntax has unintuitive rules (1-based arrays, emptyarray requirement)

This skill documents patterns learned the hard way so you don't have to.

Quick Start

"Debug my scenario that says success but doesn't work"
→ Remove Ignore error handlers, check actual module errors

"Create a webhook that adds contacts to HubSpot and Brevo"
→ Use upsertAContact (not updateContact), build listIds with emptyarray + add()

"Update my scenario blueprint"
→ Fetch via API to file, modify with Python, PATCH back

Direct API vs MCP Decision Matrix

Default to the Direct API for blueprint modifications. The MCP is great for discovery but risky for complex updates.

Task Approach Why
Modify blueprints Direct API MCP can overflow context; API writes to disk
Bulk operations Direct API Data stays out of context window
Debug failed scenarios Direct API Full control over payloads
Fetch blueprints Direct API Save to file, parse with Python
Inspect a scenario MCP scenarios_get OK if used early in conversation only
List scenarios/connections MCP Quick, low-risk
Get module schemas MCP app-module_get Use format=instructions
Check execution status MCP executions_list Simple query
Discover module names MCP app-modules_list Fastest way
Validate module config MCP validate_module_configuration Pre-flight check

Context Overflow Warning

scenarios_get — Use Early or Use API

scenarios_get returns the full blueprint which can be 200KB+. It works via MCP, but only early in a conversation when context window headroom is large.

Rule of thumb:

  • First few messages? MCP scenarios_get is fine.
  • Long conversation with many tool calls? Fetch via Direct API and save to disk instead.

MCP Tool Risk Levels

Tool Risk Notes
scenarios_list, connections_list, executions_list ✅ LOW Always safe
app-modules_list, scenarios_interface ✅ LOW Always safe
app-module_get (format=instructions) ✅ LOW Always safe
validate_module_configuration ✅ LOW Pre-flight check
scenarios_get ⚠️ CONDITIONAL Safe early; use API later
executions_get_detail ⚠️ HIGH Prefer executions_list
app-module_get (format=json) ⚠️ MEDIUM Use format=instructions

Blueprint Modification Workflow

1. Fetch blueprint     → Direct API: curl ... -o blueprint.json (SAVE TO FILE)
                         OR early in conversation: MCP scenarios_get
2. Parse with Python   → Modify in memory/disk (NOT in context)
3. Validate            → MCP validate_module_configuration
4. Deactivate          → MCP scenarios_deactivate (or API /stop)
5. Update              → MCP scenarios_update (or API PATCH)
6. Activate            → MCP scenarios_activate (or API /start)
7. Test                → Trigger webhook / run scenario
8. Check executions    → MCP executions_list

Blueprint Structure Essentials

{
  "flow": [
    {
      "id": 1,
      "mapper": {},
      "module": "app:ModuleName",
      "version": 1,
      "metadata": {"designer": {"x": 0, "y": 0}},
      "parameters": {"__IMTCONN__": YOUR_CONNECTION_ID}
    }
  ],
  "name": "Scenario Name",
  "metadata": {
    "instant": false, "version": 1,
    "designer": {"orphans": []},
    "scenario": {"dlq": false, "dataloss": false, "maxErrors": 3, "autoCommit": true, "sequential": false}
  }
}

Key rules:

  • parameters: Static config (connection IDs). No IML expressions allowed.
  • mapper: Dynamic values. IML expressions go here.
  • Scenario inputs: Use {{var.input.fieldname}} — never {{1.fieldname}}.
  • Interface spec: Only name and type properties allowed.

Debugging "Successful" Scenarios

The Golden Rule: Ignore Handlers Mask Errors

A scenario can show status: 1 (SUCCESS) while modules silently fail. Error handlers like builtin:Ignore hide actual problems.

Debugging Workflow

1. Check execution status     → executions_list(scenarioId)
2. If status=1 but wrong output → Error handlers are hiding failures
3. Remove Ignore handlers      → Update blueprint with onerror:[] removed
4. Trigger test data           → Run the scenario
5. Check execution again       → Now status=3 with actual error
6. Read the error message      → [405], [400], validation errors, etc.
7. Fix root cause              → See Common Error Patterns
8. Re-add Ignore handlers      → Restore error handling once fixed

Common Error Patterns

Error Likely Cause Fix
[405] on HubSpot update updateContact is finicky Use upsertAContact instead
[400] Property values not valid Enum value mismatch Check contains() transforms
JSON blob in text field Wrong array access syntax Use [1] indexing, not first().nested
listIds/0 should be type number split() for numeric array Use add(emptyarray; N) pattern
'6' is not a valid array add() without emptyarray Start with add(emptyarray; 6)
BlueprintValidationError Wrong input variable syntax Use {{var.input.x}}

Common Pitfalls (Quick Reference)

  1. Array indexing is 1-based: [1] for first element, not [0]
  2. Nested access: Use {{6.choices[1].message.content}} not first().nested
  3. Ignore handlers hide errors: Remove them to debug
  4. updateContact is unreliable: Use upsertAContact
  5. Module names are case-sensitive: Verify with app-modules_list
  6. No IML in parameters: Never use {{...}} in parameters block
  7. Scenario input syntax: {{var.input.fieldname}}
  8. Interface spec: Only name and type properties
  9. Numeric arrays need emptyarray: add(emptyarray; N) pattern
  10. split() returns strings: Use emptyarray + add() for numbers

Reference Files

Load these as needed based on the task:

Examples

Example 1: Webhook → HubSpot + Brevo

User: "Create a webhook that captures form data, adds to HubSpot, and subscribes to Brevo list 6"

Claude: I'll create this scenario. Key patterns:
- Webhook trigger (builtin:BasicWebhook)
- HubSpot upsertAContact (not updateContact)
- Brevo CreateContact with listIds: {{add(emptyarray; 6)}}

Example 2: Debug Silent Failure

User: "My scenario shows success but the HubSpot contact isn't updating"

Claude: This is usually an Ignore handler masking errors. Let me:
1. Fetch the blueprint via API
2. Find modules with onerror: [{"handler": "builtin:Ignore"}]
3. Temporarily remove them
4. Re-run to see the actual error

Example 3: AI Research Bot

User: "Build a scenario that takes a company name and enriches the contact with research"

Claude: I'll use:
- Scenario inputs (interface) for company name
- OpenAI/Perplexity module for research
- Access response with {{3.choices[1].message.content}} (1-based!)
- HubSpot upsertAContact to save findings

License

MIT — Use freely, attribution appreciated.