Claude Code (der AI-Brain) + n8n (der Workflow-Engine) = kraftvolle Kombination. Dieser Guide zeigt dir, wie man sie zusammenbringt.

Warum Claude Code + n8n zusammen?

Tool Spezialität Kann nicht
Claude Code Intelligenz, Code-Analyse, Entscheidungen Regelmäßige Execution, Scheduling, Multi-Step Orchestration
n8n Workflow-Orchestration, Scheduling, Web-Integrations, Datenfluss Intelligente Entscheidungen, Code-Analyse, Learning

Zusammen:

n8n empfängt Event (z.B. Email)
  ↓
Sendet an Claude Code Webhook
  ↓
Claude Code analysiert intelligent
  ↓
Gibt Decision/Output an n8n zurück
  ↓
n8n führt basierend auf Decision die nächsten Steps aus

Result: Intelligente Automatisierung + Zuverlässige Execution

Architektur: Wie sie kommunizieren

┌─────────────────────────────────────────┐
│              n8n Workflow                │
├─────────────────────────────────────────┤
│ [Webhook Trigger] → Email Received      │
│      ↓                                   │
│ [Extract Data] → Parse Email             │
│      ↓                                   │
│ [HTTP Request] → Call Claude Code CLI    │
│      (POST to http://localhost:3000/)   │
│      ↓                                   │
│ [Decision Node] → If result contains     │
│                   "spam" → Delete        │
│                   "important" → Alert    │
│                   "normal" → Archive     │
└─────────────────────────────────────────┘
        ↑                          │
        └──────────────────────────┘

Pattern 1: n8n Webhook → Claude Code → n8n

Setup: Claude Code als HTTP Server

# claude_code_server.py

from flask import Flask, request, jsonify
import anthropic
import json

app = Flask(__name__)
client = anthropic.Anthropic()

@app.route('/analyze', methods=['POST'])
def analyze():
    """
    HTTP Endpoint für n8n
    n8n sendet data, wir analysieren mit Claude
    """
    data = request.json
    text = data.get('text', '')
    task = data.get('task', 'Analyze this')

    # Call Claude Code
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=1024,
        messages=[{
            "role": "user",
            "content": f"{task}:\n\n{text}"
        }]
    )

    result = response.content[0].text

    # Parse Claude output (erwarten wir JSON)
    try:
        result_json = json.loads(result)
    except:
        result_json = {"text": result, "parsed": False}

    return jsonify({
        "status": "success",
        "analysis": result_json,
        "tokens": response.usage.input_tokens + response.usage.output_tokens
    })

@app.route('/classify', methods=['POST'])
def classify():
    """
    Klassifiziere Email in: Spam, Wichtig, Normal
    """
    data = request.json
    email = data.get('email', '')

    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=200,
        messages=[{
            "role": "user",
            "content": f"""Klassifiziere diese Email als JSON:
{{
  "category": "spam" | "important" | "normal",
  "confidence": 0.9,
  "reason": "string"
}}

Email:
{email}"""
        }]
    )

    result = response.content[0].text

    try:
        classification = json.loads(result)
    except:
        classification = {"category": "normal", "confidence": 0.5}

    return jsonify(classification)

if __name__ == '__main__':
    app.run(port=3000, debug=False)

n8n Workflow (JSON)

