Zettelrobbe

Zettelrobbe

apps.detail.types.app from popov's Repository

apps.detail.sections.overview

Automatically tag, sort, and search your Paperless-ngx documents – using local or hosted AI. Tagging IA fiable, OCR rescue queue (Mistral ou modeles vision locaux, PDF multi-pages), files failed/ignored, historique rescan, MFA, setup guide, custom fields enrichis. Configuration initiale via le wizard web au premier lancement (URL Paperless-ngx, token API, provider LLM/OCR).

📊 At a Glance: Next vs. Original

Feature Paperless-AI Zettelrobbe
Core automation
AI-based document classification
Paperless-ngx integration
Basic manual processing flows
Performance and scale
Server-side history pagination
Tag caching with reduced API calls
Faster dashboard behavior under high volume
Security and reliability
Security-focused dependency maintenance
Global API + SSE rate limiting
MFA login support
OCR and recovery workflows
Works with blurry documents and images
UX and operations
Settings tabs with runtime ENV hints

🚀 The Evolution: What makes it "Next"?

This isn't just a collection of patches; it's a total overhaul of how your documents interact with AI. I took the original logic and ran it through a "Does this actually make my life easier?" filter.

🧠 High-IQ Classification

Connect to OpenAI, Ollama, or any OpenAI-compatible API. We've moved beyond simple keyword matching. The AI now understands intent and context, meaning it knows the difference between an "Electricity Bill" and a "Manual for a Toaster" without you writing a single regex.

👓 Flexible OCR Vision (Mistral + Local)

Waging war against blurry scans, shaky smartphone photos, and handwritten scribbles that standard OCR usually chokes on. You can run OCR with:

  • Mistral OCR (provider: mistral)
  • local OpenAI-compatible vision APIs (provider: ollama + /v1 endpoint, e.g. LM Studio, vLLM, or any other OpenAI-compatible server)
  • native Ollama chat vision APIs (provider: ollama + /api/chat endpoint)

This isn't locked to one model. Any vision-capable model your endpoint serves works — for example llama3.2-vision, gemma3, qwen2-vl, minicpm-v, moondream, pixtral, internvl, or llava. During setup, Quickstart probes your endpoint and automatically detects which of its models are vision-capable, so you don't have to guess.

Multi-page PDFs are also fully supported for local vision models: pages are rendered to images via poppler and sent to the model one by one, instead of only OCRing a single-page thumbnail (see OCR Provider Notes below). Mistral OCR handles PDFs natively.

The OCR setup now also validates real image reading instead of only checking endpoint reachability.

⚡️ Performance without the "Spinner-Induced Rage"

I hated the lag in the original UI. I've implemented server-side pagination and aggressive tag caching. Whether you're managing 100 documents or 10,000, the dashboard stays snappy and your browser stays alive.

🛡️ Hardened for Production

I use this for my own life and my own documents. That means security isn't an afterthought - it's a requirement. Expect regular dependency updates, a reduced container attack surface, and error handling that fails gracefully instead of taking your whole stack down with it.

🧩 The "Best of" Community DNA

There were dozens of brilliant ideas and PRs left gathering dust in the original repository. I've personally hand-picked, tested, and integrated the best community suggestions, making this the most feature-complete version of the tool available.

🤖 Vibe-Coded, Human-Vetted

Built with heavy AI assistance but steered by human common sense. It's vibe-coded in the sense that I prioritize how the tool actually feels to use over rigid corporate specs. Yet it's engineered to be more stable than your enterprise-driven Microsoft Access '97 nightmare business software.


💖 Fuel the Evolution

Maintaining this solo, chasing bugs, and keeping up with the rapid pace of AI is a massive labor of love. If this tool saves your sanity (and your weekends), consider fueling the next update. Whether it's a cold energy drink or just a "thanks"; your support keeps the code flowing.

GitHub Sponsors Buy Me A Coffee PayPal Ko-fi


⚠️ A Note on Stability & Migration

Data is sacred. Back it up.

Because Zettelrobbe introduces significant architectural improvements and new database logic, it's a "one-way street" evolution. Since I am cleaning up and optimizing the core logic plus adding new features, there is no guarantee of stability right now.

However, I develop this for my own production environment, so I have zero interest in breaking things. However, every server is different. Please create a full backup of your Paperless-ngx. If you're coming from the original version, a fresh install is often the cleanest path to document zen.


🚀 Quick Start

Docker Compose (Recommended)

Please check the docker variables here for all configuration options.

If you are using plain HTTP (like running Zettelrobbe locally on your NAS, your PC, or in your home network), make sure to set COOKIE_SECURE_MODE=never to avoid login issues! See Configuration for details. Using a reverse proxy like Nginx or Caddy with HTTPS is highly recommended for security and performance, especially if you expose the service to the internet.

services:
  zettelrobbe:
    image: admonstrator/zettelrobbe:latest
    container_name: zettelrobbe
    restart: unless-stopped
    ports:
      - '3000:3000'
    volumes:
      - data:/app/data

volumes:
  data:

Then open http://localhost:3000 to complete setup.

