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 ad17f5e..c69a2a5 100644 Binary files a/02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.docx and b/02 Projekte/Pachtanpassung Viedenz 2026/Nachtrag Pachtvertrag Viedenz.docx differ diff --git a/02 Projekte/Pachtanpassung Viedenz 2026/~$chtrag Pachtvertrag Viedenz.docx b/02 Projekte/Pachtanpassung Viedenz 2026/~$chtrag Pachtvertrag Viedenz.docx deleted file mode 100644 index 4d592e1..0000000 Binary files a/02 Projekte/Pachtanpassung Viedenz 2026/~$chtrag Pachtvertrag Viedenz.docx and /dev/null differ 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