{
  "nodes": [
    {
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [250, 300],
      "webhookId": "123abc",
      "webhookPath": "email-classifier"
    },
    {
      "name": "Extract Email Data",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [450, 300],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "email_text",
              "value": "={{ $json.body.email_content }}"
            }
          ]
        }
      }
    },
    {
      "name": "Call Claude Code",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [650, 300],
      "parameters": {
        "method": "POST",
        "url": "http://localhost:3000/classify",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "email",
              "value": "={{ $node['Extract Email Data'].json.email_text }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "name": "Router",
      "type": "n8n-nodes-base.router",
      "typeVersion": 1,
      "position": [850, 300],
      "parameters": {
        "routes": [
          {
            "name": "Spam",
            "value": "={{ $node['Call Claude Code'].json.category === 'spam' }}"
          },
          {
            "name": "Important",
            "value": "={{ $node['Call Claude Code'].json.category === 'important' }}"
          },
          {
            "name": "Normal",
            "value": "={{ true }}"
          }
        ]
      }
    },
    {
      "name": "Delete Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "position": [1050, 200],
      "parameters": {
        "operation": "delete",
        "messageId": "={{ $json.messageId }}"
      }
    },
    {
      "name": "Send Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 3,
      "position": [1050, 300],
      "parameters": {
        "text": "🔴 Important Email: {{ $json.subject }}"
      }
    },
    {
      "name": "Archive",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "position": [1050, 400],
      "parameters": {
        "operation": "addLabel",
        "label": "Archived"
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [[{"node": "Extract Email Data", "branch": 0}]]
    },
    "Extract Email Data": {
      "main": [[{"node": "Call Claude Code", "branch": 0}]]
    },
    "Call Claude Code": {
      "main": [[{"node": "Router", "branch": 0}]]
    },
    "Router": {
      "main": [
        [{"node": "Delete Email", "branch": 0}],
        [{"node": "Send Alert", "branch": 0}],
        [{"node": "Archive", "branch": 0}]
      ]
    }
  }
}

Pattern 2: n8n generiert Workflows mit Claude Code

Szenario: "Baue mir einen Workflow für X"

# claude_code_workflow_generator.py

#!/usr/bin/env python3

import anthropic
import json
import subprocess

client = anthropic.Anthropic()

def generate_workflow(requirement: str) -> str:
    """
    Claude Code generiert n8n Workflow JSON
    """
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=4000,
        messages=[{
            "role": "user",
            "content": f"""
You are an n8n workflow expert.

Generate a complete n8n workflow JSON for:
{requirement}

Requirements:
1. Use realistic n8n node types (webhook, http, slack, gmail, etc.)
2. Include proper connections between nodes
3. Add parameters for each node
4. Output ONLY valid JSON, no explanations

The workflow should:
- Handle errors
- Log important steps
- Include all necessary parameters

Output format:
{{
  "nodes": [...],
  "connections": {...}
}}
"""
        }]
    )

    workflow_json = response.content[0].text

    # Validiere JSON
    try:
        workflow = json.loads(workflow_json)
        return workflow_json
    except:
        print("❌ Generated invalid JSON, retrying with constraints...")
        # Retry mit strengeren Constraints
        return None

def deploy_workflow(workflow_json: str, n8n_url: str, n8n_api_key: str):
    """
    Deploy den generierten Workflow zu n8n
    """
    import requests

    # Import via n8n API
    headers = {
        "X-N8N-API-KEY": n8n_api_key,
        "Content-Type": "application/json"
    }

    response = requests.post(
        f"{n8n_url}/api/v1/workflows",
        headers=headers,
        json=json.loads(workflow_json)
    )

    if response.status_code == 201:
        workflow_id = response.json()['id']
        print(f"✓ Workflow deployed: {workflow_id}")

        # Aktiviere Workflow
        requests.patch(
            f"{n8n_url}/api/v1/workflows/{workflow_id}",
            headers=headers,
            json={"active": True}
        )

        return workflow_id
    else:
        print(f"❌ Deploy failed: {response.text}")
        return None

# Nutze es
requirement = """
Customer support workflow:
1. Email kommt an
2. Claude Code analysiert Intent (bug report, feature request, billing issue)
3. Basierend auf Intent:
   - Bug: Create GitHub issue, Email to Dev Team, Add to Backlog
   - Feature: Add to Feature Board, Email to Product Owner
   - Billing: Create ticket in Zendesk, Email to Finance
4. Send confirmation to customer
"""

workflow = generate_workflow(requirement)

if workflow:
    print("Generated workflow:")
    print(workflow[:200] + "...")

    # Deploy (if n8n is running)
    # deploy_workflow(workflow, "http://localhost:5678", "your_api_key")

