From a7732a655a6f70a160c08ac9fb6c260bd262c282 Mon Sep 17 00:00:00 2001 From: beo3000 Date: Fri, 15 May 2026 09:17:28 +0200 Subject: [PATCH] paperless mcp --- .claude/settings.json | 17 +- .../conv-1778770805666-gv3mpxj5m.meta.json | 2 +- .../conv-1778827726105-2m4ikxrxg.meta.json | 23 ++ .obsidian/plugins/claudian/data.json | 2 +- .obsidian/workspace.json | 63 ++--- .../Nachtrag Pachtvertrag Viedenz.docx | Bin 12804 -> 20509 bytes .../~$chtrag Pachtvertrag Viedenz.docx | Bin 162 -> 0 bytes 03 Bereiche/Heimnetz/Server/Paperless.md | 224 +++++++++++------- CLAUDE.md | 23 +- scripts/paperless-mcp/.env.example | 4 + scripts/paperless-mcp/.gitignore | 1 + scripts/paperless-mcp/docker-compose.yml | 23 ++ 12 files changed, 237 insertions(+), 145 deletions(-) create mode 100644 .claudian/sessions/conv-1778827726105-2m4ikxrxg.meta.json delete mode 100644 02 Projekte/Pachtanpassung Viedenz 2026/~$chtrag Pachtvertrag Viedenz.docx create mode 100644 scripts/paperless-mcp/.env.example create mode 100644 scripts/paperless-mcp/.gitignore create mode 100644 scripts/paperless-mcp/docker-compose.yml diff --git a/.claude/settings.json b/.claude/settings.json index a8caf71..6ba4cf1 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -198,7 +198,18 @@ "Bash(pandoc -f markdown -t docx \"_vollmacht_print.md\" -o \"Vollmacht Vera Pachtvertrag Viedenz.docx\")", "Bash(rm \"_vollmacht_print.md\")", "Bash(pandoc -f markdown -t docx \"_nachtrag_print.md\" -o \"Nachtrag Pachtvertrag Viedenz.docx\")", - "Bash(rm \"_nachtrag_print.md\")" + "Bash(rm \"_nachtrag_print.md\")", + "Read(//c/Users/d-chrka/**)", + "Edit(D:\\\\projects\\\\chrka\\\\brain\\\\.claude\\\\settings.json)", + "Bash(curl -sS -o /dev/null -w \"MCP root: HTTP %{http_code}\\\\n\" http://localhost:5000/)", + "Bash(curl -sS -o /dev/null -w \"MCP /mcp: HTTP %{http_code}\\\\n\" http://localhost:5000/mcp)", + "Bash(curl -sS -o /dev/null -w \"MCP /health: HTTP %{http_code}\\\\n\" http://localhost:5000/health)", + "Bash(curl -sS -X POST http://localhost:5000/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' -w '\\\\n---HTTP %{http_code}---\\\\n')", + "Bash(curl -sS -N -X POST http://localhost:5000/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -H 'Mcp-Session-Id: test-session' -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}')", + "Bash(curl -sS -i -X POST http://localhost:5000/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}')", + "Bash(curl -sS -D - -o /dev/null -X POST http://localhost:5000/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}')", + "Bash(awk '{print $2}')", + "Bash(SID=$\\(curl -sS -D - -o /dev/null -X POST http://localhost:5000/mcp \\\\\n -H \"Content-Type: application/json\" \\\\\n -H \"Accept: application/json, text/event-stream\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' | grep -i \"mcp-session-id\" | awk '{print $2}' | tr -d '\\\\r\\\\n'\\)\ncurl -sS -X POST http://localhost:5000/mcp \\\\\n -H \"Content-Type: application/json\" -H \"Accept: application/json, text/event-stream\" -H \"Mcp-Session-Id: $SID\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}' -o /dev/null\necho \"=== Call: paperless_documents_get id=3323 ===\"\ncurl -sS -X POST http://localhost:5000/mcp \\\\\n -H \"Content-Type: application/json\" -H \"Accept: application/json, text/event-stream\" -H \"Mcp-Session-Id: $SID\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"paperless_documents_get\",\"arguments\":{\"id\":3323}}}' | head -c 600)" ] }, "ms365-calendar": { @@ -207,5 +218,9 @@ "-c", "TOKEN=$(curl -s -X POST 'https://login.microsoftonline.com/94cf90d7-e9ff-49a1-bc3b-a5b94d3cc8ca/oauth2/v2.0/token' -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=client_credentials&client_id=93f9f15c-b566-4ca1-9145-c23f87c7f5c7&client_secret=Gpm8Q~5QKks3jYrbIkTM54AHmnZPC3a8RDc1Xam.&scope=https://graph.microsoft.com/.default' | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('access_token',''))\") && MS365_MCP_OAUTH_TOKEN=$TOKEN npx -y @softeria/ms-365-mcp-server --preset calendar --read-only" ] + }, + "paperless": { + "type": "http", + "url": "http://localhost:5000/mcp" } } diff --git a/.claudian/sessions/conv-1778770805666-gv3mpxj5m.meta.json b/.claudian/sessions/conv-1778770805666-gv3mpxj5m.meta.json index 67bbae1..b928096 100644 --- a/.claudian/sessions/conv-1778770805666-gv3mpxj5m.meta.json +++ b/.claudian/sessions/conv-1778770805666-gv3mpxj5m.meta.json @@ -4,7 +4,7 @@ "title": "Dokumentiere pachtvertrag Viedenz", "titleGenerationStatus": "success", "createdAt": 1778770805667, - "updatedAt": 1778780175097, + "updatedAt": 1778827603536, "lastResponseAt": 1778780175097, "sessionId": "2e51702d-cc9f-4067-8ae7-d6d8ade4c972", "providerState": { diff --git a/.claudian/sessions/conv-1778827726105-2m4ikxrxg.meta.json b/.claudian/sessions/conv-1778827726105-2m4ikxrxg.meta.json new file mode 100644 index 0000000..1a9e0df --- /dev/null +++ b/.claudian/sessions/conv-1778827726105-2m4ikxrxg.meta.json @@ -0,0 +1,23 @@ +{ + "id": "conv-1778827726105-2m4ikxrxg", + "providerId": "claude", + "title": "Optimize Paperless MCP integration", + "titleGenerationStatus": "success", + "createdAt": 1778827726105, + "updatedAt": 1778829160912, + "lastResponseAt": 1778829160911, + "sessionId": "81a5f2af-0645-4bdc-a7ca-8444d8ef0b5e", + "providerState": { + "providerSessionId": "81a5f2af-0645-4bdc-a7ca-8444d8ef0b5e" + }, + "usage": { + "model": "opus", + "inputTokens": 1, + "cacheCreationInputTokens": 1378, + "cacheReadInputTokens": 113684, + "contextWindow": 200000, + "contextTokens": 115063, + "percentage": 58, + "contextWindowIsAuthoritative": true + } +} \ No newline at end of file diff --git a/.obsidian/plugins/claudian/data.json b/.obsidian/plugins/claudian/data.json index 52a5cbc..2c1c127 100644 --- a/.obsidian/plugins/claudian/data.json +++ b/.obsidian/plugins/claudian/data.json @@ -3,7 +3,7 @@ "openTabs": [ { "tabId": "tab-1776326979311-d1ltpj7", - "conversationId": "conv-1778770805666-gv3mpxj5m" + "conversationId": "conv-1778827726105-2m4ikxrxg" } ], "activeTabId": "tab-1776326979311-d1ltpj7" diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 4e2c606..c26d867 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -4,53 +4,20 @@ "type": "split", "children": [ { - "id": "abd6dd12c3a7a3c4", + "id": "d7ad139896e58563", "type": "tabs", "children": [ { - "id": "906e7d9288100579", + "id": "2c51a65fe9d6b31a", "type": "leaf", "state": { - "type": "markdown", - "state": { - "file": "00 Kontext/Personen/Hedwig Theile-Ochel.md", - "mode": "source", - "source": false - }, + "type": "empty", + "state": {}, "icon": "lucide-file", - "title": "Hedwig Theile-Ochel" - } - }, - { - "id": "a9ec1200215db86a", - "type": "leaf", - "state": { - "type": "markdown", - "state": { - "file": "00 Kontext/Personen/Stefan Theile-Ochel.md", - "mode": "source", - "source": false - }, - "icon": "lucide-file", - "title": "Stefan Theile-Ochel" - } - }, - { - "id": "eda038c515c8d69c", - "type": "leaf", - "state": { - "type": "markdown", - "state": { - "file": "02 Projekte/Pachtanpassung Viedenz 2026/Vollmacht Vera Pachtvertrag Viedenz.md", - "mode": "source", - "source": false - }, - "icon": "lucide-file", - "title": "Vollmacht Vera Pachtvertrag Viedenz" + "title": "Neuer Tab" } } - ], - "currentTab": 2 + ] } ], "direction": "vertical" @@ -228,21 +195,21 @@ }, "active": "1e4fd006b67464e8", "lastOpenFiles": [ + "CLAUDE.md.tmp.65564.1778829146795", + "03 Bereiche/Heimnetz/Server/Paperless.md.tmp.65564.1778828902314", + "02 Projekte/Pachtanpassung Viedenz 2026/~WRL3351.tmp", + "02 Projekte/Pachtanpassung Viedenz 2026/~WRD3340.tmp", + "02 Projekte/Pachtanpassung Viedenz 2026/~WRD3332.tmp", + "scripts/paperless-mcp/docker-compose.yml", + "scripts/paperless-mcp/docker-compose.yml.tmp.65564.1778828475762", + "scripts/paperless-mcp", + "02 Projekte/Pachtanpassung Viedenz 2026/Vollmacht Vera Pachtvertrag Viedenz.md", "02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.pdf", "02 Projekte/Pachtanpassung Viedenz 2026/~WRD1720.tmp", "02 Projekte/Pachtanpassung Viedenz 2026/Vollmacht Vera Pachtvertrag Viedenz.pdf", - "02 Projekte/Pachtanpassung Viedenz 2026/~WRL1427.tmp", - "02 Projekte/Pachtanpassung Viedenz 2026/~WRD1408.tmp", - "02 Projekte/Pachtanpassung Viedenz 2026/~$chtrag Pachtvertrag Viedenz.docx", - "02 Projekte/Pachtanpassung Viedenz 2026/~WRL0003.tmp", - "02 Projekte/Pachtanpassung Viedenz 2026/~WRD0002.tmp", - "02 Projekte/Pachtanpassung Viedenz 2026/~WRD0000.tmp", - "02 Projekte/Pachtanpassung Viedenz 2026/~$llmacht Vera Pachtvertrag Viedenz.docx", - "02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.docx", "02 Projekte/Pachtanpassung Viedenz 2026/_nachtrag_print.md", "02 Projekte/Pachtanpassung Viedenz 2026/_vollmacht_print.md", "00 Kontext/Personen/Stefan Theile-Ochel.md", - "02 Projekte/Pachtanpassung Viedenz 2026/Vollmacht Vera Pachtvertrag Viedenz.md", "00 Kontext/Personen/Anne Menne.md", "00 Kontext/Personen/Hedwig Theile-Ochel.md", "02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.md", diff --git a/02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.docx b/02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.docx index ad17f5e888eaf3df992fdd68f3bc37a1200ea9d7..c69a2a58e4b4307f323c9ed053e7875805c09357 100644 GIT binary patch literal 20509 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 literal 12804 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 O^G~{gN+wR4oB#k{kRe0> diff --git a/03 Bereiche/Heimnetz/Server/Paperless.md b/03 Bereiche/Heimnetz/Server/Paperless.md index d70f0cb..bd26f7e 100644 --- a/03 Bereiche/Heimnetz/Server/Paperless.md +++ b/03 Bereiche/Heimnetz/Server/Paperless.md @@ -1,6 +1,9 @@ --- tags: - - upnote-import + - server + - paperless + - dms + - heimnetz --- # Paperless-NGX @@ -22,7 +25,7 @@ Archivsystem. ### Config NPM ```yaml -   proxy_http_version 1.1; + proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; @@ -35,135 +38,194 @@ Archivsystem. add_header P3P 'CP=""'; # may not be required in all setups ``` -# Update +# MCP-Anbindung (Claude Code) -1. Version notierenaktuelle Version vermerken. Wird benötigt, falls ein Rollback erforderlich sein sollte -2. altes Backup löschen, in /volume1/docker$ +Damit Claude Code strukturiert (statt per `curl`) mit Paperless arbeiten kann, läuft ein **PaperlessMCP**-Container lokal auf der Windows-Workstation. Er übersetzt MCP-Tool-Calls in REST-Aufrufe gegen `paper.straso.com`. + +## Architektur + +``` +Claude Code ──MCP/HTTP──► PaperlessMCP (127.0.0.1:5000) ──REST/HTTPS──► Paperless-ngx (paper.straso.com) + (Windows) (Docker Desktop, Windows) (NAS, 10.40.10.131:8000) +``` + +Bewusst **nicht** in die NAS-Compose aufgenommen — Begründung siehe Abschnitt „Designentscheidungen". + +## Komponenten + +| Punkt | Wert | +|---|---| +| Repo | [barryw/PaperlessMCP](https://github.com/barryw/PaperlessMCP) (.NET, 43 Tools, Bulk-Ops) | +| Image | `ghcr.io/barryw/paperlessmcp:latest` | +| Stack-Datei | `scripts/paperless-mcp/docker-compose.yml` | +| Env-Datei | `scripts/paperless-mcp/.env` (gitignored, Template: `.env.example`) | +| Bind-Adresse | `127.0.0.1:5000` (lokal-only, kein LAN-Exposure) | +| MCP-Endpoint | `http://localhost:5000/mcp` | +| Claude-Config | `paperless` als HTTP-MCP in `.claude/settings.json` | +| Tool-Prefix in Claude | `mcp__paperless__*` | + +## Betrieb ```bash -cd /volume1/docker -rm -r paperless_backup/ +cd D:\projects\chrka\brain\scripts\paperless-mcp + +docker compose up -d # start +docker compose ps # status +docker compose logs -f # tail logs +docker compose pull && docker compose up -d # update +docker compose down # stop ``` -2. Anwendung stoppen in /volume1/docker/paperless$ +## Sicherheit -``` -cd paperless -sudo docker-compose down -``` +- **Token** liegt nur in `scripts/paperless-mcp/.env` (gitignored, identisch zum Token in `scripts/.env`) +- **Port-Binding** `127.0.0.1:5000` → kein Zugriff aus LAN/Internet, auch nicht versehentlich +- **Dry-Run default** in PaperlessMCP: destruktive Ops (Delete, Bulk-Edit) brauchen explizit `confirm=true` +- Tausche Token bei Bedarf in Paperless: Settings → Django Admin → Tokens, danach `.env` aktualisieren + `docker compose restart` -3. neues Backup erstellen, in /volume1/docker$ +## Designentscheidungen -``` -cd .. -sudo cp -r ./paperless ./paperless_backup -``` +- **Lokal statt NAS-Compose**, weil: + - MCP-Server hat sehr breite Schreibrechte → soll nicht im LAN exponiert sein + - Token muss nicht auf die NAS migriert werden, bleibt im Vault-Workspace + - NAS-Update-Routine bleibt schlank (siehe unten) + - Container läuft nur wenn gebraucht, kein 24/7-Idle +- **HTTP statt stdio**, weil PaperlessMCP nur HTTP unterstützt und Claude Code HTTP-MCPs nativ kann +- **Eigene `.env` statt `scripts/.env`**, weil PaperlessMCP andere Variablennamen erwartet (`PAPERLESS_BASE_URL`, `PAPERLESS_API_TOKEN`) -4. Images löschen, in /volume1/docker/paperless$ +## Troubleshooting -``` -cd paperless -sudo docker-compose rm -f -``` +| Symptom | Check | +|---|---| +| Claude findet `paperless` nicht | Container läuft? `docker compose ps`. Claude Code neu starten. | +| `Connection refused` auf :5000 | Docker Desktop läuft? Port-Binding stimmt? `netstat -an \| findstr 5000` | +| 401 von paper.straso.com | Token in `.env` korrekt? Token in Paperless noch gültig? | +| `mcpServers`-Key nicht gefunden | `paperless`-Eintrag in `.claude/settings.json` steht auf Root-Ebene; ggf. unter `mcpServers` schieben | +| Image-Tag broken | In `docker-compose.yml` auf konkrete Version pinnen, siehe [Releases](https://github.com/barryw/PaperlessMCP/releases) | -5. Images Updaten, in /volume1/docker/paperless$ +# Update -``` -sudo docker-compose pull -``` +Arbeitsverzeichnis auf der NAS: `/volume1/docker/paperless` -6. Anwendung starten +1. **Aktuelle Version notieren** — für Rollback im Fehlerfall. -``` -sudo docker-compose up -d -``` +2. **Altes Backup löschen:** + ```bash + cd /volume1/docker + rm -r paperless_backup/ + ``` -### DB-Server-Upgrade +3. **Anwendung stoppen:** + ```bash + cd /volume1/docker/paperless + sudo docker-compose down + ``` -nur den DB Container starten +4. **Neues Backup erstellen:** + ```bash + cd /volume1/docker + sudo cp -r ./paperless ./paperless_backup + ``` -``` +5. **Container entfernen:** + ```bash + cd /volume1/docker/paperless + sudo docker-compose rm -f + ``` + +6. **Images aktualisieren:** + ```bash + sudo docker-compose pull + ``` + +7. **Anwendung starten:** + ```bash + sudo docker-compose up -d + ``` + +## DB-Server-Upgrade + +Nur den DB-Container starten: + +```bash sudo docker-compose up -d db ``` -backup script erstellen +Backup-Script: -``` +```bash sudo docker exec -it paperless-db-1 pg_dumpall -U paperless > $HOME/upgrade_paperless_backup.sql ``` -….. +### Bekannte Stolperfallen -[Paperless broke after update | solariz.de - Tech & Thoughts](https://solariz.de/posts/25/paperless-broken-after-upgrade-postgress/#paperless-ngx-postgresql-14-or-later-is-required-error) +- **PostgreSQL 14+ Pflicht ab bestimmten Versionen:** [solariz.de — Paperless broken after upgrade](https://solariz.de/posts/25/paperless-broken-after-upgrade-postgress/#paperless-ngx-postgresql-14-or-later-is-required-error) +- **`password authentication failed for user "paperless"`** — Volumes zurücksetzen ([Issue #1552](https://github.com/jonaswinkler/paperless-ng/issues/1552)): + ```bash + docker-compose up -V --remove-orphans --force-recreate + ``` -außerdem mussten alle volumes einmal zurückgesetzt werden: [\[BUG\] password authentication failed for user "paperless" · Issue #1552 · jonaswinkler/paperless-ng](https://github.com/jonaswinkler/paperless-ng/issues/1552) - -``` -docker-compose up -V --remove-orphans --force-recreate -``` - -#
- -# Updateverlauf +## Updateverlauf - 2025-09-26: von 2.13.5 auf 2.18.4 -##
- # Archivierungsworkflow -### Dokumente, die aufbewahrt werden: +## Dokumente, die aufbewahrt werden -189er Etiketten für [ASNs](https://docs.paperless-ngx.com/advanced_usage/#archive-serial-number-assignment): +- 189er Etiketten für [ASNs](https://docs.paperless-ngx.com/advanced_usage/#archive-serial-number-assignment): [bueroshop24 — Avery Zweckform L4731REV](https://www.bueroshop24.de/5670-avery-zweckform-etiketten-l4731rev-25-wei%C3%9F-25-4-x-10-0-mm-345520?mkz=724) +- Tool zum Generieren von Barcodes: [tobiasmaier.info — ASN QR Code Label Generator](https://tobiasmaier.info/asn-qr-code-label-generator/) -[https://www.bueroshop24.de/5670-avery-zweckform-etiketten-l4731rev-25-wei%C3%9F-25-4-x-10-0-mm-345520?mkz=724](https://www.bueroshop24.de/5670-avery-zweckform-etiketten-l4731rev-25-wei%C3%9F-25-4-x-10-0-mm-345520?mkz=724) +## Empfohlener Workflow -Tools zum generieren von Barcodes: +[Paperless-ngx Docs — Recommended Workflow](https://docs.paperless-ngx.com/usage/#usage-recommended-workflow) -[https://tobiasmaier.info/asn-qr-code-label-generator/](https://tobiasmaier.info/asn-qr-code-label-generator/) - -### empfohlener Wokflow: - -[https://docs.paperless-ngx.com/usage/#usage-recommended-workflow](https://docs.paperless-ngx.com/usage/#usage-recommended-workflow) - -### ASN-Definition: +## ASN-Definition Zähler-Offset: -100189 = Christian +| Offset | Person | +|---|---| +| 100189 | Christian | +| 200189 | Vera | +| 300189 | Vicky | +| 400189 | Justus | +| 500189 | Hetti | -200189 = Vera - -300189 = Vicky - -400189 = Justus - -500189 = Hetti - -z.B.: ASN200000,TAG:Vera +Beispiel: `ASN200000, TAG:Vera` # Dokumente exportieren -VoraussetzungVolume für Export-Verzeichnis festlegen +**Voraussetzung:** Volume für Export-Verzeichnis festlegen. - ` ``` volumes: - /volume1/docker/paperless/data:/usr/src/paperless/data - /volume1/docker/paperless/media:/usr/src/paperless/media - /volume1/docker/paperless_export:/usr/src/paperless/export # https://paperless.readthedocs.io/en/latest/utilities.html#the-exporter - /volume1/homes/chk/Drive/Paperless-Input:/usr/src/paperless/consume ``` ` +```yaml +volumes: + - /volume1/docker/paperless/data:/usr/src/paperless/data + - /volume1/docker/paperless/media:/usr/src/paperless/media + - /volume1/docker/paperless_export:/usr/src/paperless/export # https://paperless.readthedocs.io/en/latest/utilities.html#the-exporter + - /volume1/homes/chk/Drive/Paperless-Input:/usr/src/paperless/consume +``` -manueller Export +Manueller Export: -` ``` sudo docker exec paperless-webserver-1 document_exporter ../export ``` ` +```bash +sudo docker exec paperless-webserver-1 document_exporter ../export +``` -Archiv erzeugen +Archiv erzeugen: -` ``` tar -czf paper_export.tgz ./paperless_export ``` ` +```bash +tar -czf paper_export.tgz ./paperless_export +``` -manueller Import +Manueller Import: -` ``` sudo docker exec paperless-webserver-1 document_importer ../export ``` ` +```bash +sudo docker exec paperless-webserver-1 document_importer ../export +``` -Quelle: [https://www.youtube.com/watch?v=F-NtIbxF6oc](https://www.youtube.com/watch?v=F-NtIbxF6oc) +Quelle: [YouTube — Paperless-ngx Export/Import](https://www.youtube.com/watch?v=F-NtIbxF6oc) # Backup NAS in Amazon Cloud -[https://s3.console.aws.amazon.com/s3/buckets/paperbackup?region=eu-west-1&tab=objects](https://s3.console.aws.amazon.com/s3/buckets/paperbackup?region=eu-west-1&tab=objects) - -Amazon Portal S3 → Buckets +- [S3 Bucket `paperbackup`](https://s3.console.aws.amazon.com/s3/buckets/paperbackup?region=eu-west-1&tab=objects) (Amazon Portal S3 → Buckets) diff --git a/CLAUDE.md b/CLAUDE.md index 5cbab0d..a35e23b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -37,27 +37,24 @@ Christian Kauer, IT-Leiter bei der KRAH Elektrotechnischen Fabrik GmbH & Co. KG, Wenn der Nutzer „Paperless", „mein Dokumentenarchiv", „mein Archiv", „meine Belege" o.ä. erwähnt, ist die Paperless-ngx-Instanz unter `https://paper.straso.com/` gemeint. -**Zugriff:** REST-API mit Token-Auth. Credentials in `scripts/.env`: -- `PAPERLESS_URL=https://paper.straso.com/` -- `PAPERLESS_TOKEN=...` +**Zugriff:** Primär über **MCP** (`mcp__paperless__*`-Tools). Container läuft lokal auf `http://localhost:5000/mcp`. Setup-Doku: [[03 Bereiche/Heimnetz/Server/Paperless.md|Paperless.md]]. -**Aufruf-Pattern (Bash + curl):** +**Wichtige Tools:** +- `paperless_documents_get` — Einzeldokument (inkl. OCR-`content`) +- `paperless_documents_list` / Search-Tools — Listen, Filter, Volltextsuche +- `paperless_correspondents_*`, `paperless_document_types_*`, `paperless_tags_*` — Metadaten +- `paperless_documents_update` / Bulk-Ops — Editieren (Dry-Run default, destruktive Ops brauchen `confirm=true`) + +**Fallback (nur wenn MCP-Container down):** REST mit Token-Auth aus `scripts/.env`: ```bash source scripts/.env curl -sS -H "Authorization: Token $PAPERLESS_TOKEN" "$PAPERLESS_URL/api/documents//" ``` -**Wichtige Endpoints:** -- `GET /api/documents//` — Einzeldokument (inkl. OCR-`content`) -- `GET /api/documents/?correspondent__id=&page_size=50&ordering=created` — Liste filtern -- `GET /api/documents/?query=` — Volltextsuche -- `GET /api/correspondents//`, `/api/document_types//`, `/api/tags//` — Metadaten auflösen -- `GET /api/documents//download/` — Originaldatei - **Hinweise:** -- JSON immer mit `encoding='utf-8'` lesen (Windows-Default cp1252 scheitert) - Bei Bezug auf Dokumente: ID, Titel und Datum nennen, in Notizen als `[[Paperless ]]` verlinken -- Token nicht in Notizen oder Chat ausgeben +- Token niemals in Notizen oder Chat ausgeben +- Bei Fallback auf curl: JSON immer mit `encoding='utf-8'` lesen (Windows-Default cp1252 scheitert) ## Session-Routinen diff --git a/scripts/paperless-mcp/.env.example b/scripts/paperless-mcp/.env.example new file mode 100644 index 0000000..7012b4e --- /dev/null +++ b/scripts/paperless-mcp/.env.example @@ -0,0 +1,4 @@ +# Copy to .env and fill in values. Never commit .env. +# Token comes from Paperless: Settings -> Django Admin -> Tokens +PAPERLESS_BASE_URL=https://paper.straso.com +PAPERLESS_API_TOKEN= diff --git a/scripts/paperless-mcp/.gitignore b/scripts/paperless-mcp/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/scripts/paperless-mcp/.gitignore @@ -0,0 +1 @@ +.env diff --git a/scripts/paperless-mcp/docker-compose.yml b/scripts/paperless-mcp/docker-compose.yml new file mode 100644 index 0000000..a67dfc4 --- /dev/null +++ b/scripts/paperless-mcp/docker-compose.yml @@ -0,0 +1,23 @@ +# PaperlessMCP — MCP server bridging Claude Code to Paperless-ngx +# Runs locally on Windows (Docker Desktop). Exposed only on localhost. +# Repo: https://github.com/barryw/PaperlessMCP +# +# Start: docker compose up -d +# Stop: docker compose down +# Update: docker compose pull && docker compose up -d +# Logs: docker compose logs -f + +services: + paperless-mcp: + image: ghcr.io/barryw/paperlessmcp:latest + container_name: paperless-mcp + restart: unless-stopped + env_file: + - .env + ports: + - "127.0.0.1:5000:5000" # localhost only — never expose publicly + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:5000/health"] + interval: 30s + timeout: 5s + retries: 3