OCR Provider Notes

  • OCR API key env: OCR_API_KEY (backward-compatible fallback: MISTRAL_API_KEY)
  • Local OCR supports model discovery from both /api/tags (Ollama-style) and /v1/models (OpenAI-compatible)
  • OCR test sends a real PNG image and expects the exact token: OCR-TEST-182730173401
  • For OpenAI-compatible endpoints that reject data URLs, OCR validation automatically retries with raw base64 payload
  • Local vision OCR renders multi-page PDFs to per-page images via poppler (pdftoppm, bundled in the Docker image) and sends each page to the model. Configure with OCR_PDF_RENDER_ENABLED (default yes), OCR_PDF_RENDER_MAX_PAGES (default 10, each page is one model request), and OCR_PDF_RENDER_DPI (default 150)
  • On bare-metal installs, install poppler-utils to enable multi-page PDF OCR; without it the app falls back to OCRing only the first-page thumbnail
  • The Mistral OCR provider processes PDFs natively and ignores the OCR_PDF_RENDER_* settings
  • The OCR queue can be worked through automatically instead of pressing Process All Pending: enable OCR_AUTO_PROCESS_ENABLED (default no) and configure OCR_AUTO_PROCESS_INTERVAL (cron, default */15 * * * *), OCR_AUTO_PROCESS_BATCH_SIZE (documents per run, default 10) and OCR_AUTO_ANALYZE (run AI analysis right after OCR, default yes). Runs are skipped while a document scan is active or while Paperless-ngx is unreachable, so queued documents are never marked as failed because of an outage

Container Images

Image Tag Size
admonstrator/zettelrobbe:latest ~500–700 MB

Docker Hub: admonstrator/zettelrobbe

Versioned release tags use the format vYYYY.MM.## (example: v2026.03.01).


💬 Frequently Asked Questions

"Is this project stable if it's vibe-coded?"

Short answer: I use it every day for my actual documents. If it breaks, my own life becomes a chaotic mess of untagged invoices—so I have a very strong biological incentive to keep it stable.

Long answer: It's not vibe-coded in the sense of being random; I test every feature and try to automate as much of the testing as possible. And NO! it's not just one pile of AI-generated code inside a main.js file. Since I work as an IT architect, I understand the importance of maintainable code.

"So you don't read the code? Should I be worried?"

I can read and understand code logic, but I don't write JavaScript from scratch myself. I treat AI like a talented, slightly erratic junior dev. I guide the architecture, I read and audit the logic of every line it generates, and I test the hell out of it. I am the filter. No "AI-slop" gets merged without passing my "Does this actually solve the problem?" test. Or at least, it doesn't stay merged if I encounter issues in production. You can learn more about the author's background and the AI-assisted development workflow on the About the Project & Author page.

"Why was RAG (semantic search/chat) support removed?"

We decided to focus the project entirely on its core mission: highly reliable automated document tagging, correspondent detection, and custom field/metadata extraction. Running a secondary Python RAG container with a vector database (ChromaDB) added massive image sizes, high RAM requirements, and severe architectural overhead. For a detailed breakdown of this decision, check out the RAG Deprecation page.

"What if I'm a 'real' developer and I find a bug?"

Please, for the love of all that is holy, open a PR. I welcome everyone; from fellow vibe-coders to the wizards who actually understand memory management. If you see something that makes your inner Senior Architect cry, fix it and send it over. I'm happy to learn, as long as we keep the "it just works" spirit alive.

"Why should I use this instead of the original project?"

If the original works for you, stay there! But if you're tired of loading spinners, want better AI and OCR, then Zettelrobbe is for you. It's a more polished, more powerful, and more user-friendly evolution of the original vision.

"Does this support [Specific Niche AI Provider]?"

If it's OpenAI-compatible, it probably works. If not, open an issue! Since I have an AuDHD brain, I'm prone to hyper-focusing on cool new features — so if your suggestion catches my interest, it might be implemented before my second energy drink.


Zettelrobbe is made with ❤️ by admon for the community

⭐ If you find this useful, please star the repository!

apps.marketingCta.appInstallTitle

apps.marketingCta.appInstallDescription

apps.installHelp.stepOpen apps.installHelp.stepSearchApp apps.installHelp.stepReview apps.installHelp.stepInstall

apps.detail.sections.categories

apps.downloadStats.title

1,526
apps.downloadStats.metrics.totalDownloads

apps.detail.sections.related

apps.detail.sections.details

apps.detail.details.repository
admonstrator/zettelrobbe:latest
apps.detail.details.lastUpdated2026-08-03
apps.detail.details.firstSeen2026-08-05

apps.detail.sections.runtime

apps.detail.details.webui
http://[IP]:[PORT:3000]/
apps.detail.details.network
bridge
apps.detail.details.shell
sh
apps.detail.details.privileged
false
apps.detail.details.extraParams
--restart=unless-stopped

apps.detail.sections.configuration

WebUI PortPorttcp

Port hote pour l'interface web (container: 3000)

apps.detail.config.target
3000
apps.detail.config.default
3000
apps.detail.config.value
3000
DataPathrw

Base SQLite, config et etat de l'application

apps.detail.config.target
/app/data
apps.detail.config.default
/mnt/user/appdata/zettelrobbe
apps.detail.config.value
/mnt/user/appdata/zettelrobbe
COOKIE_SECURE_MODEVariable

'never' pour acces HTTP LAN. Passer en 'auto' derriere un reverse proxy HTTPS (Cloudflare Tunnel)

apps.detail.config.default
never
apps.detail.config.value
never
TZVariable

Fuseau horaire

apps.detail.config.default
Europe/Zurich
apps.detail.config.value
Europe/Zurich
ALLOW_REMOTE_SETUPVariable

Autorise l'acces au wizard de setup depuis le LAN (le setup n'est accessible que depuis localhost par defaut). Remettre a 'no' apres la configuration initiale.

apps.detail.config.default
yes
apps.detail.config.value
yes