Pattern 3: n8n Workflow mit Claude Code Nodes

n8n hat eine "Code Node", wo du JavaScript/TypeScript schreiben kannst. Du kannst Claude API direkt aufrufen:

// Inside n8n Code Node

const Anthropic = require("@anthropic-ai/sdk");

const client = new Anthropic({
  apiKey: $('env', 'ANTHROPIC_API_KEY') // n8n Environment Variable
});

// Analysiere den bisherigen Workflow Context
const emailSubject = $node.previous().json.subject;
const emailBody = $node.previous().json.body;

// Call Claude
const response = await client.messages.create({
  model: "claude-3-5-sonnet-20241022",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: `Classify this support email:

Subject: ${emailSubject}
Body: ${emailBody}

Respond with JSON:
{
  "category": "bug|feature|billing",
  "priority": "high|medium|low",
  "assignee": "devops|product|finance"
}`
    }
  ]
});

// Return für nächste Node
return {
  json: {
    analysis: response.content[0].text,
    tokens_used: response.usage.input_tokens + response.usage.output_tokens
  }
};

Pattern 4: Automated Testing mit Claude Code + n8n

n8n Workflows brauchen Tests. Claude Code kann sie generieren:

# test_n8n_workflow.sh

#!/bin/bash

N8N_URL="http://localhost:5678"
WORKFLOW_ID="abc123xyz"

# 1. Erstelle Test-Daten
TEST_DATA='{"email": "[email protected]", "subject": "Help"}'

# 2. Trigger Workflow via Webhook
WEBHOOK_URL="$N8N_URL/webhook/test-email"
RESPONSE=$(curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d "$TEST_DATA")

echo "Workflow Response: $RESPONSE"

# 3. Nutze Claude Code um Response zu validieren
claude-code run -p "
Validate this n8n workflow response:
$RESPONSE

Check:
1. Status is 200-299
2. Result has required fields
3. No errors in execution

Output JSON:
{
  \"valid\": true/false,
  \"issues\": [...]
}"

Pattern 5: DSGVO-Compliance bei Claude + n8n Integration

Problem: Wenn Claude Code personenbezogene Daten verarbeitet (Namen, Emails, etc.), brauchst du Compliance.

Datenschutz-Checkliste

# DSGVO Compliance für Claude + n8n

## Datenfluss
- [ ] Daten fließt: User → n8n → Claude Code
- [ ] Verschlüsselung: TLS/HTTPS bei allen Übertragungen
- [ ] Storage: Daten NICHT in Claude Context speichern
- [ ] Retention: Claude Context wird regelmäßig geleert (/compact)
- [ ] Deletion: Nutzer-Anfrage auf Datenlöschung wird umgesetzt

## Claude Code Nutzung
- [ ] System Prompt erklärt dass PII-Daten anonym werden
- [ ] Keine Daten länger als nötig speichern
- [ ] Output wird anonymisiert bevor es zurückkommt
- [ ] Audit Log welche User-Daten Claude sah

## n8n Integration
- [ ] n8n ist selbst gehostet (nicht Cloud)
- [ ] Database ist verschlüsselt
- [ ] Backups sind verschlüsselt
- [ ] Zugriff ist log-tracked
- [ ] PII-Daten werden vor Claude anonymisiert

Implementierung

# Anonymize before sending to Claude

