> ## Documentation Index
> Fetch the complete documentation index at: https://docs.localmind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Nodes

> Erstellen Sie eigene Nodes für Automate - Erweitern Sie die Funktionalität mit benutzerdefinierten Nodes

Custom Nodes sind selbst entwickelte Erweiterungen für Automate. Sie erstellen einen Custom Node, wenn die Standard-Node-Bibliothek nicht ausreicht — typischerweise in drei Fällen:

* **Spezifische API-Integration:** Sie müssen sich mit einer internen API oder einem spezialisierten System verbinden, für das es keinen Standard-Node gibt.
* **Komplexe Daten-Transformation:** Sie benötigen Transformationen, die über Set-, Filter- und Code-Nodes hinausgehen.
* **Wiederverwendbare Geschäftslogik:** Bestimmte Geschäftsregeln werden in vielen Workflows verwendet und sollen als ein Node gekapselt sein.

Automate basiert auf n8n — Custom Nodes folgen deshalb dem n8n-Node-Format. Diese Seite zeigt das Setup und ein vollständiges Localmind-Beispiel; die vollständige Referenz zu Property-Typen, UI-Elementen und Node-Verhalten finden Sie in der [offiziellen n8n-Dokumentation](https://docs.n8n.io/integrations/creating-nodes/).

## Aufbau eines Nodes

Jeder Node implementiert das `INodeType`-Interface: `description` definiert Anzeigename, Inputs/Outputs, Credentials und die konfigurierbaren Properties; `execute` enthält die Logik.

```typescript Node-Struktur theme={null}
interface INodeType {
  description: INodeTypeDescription;
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
  methods?: INodeTypeDescriptionMethods;
}
```

Es gibt drei Node-Typen:

| Typ              | Aufgabe                                                                        | Beispiele                                         | Kern-Methode |
| ---------------- | ------------------------------------------------------------------------------ | ------------------------------------------------- | ------------ |
| **Regular Node** | Führt Operationen aus und gibt Daten weiter, wird von anderen Nodes aufgerufen | Daten-Transformation, API-Calls, Berechnungen     | `execute()`  |
| **Trigger Node** | Startet Workflows automatisch basierend auf Events oder Zeitplänen             | Webhook-Trigger, Schedule-Trigger, Event-Listener | `trigger()`  |
| **Webhook Node** | Empfängt HTTP-Requests und kann Antworten senden                               | REST-API-Endpoints, Webhook-Listener              | `webhook()`  |

Die Code-Skelette für Trigger- und Webhook-Nodes stehen in der [n8n-Dokumentation](https://docs.n8n.io/integrations/creating-nodes/) — das Beispiel unten zeigt einen Regular Node.

## Entwicklungsumgebung einrichten

Voraussetzungen: Node.js 18+, TypeScript (`npm install -g typescript`), Git und ein Code-Editor (VS Code empfohlen).

<Steps>
  <Step title="Projekt-Verzeichnis erstellen">
    ```bash theme={null}
    mkdir localmind-custom-node
    cd localmind-custom-node
    ```
  </Step>

  <Step title="package.json anlegen">
    Initialisieren Sie mit `npm init -y` und bearbeiten Sie die `package.json`. Der `n8n`-Block registriert Ihre Nodes:

    ```json package.json theme={null}
    {
      "name": "localmind-custom-node",
      "version": "1.0.0",
      "description": "Custom Nodes für Localmind Automate",
      "main": "index.js",
      "scripts": {
        "build": "tsc",
        "dev": "tsc --watch"
      },
      "keywords": ["n8n", "n8n-node", "localmind"],
      "author": "Localmind",
      "license": "MIT",
      "n8n": {
        "n8nNodesApiVersion": 1,
        "nodes": [
          {
            "node": "LocalmindAgent",
            "sourcePath": "nodes/LocalmindAgent/LocalmindAgent.node.ts"
          }
        ]
      },
      "dependencies": {
        "n8n-workflow": "^1.0.0"
      },
      "devDependencies": {
        "@types/node": "^20.0.0",
        "typescript": "^5.0.0"
      }
    }
    ```
  </Step>

  <Step title="TypeScript konfigurieren">
    ```json tsconfig.json theme={null}
    {
      "compilerOptions": {
        "module": "commonjs",
        "target": "ES2020",
        "lib": ["ES2020"],
        "declaration": true,
        "outDir": "./dist",
        "rootDir": "./",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "resolveJsonModule": true
      },
      "include": ["nodes/**/*"],
      "exclude": ["node_modules", "dist"]
    }
    ```
  </Step>

  <Step title="Abhängigkeiten installieren">
    ```bash theme={null}
    npm install
    ```
  </Step>
</Steps>

## Beispiel: Localmind Agent Node

Ein vollständiger Custom Node, der Localmind-Agenten über den OpenAI-kompatiblen `/v1`-Endpoint aufruft (`model` trägt die Agent-UUID):

```typescript nodes/LocalmindAgent/LocalmindAgent.node.ts theme={null}
import {
  IExecuteFunctions,
  INodeExecutionData,
  INodeType,
  INodeTypeDescription,
  NodePropertyTypes,
} from 'n8n-workflow';

export class LocalmindAgent implements INodeType {
  description: INodeTypeDescription = {
    displayName: 'Localmind Agent',
    name: 'localmindAgent',
    icon: 'file:localmind.svg',
    group: ['transform'],
    version: 1,
    subtitle: '={{$parameter["operation"]}}',
    description: 'Ruft einen Localmind-Agenten auf',
    defaults: {
      name: 'Localmind Agent',
    },
    inputs: ['main'],
    outputs: ['main'],
    credentials: [
      {
        name: 'localmindApi',
        required: true,
      },
    ],
    properties: [
      {
        displayName: 'Agent ID',
        name: 'agentId',
        type: 'string',
        required: true,
        default: '',
        description: 'Die ID des Localmind-Agenten',
      },
      {
        displayName: 'Input',
        name: 'input',
        type: 'string',
        required: true,
        default: '',
        description: 'Der Input-Text für den Agenten',
      },
      {
        displayName: 'Temperature',
        name: 'temperature',
        type: 'number',
        typeOptions: {
          minValue: 0,
          maxValue: 2,
          numberStepSize: 0.1,
        },
        default: 0.7,
        description: 'Die Temperature für die Agent-Antwort',
      },
      {
        displayName: 'Max Tokens',
        name: 'maxTokens',
        type: 'number',
        typeOptions: {
          minValue: 1,
          maxValue: 4000,
        },
        default: 500,
        description: 'Maximale Anzahl von Tokens in der Antwort',
      },
    ],
  };

  async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
    const items = this.getInputData();
    const returnData: INodeExecutionData[] = [];

    for (let i = 0; i < items.length; i++) {
      const agentId = this.getNodeParameter('agentId', i) as string;
      const input = this.getNodeParameter('input', i) as string;
      const temperature = this.getNodeParameter('temperature', i) as number;
      const maxTokens = this.getNodeParameter('maxTokens', i) as number;

      const credentials = await this.getCredentials('localmindApi');
      const apiKey = credentials.apiKey as string;

      // API-Call zu Localmind (OpenAI-kompatibler /v1-Endpoint, model = agent_uuid)
      const response = await this.helpers.httpRequest({
        method: 'POST',
        url: `https://<deine-instanz>-api.localmind.ai/v1/chat/completions`,
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json',
        },
        body: {
          model: agentId,
          messages: [{ role: 'user', content: input }],
          temperature,
          max_tokens: maxTokens,
        },
      });

      returnData.push({
        json: {
          agentId,
          input,
          response: response.choices[0].message.content,
          totalTokens: response.usage.total_tokens,
        },
      });
    }

    return [returnData];
  }
}
```

Das Beispiel zeigt zugleich die wichtigsten Bausteine der Datenverarbeitung: `getInputData()` liest die Input-Items, `getNodeParameter()` liest die Node-Konfiguration, `returnData.push({ json: ... })` erzeugt den Output. Für Fehlerbehandlung pro Item prüfen Sie `this.continueOnFail()` — ist die Option aktiv, geben Sie den Fehler als Item weiter statt die Execution abzubrechen (Details: [n8n-Dokumentation](https://docs.n8n.io/integrations/creating-nodes/)).

### Credentials definieren

Für die API-Authentifizierung definieren Sie einen Credential-Typ. Als API-Key verwenden Sie einen **persönlichen User-API-Key** (`sk-…`), den Sie unter **Benutzereinstellungen → API-Schlüssel** erstellen — optional auf einzelne Spaces gescoped (siehe [Persönliche API-Schlüssel](/navigation/Persönliche-API-Schlüssel)):

```typescript credentials/localmindApi.credentials.ts theme={null}
import {
  ICredentialType,
  INodeProperties,
} from 'n8n-workflow';

export class LocalmindApi implements ICredentialType {
  name = 'localmindApi';
  displayName = 'Localmind API';
  properties: INodeProperties[] = [
    {
      displayName: 'API Key',
      name: 'apiKey',
      type: 'string',
      typeOptions: {
        password: true,
      },
      default: '',
      required: true,
    },
    {
      displayName: 'Base URL',
      name: 'baseUrl',
      type: 'string',
      default: 'https://<deine-instanz>-api.localmind.ai/v1',
      required: true,
    },
  ];
}
```

### Properties

Properties sind die konfigurierbaren Parameter Ihres Nodes. Neben `string` und `number` (siehe Beispiel oben) gibt es unter anderem `options` für Dropdown-Auswahlen und `collection` für Key-Value-Sammlungen; gesteuert wird das Verhalten über Felder wie `required`, `default`, `placeholder` und `typeOptions` (etwa `minValue`, `maxValue`, `numberStepSize`). Die vollständige Liste aller Property-Typen dokumentiert die [n8n-Referenz](https://docs.n8n.io/integrations/creating-nodes/).

<Note>
  Einen direkten SQL-/Datenbank-Zugriff auf Localmind gibt es nicht. Daten in Spaces erreichen Sie ausschließlich über die [Localmind API](/api-reference/introduction) — zum Beispiel über die Dokument- und Such-Endpoints (siehe [Dokumente und Suche](/api-reference/Dokumente-und-Suche)).
</Note>

## Testen

Kompilieren Sie den Node mit `npm run build` und testen Sie ihn lokal im Automate Dev-Modus. Ergänzen Sie Unit Tests für die Node-Logik (z.B. `test/LocalmindAgent.test.ts` mit einem Test-Framework Ihrer Wahl) und Integration Tests in echten Workflows: Test-Workflow erstellen, mit Test-Daten ausführen, Outputs überprüfen. Wie Sie Nodes und Workflows systematisch testen, steht unter [Testing](/automate/testing).

## Deployment

1. **Build erstellen:** `npm run build` kompiliert TypeScript zu JavaScript.
2. **Package erstellen:** `npm pack` erzeugt eine installierbare `.tgz`-Datei.
3. **Node installieren:** im Automate-Verzeichnis `npm install /path/to/localmind-custom-node-1.0.0.tgz` ausführen.

Für die Verteilung im Team haben Sie mehrere Optionen: eine private npm Registry, Installation direkt aus einem Git-Repository, lokale Installation für Entwicklung und Testing oder das Bündeln in ein Docker-Image für Container-Deployments.

## Best Practices

* **Dokumentation:** jeden Property und jede Funktion klar beschreiben (`description`-Felder pflegen).
* **Error Handling:** alle Fehlerfälle abfangen, `continueOnFail()` unterstützen.
* **Performance:** unnötige API-Calls vermeiden.
* **Wiederverwendbarkeit:** Nodes so designen, dass sie in verschiedenen Kontexten funktionieren.
* **Testing:** Unit- und Integration-Tests schreiben.
* **Versionierung:** semantische Versionierung verwenden.

## Häufige Probleme

| Problem                                | Lösung                                                                                                                                      |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Node erscheint nicht in der Node-Liste | `package.json`-Konfiguration (`n8n`-Block) prüfen, sicherstellen dass der Node kompiliert wurde, Automate nach der Installation neu starten |
| TypeScript-Kompilierung schlägt fehl   | `tsconfig.json` prüfen, alle Dependencies installieren, Type-Definitionen überprüfen                                                        |
| Credentials werden nicht geladen       | Credential-Definition prüfen, gespeicherte Credentials kontrollieren, Credential-Zugriff im Node testen                                     |

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="n8n Dokumentation" icon="book" href="https://docs.n8n.io/integrations/creating-nodes/">
    Offizielle Referenz für Custom Nodes: Property-Typen, Trigger-/Webhook-Skelette, UI-Elemente.
  </Card>

  <Card title="Localmind API" icon="code" href="/api-reference/introduction">
    Endpoint-Referenz und Code-Beispiele für Integrationen.
  </Card>
</CardGroup>

Bei Fragen zur Entwicklung von Custom Nodes unterstützt Sie unser Entwickler-Team unter [dev@localmind.ai](mailto:dev@localmind.ai).
