diff --git a/paperless_ollama.json b/paperless_ollama.json
new file mode 100644
index 0000000..1525949
--- /dev/null
+++ b/paperless_ollama.json
@@ -0,0 +1,260 @@
+{
+ "updatedAt": "2026-10-01T11:55:03.918Z",
+ "createdAt": "2026-10-01T08:16:25.450Z",
+ "id": "NljcXxbg9UqJVBEW",
+ "name": "paperless_ollama",
+ "active": true,
+ "isArchived": false,
+ "nodes": [
+ {
+ "parameters": {
+ "workflowInputs": {
+ "values": [
+ {
+ "name": "correspondents",
+ "type": "any"
+ },
+ {
+ "name": "tags",
+ "type": "any"
+ },
+ {
+ "name": "documents",
+ "type": "any"
+ },
+ {
+ "name": "content",
+ "type": "any"
+ }
+ ]
+ }
+ },
+ "type": "n8n-nodes-base.executeWorkflowTrigger",
+ "typeVersion": 1.1,
+ "position": [
+ -256,
+ -368
+ ],
+ "id": "4606e8a4-69c3-4ee1-b54e-a826590aa12e",
+ "name": "Input"
+ },
+ {
+ "parameters": {
+ "jsCode": "const raw = $json.content || $json.text || \"\";\n\n// 1. Markdown entfernen & zuschneiden\nlet cleaned = raw.replace(/```json|```/g, '').trim();\n\n// 2. JSON-Bereich isolieren\nconst firstBrace = cleaned.indexOf('{');\nconst firstBracket = cleaned.indexOf('[');\nlet start = -1;\n\nif (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {\n start = firstBrace;\n} else if (firstBracket !== -1) {\n start = firstBracket;\n}\n\nif (start !== -1) {\n cleaned = cleaned.substring(start);\n}\n\n// 3. Parsen\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (e) {\n // Notfall-Reparatur, falls schließende Klammer fehlte\n parsed = JSON.parse(cleaned + (cleaned.startsWith('[') ? ']' : '}'));\n}\n\n// 4. n8n-konformes Format zurückgeben\nif (Array.isArray(parsed)) {\n // Array -> Mehrere n8n Items\n return parsed.map(entry => ({\n json: typeof entry === 'object' && entry !== null ? entry : { value: entry }\n }));\n}\n\nif (typeof parsed === 'object' && parsed !== null) {\n // Normales Objekt -> Ein n8n Item\n return [{ json: parsed }];\n}\n\n// Primitiver Wert (String, Zahl etc.)\nreturn [{ json: { value: parsed } }];"
+ },
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 352,
+ -352
+ ],
+ "id": "937e6c25-05c3-4e95-b8bf-76c310f80207",
+ "name": "Code in JavaScript",
+ "executeOnce": true
+ },
+ {
+ "parameters": {
+ "modelId": {
+ "__rl": true,
+ "value": "ministral-3:3b",
+ "mode": "list",
+ "cachedResultName": "ministral-3:3b"
+ },
+ "messages": {
+ "values": [
+ {
+ "content": "=\n{{ (Array.isArray($json.correspondents) ?$json.correspondents : []).map(c => `[${c.paperless_id ?? c.id}] ${c.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.tags) ?$json.tags : []).map(t => `[${t.paperless_id ?? t.id}] ${t.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.documents) ?$json.documents : []).map(d => `[${d.paperless_id ?? d.id}] ${d.name}`).join(', ') }}\n\n\n\n{{ ($json.content || '').substring(0, 1200) }}\n"
+ }
+ ]
+ },
+ "options": {
+ "system": "Klassifiziere den Dokumentenauszug anhand der bereitgestellten Listen.\n\nRegel für alle Entitäten:\n- Verwende die ID aus der jeweiligen Liste.\n- Falls kein passender Eintrag existiert: Setze die ID zwingend auf null und trage den neu erkannten Namen ein.\n- Tags dürfen mehrere Treffer oder ein leeres Array [] sein.\n\nAntworte ausschließlich mit reinem JSON (keine Markdown-Backticks, beginne direkt mit {):\n{\n \"Title\": \"Kurzer aussagekräftiger Dokumenttitel\",\n \"Korrespondent-ID\": number | null,\n \"Korrespondent\": \"string\",\n \"Dokumententyp-ID\": number | null,\n \"Dokumententyp\": \"string\",\n \"Tags\": [\n {\n \"Tag-ID\": number | null,\n \"Name\": \"string\"\n }\n ]\n}",
+ "temperature": 0,
+ "num_predict": 150,
+ "keep_alive": "5m",
+ "format": "json"
+ }
+ },
+ "type": "@n8n/n8n-nodes-langchain.ollama",
+ "typeVersion": 1,
+ "position": [
+ -32,
+ -368
+ ],
+ "id": "b7823307-d92a-4ec4-89fe-fdb0b0e7141c",
+ "name": "Mistral",
+ "executeOnce": true,
+ "credentials": {
+ "ollamaApi": {
+ "id": "fgaZliEtIoej3jtn",
+ "name": "Ollama account"
+ }
+ }
+ }
+ ],
+ "connections": {
+ "Input": {
+ "main": [
+ [
+ {
+ "node": "Mistral",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Mistral": {
+ "main": [
+ [
+ {
+ "node": "Code in JavaScript",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ }
+ },
+ "settings": {
+ "executionOrder": "v1",
+ "binaryMode": "separate"
+ },
+ "staticData": null,
+ "meta": null,
+ "pinData": {},
+ "versionId": "4bec14cf-b613-45e5-918b-73f02b6384d5",
+ "activeVersionId": "4bec14cf-b613-45e5-918b-73f02b6384d5",
+ "triggerCount": 0,
+ "shared": [
+ {
+ "updatedAt": "2026-10-01T08:16:25.453Z",
+ "createdAt": "2026-10-01T08:16:25.453Z",
+ "role": "workflow:owner",
+ "workflowId": "NljcXxbg9UqJVBEW",
+ "projectId": "cSAaWNJydnksD5EB"
+ }
+ ],
+ "activeVersion": {
+ "updatedAt": "2026-10-01T11:55:06.000Z",
+ "createdAt": "2026-10-01T11:54:59.108Z",
+ "versionId": "4bec14cf-b613-45e5-918b-73f02b6384d5",
+ "workflowId": "NljcXxbg9UqJVBEW",
+ "nodes": [
+ {
+ "parameters": {
+ "workflowInputs": {
+ "values": [
+ {
+ "name": "correspondents",
+ "type": "any"
+ },
+ {
+ "name": "tags",
+ "type": "any"
+ },
+ {
+ "name": "documents",
+ "type": "any"
+ },
+ {
+ "name": "content",
+ "type": "any"
+ }
+ ]
+ }
+ },
+ "type": "n8n-nodes-base.executeWorkflowTrigger",
+ "typeVersion": 1.1,
+ "position": [
+ -256,
+ -368
+ ],
+ "id": "4606e8a4-69c3-4ee1-b54e-a826590aa12e",
+ "name": "Input"
+ },
+ {
+ "parameters": {
+ "jsCode": "const raw = $json.content || $json.text || \"\";\n\n// 1. Markdown entfernen & zuschneiden\nlet cleaned = raw.replace(/```json|```/g, '').trim();\n\n// 2. JSON-Bereich isolieren\nconst firstBrace = cleaned.indexOf('{');\nconst firstBracket = cleaned.indexOf('[');\nlet start = -1;\n\nif (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {\n start = firstBrace;\n} else if (firstBracket !== -1) {\n start = firstBracket;\n}\n\nif (start !== -1) {\n cleaned = cleaned.substring(start);\n}\n\n// 3. Parsen\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (e) {\n // Notfall-Reparatur, falls schließende Klammer fehlte\n parsed = JSON.parse(cleaned + (cleaned.startsWith('[') ? ']' : '}'));\n}\n\n// 4. n8n-konformes Format zurückgeben\nif (Array.isArray(parsed)) {\n // Array -> Mehrere n8n Items\n return parsed.map(entry => ({\n json: typeof entry === 'object' && entry !== null ? entry : { value: entry }\n }));\n}\n\nif (typeof parsed === 'object' && parsed !== null) {\n // Normales Objekt -> Ein n8n Item\n return [{ json: parsed }];\n}\n\n// Primitiver Wert (String, Zahl etc.)\nreturn [{ json: { value: parsed } }];"
+ },
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 352,
+ -352
+ ],
+ "id": "937e6c25-05c3-4e95-b8bf-76c310f80207",
+ "name": "Code in JavaScript",
+ "executeOnce": true
+ },
+ {
+ "parameters": {
+ "modelId": {
+ "__rl": true,
+ "value": "ministral-3:3b",
+ "mode": "list",
+ "cachedResultName": "ministral-3:3b"
+ },
+ "messages": {
+ "values": [
+ {
+ "content": "=\n{{ (Array.isArray($json.correspondents) ?$json.correspondents : []).map(c => `[${c.paperless_id ?? c.id}] ${c.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.tags) ?$json.tags : []).map(t => `[${t.paperless_id ?? t.id}] ${t.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.documents) ?$json.documents : []).map(d => `[${d.paperless_id ?? d.id}] ${d.name}`).join(', ') }}\n\n\n\n{{ ($json.content || '').substring(0, 1200) }}\n"
+ }
+ ]
+ },
+ "options": {
+ "system": "Klassifiziere den Dokumentenauszug anhand der bereitgestellten Listen.\n\nRegel für alle Entitäten:\n- Verwende die ID aus der jeweiligen Liste.\n- Falls kein passender Eintrag existiert: Setze die ID zwingend auf null und trage den neu erkannten Namen ein.\n- Tags dürfen mehrere Treffer oder ein leeres Array [] sein.\n\nAntworte ausschließlich mit reinem JSON (keine Markdown-Backticks, beginne direkt mit {):\n{\n \"Title\": \"Kurzer aussagekräftiger Dokumenttitel\",\n \"Korrespondent-ID\": number | null,\n \"Korrespondent\": \"string\",\n \"Dokumententyp-ID\": number | null,\n \"Dokumententyp\": \"string\",\n \"Tags\": [\n {\n \"Tag-ID\": number | null,\n \"Name\": \"string\"\n }\n ]\n}",
+ "temperature": 0,
+ "num_predict": 150,
+ "keep_alive": "5m",
+ "format": "json"
+ }
+ },
+ "type": "@n8n/n8n-nodes-langchain.ollama",
+ "typeVersion": 1,
+ "position": [
+ -32,
+ -368
+ ],
+ "id": "b7823307-d92a-4ec4-89fe-fdb0b0e7141c",
+ "name": "Mistral",
+ "executeOnce": true,
+ "credentials": {
+ "ollamaApi": {
+ "id": "fgaZliEtIoej3jtn",
+ "name": "Ollama account"
+ }
+ }
+ }
+ ],
+ "connections": {
+ "Input": {
+ "main": [
+ [
+ {
+ "node": "Mistral",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Mistral": {
+ "main": [
+ [
+ {
+ "node": "Code in JavaScript",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ }
+ },
+ "authors": "Prasanna Ranjan",
+ "name": "Version 4bec14cf",
+ "description": "",
+ "autosaved": false
+ },
+ "tags": []
+}
\ No newline at end of file