def anonymize_pii(text: str) -> dict:
    """
    Entferne PII bevor es zu Claude geht
    Return: (anonymized_text, mapping)
    """
    import re

    mapping = {}

    # Email Adressen
    emails = re.findall(r'[\w\.-]+@[\w\.-]+', text)
    for i, email in enumerate(emails):
        placeholder = f"[EMAIL_{i}]"
        text = text.replace(email, placeholder)
        mapping[placeholder] = email

    # Telefonnummern
    phones = re.findall(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b', text)
    for i, phone in enumerate(phones):
        placeholder = f"[PHONE_{i}]"
        text = text.replace(phone, placeholder)
        mapping[placeholder] = phone

    # Namen (OPTIONAL: Pattern-basiert)
    # Das ist kompliziert, meist nur bei Kontext

    return text, mapping

# Nutze es
customer_email = """
Name: John Smith
Email: [email protected]
Phone: 555-123-4567

Issue: Billing problem with order #12345
"""

anonymized, mapping = anonymize_pii(customer_email)

# Send to Claude
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    messages=[{
        "role": "user",
        "content": f"Analyze this support request:\n{anonymized}"
    }]
)

# Get result, de-anonymize if needed
result = response.content[0].text
# (result ist anonymisiert geblieben, das ist OK)

# Log für Audit
audit_log = {
    "timestamp": datetime.now(),
    "user_id": "user123",
    "data_hash": hash(customer_email),  # Hash, nicht echte Daten
    "request_type": "support_classification"
}

save_audit_log(audit_log)

Praktische Beispiele

Beispiel 1: Email-Processing Pipeline

Gmail Webhook (neue Email)
  ↓
[n8n] Extract Email Fields
  ↓
[Claude Code] Analyze Intent & Extract Action Items
  ↓
[n8n] Router:
  - If urgent: Send Slack Alert
  - If contains tracking#: Create Zendesk Ticket
  - If feedback: Post to Slack #feedback
  ↓
[n8n] Reply to Customer

Beispiel 2: Content Pipeline

Notion Database (neue Article)
  ↓
[n8n] Extract Article Content
  ↓
[Claude Code] Generate:
  - SEO Keywords
  - Social Media Captions (EN + DE)
  - LinkedIn Post
  - Newsletter Snippet
  ↓
[n8n] Publish to:
  - Medium
  - LinkedIn
  - Twitter
  - Newsletter Service
  ↓
[n8n] Log & Track Performance

Beispiel 3: Monitoring & Alerting

Prometheus/Grafana (Metrics)
  ↓
[n8n] Collect Last 1h Metrics
  ↓
[Claude Code] Analyze:
  - Are there anomalies?
  - What could be the cause?
  - Should we alert?
  ↓
[n8n] If Alert Needed:
  - Send to PagerDuty
  - Message on-call engineer
  - Create incident ticket
  ↓
[n8n] Log Analysis for Later Review

Performance-Tipps

Batching

Statt jeden Email einzeln zu Claude zu senden, batch 10 Emails:

// n8n Code Node
const emails = $items;  // Array von 10 Emails

const batch_text = emails.map(e =>
  `---\nFrom: ${e.from}\nSubject: ${e.subject}\n${e.body}`
).join('\n');

// Send entire batch to Claude once
// = 10x schneller, 1/10 der Cost

Caching

Wenn ähnliche Anfragen kommen, nutze Cache:

import hashlib
from functools import lru_cache

@lru_cache(maxsize=1000)
def classify_email_cached(email_hash: str, category_schema: str) -> str:
    """
    Cache based on email content hash + schema
    """
    # ... call Claude ...
    return result

# Nutze es
email = "..."
email_hash = hashlib.md5(email.encode()).hexdigest()
result = classify_email_cached(email_hash, SCHEMA_V1)
# Zweiter Call mit gleicher Email = sofort, aus Cache!

Checkliste: Claude Code + n8n Setup

  • Claude Code Server läuft (auf localhost:3000 oder gehostet)
  • n8n kann Claude Code erreichen (Network-Test)
  • API Keys konfiguriert (ANTHROPIC_API_KEY in Environment)
  • n8n Webhooks sind eingerichtet
  • Workflows sind getestet (mit Test-Data)
  • Fehlerhandling ist implementiert
  • Logging funktioniert (für Debugging)
  • DSGVO Compliance prüfungen bestanden
  • Performance ist OK (< 5s Response Time)
  • Monitoring läuft (Uptime, Error Rates)

Sources: