Skip to content

Document Ingestion Pipeline

Ingest PDFs, Word, PPTX, XLSX from Nextcloud/Paperless into Open WebUI's knowledge base and make them searchable via MCP.

Architecture

Nextcloud folder / Paperless webhook
  → n8n trigger (CT 104)
  → Docling MCP (port 18005) — PDF/DOCX/PPTX/XLSX → Markdown + structure
  → TEI /v1/embeddings  — multilingual-e5-base (local, 768d)
  → Qdrant (shared vector store, http://qdrant:6333)
  → Open WebUI knowledge base API  ← searchable in chat

Paperless shortcut: Paperless-ngx already OCRs documents. Its full-text content is available at /api/documents/?added__gt=<last_run>. An n8n workflow can re-embed directly from Paperless's REST API without re-running Docling for already-OCR'd PDFs.

Deployed components (as of 2026-05-26)

Component Location Endpoint
Qdrant CT 104, ai-internal net http://qdrant:6333 (REST), qdrant:6334 (gRPC)
nomic CT 104, ai-internal net http://nomic:80 — text+vision 768d
TEI (Text Embeddings Inference) CT 104, ai-internal net http://tei:80 — text-only 768d (standby)
Open WebUI CT 104, port 14002 Uses Qdrant + nomic natively
Bifrost CT 104, port 14003 Semantic cache → Qdrant gRPC, mistral-embed 1024d
Docling MCP CT 104, port 18005 MCP server in gateway

Embedding stack

Service Model Dimensions Use
nomic nomic-ai/nomic-embed-text-v1.5 + nomic-embed-vision-v1.5 768d OWUI RAG, ingest pipeline
TEI intfloat/multilingual-e5-base 768d Standby; same vector space as nomic text
Bifrost cache mistral/mistral-embed via Bifrost 1024d Semantic cache only (separate Qdrant collection)

Both nomic models share a 768d embedding space — text and image queries work on the same documents Qdrant collection.

OWUI RAG config (env-driven)

VECTOR_DB=qdrant
QDRANT_URI=http://qdrant:6333
RAG_EMBEDDING_ENGINE=openai
RAG_OPENAI_API_BASE_URL=http://nomic:80
RAG_OPENAI_API_KEY=none
RAG_EMBEDDING_MODEL=nomic-ai/nomic-embed-text-v1.5
CONTENT_EXTRACTION_ENGINE=docling
CHUNK_SIZE=1200
CHUNK_OVERLAP=150
ENABLE_RAG_HYBRID_SEARCH=true

To switch to Bifrost embeddings (1024d, better quality — requires re-indexing documents collection):

RAG_OPENAI_API_BASE_URL=http://bifrost:8080/v1
RAG_EMBEDDING_MODEL=mistral/mistral-embed

Bifrost embedding models (available for external services / upgrade)

Three embedding models tested and working via http://bifrost:8080/v1/embeddings: - mistral/mistral-embed (1024d) — ✓ production-ready - mistral/codestral-embed (1024d) — ✓ - gemini/gemini-embedding-001 (768d/1536d) — ✓

Converter comparison

Tool Image Formats Notes
Docling (deployed) MCP on 18005 PDF, DOCX, PPTX, XLSX, HTML Best for structured Office/PDF with tables
MinerU opendatalab/mineru PDF (layout-aware, OCR) Better for academic papers / scanned PDFs
Markitdown (in gateway) Office, PDF Ad-hoc only; not suitable for batch

Start with Docling — already deployed. Add MinerU if academic paper OCR quality is needed.

Sharing Qdrant with other services

Qdrant is on ai-internal network — any service on that network can use it:

from qdrant_client import QdrantClient
client = QdrantClient(url="http://qdrant:6333")

n8n, MCP tools, and custom pipelines should use http://nomic:80/v1/embeddings for consistent 768d vectors. Mixing models/dimensions in the same collection will fail.

Bifrost semantic caching

Bifrost uses Qdrant (gRPC port 6334) as a semantic cache backend. Config lives in /opt/stacks/ai/bifrost/data/config.json:

{
  "$schema": "https://www.getbifrost.ai/schema",
  "vector_store": {"enabled": true, "type": "qdrant", "config": {"host": "qdrant", "port": 6334}},
  "plugins": [{
    "enabled": true, "name": "semantic_cache",
    "config": {
      "provider": "mistral", "embedding_model": "mistral-embed", "dimension": 1024,
      "ttl": "10m", "threshold": 0.85, "conversation_history_threshold": 3, "exclude_system_prompt": true
    }
  }]
}

The semantic cache uses a separate Qdrant collection (auto-created) at 1024d — no collision with the documents collection at 768d. TTL: 10 min, similarity threshold: 0.85.

Intel Arc GPU passthrough (enabled)

CT 104 Intel Core Ultra 7 155H iGPU is passed through via PVE dev3/dev4 entries (/dev/dri/renderD128 and /dev/dri/card1). No TEI Intel image exists currently — passthrough is available for future inference acceleration.

Pending

  • n8n workflow: Nextcloud/Paperless → Docling → nomic → Qdrant
  • MCP knowledge-search tool pointing at Qdrant (replaces LobeChat search intent)
  • ingest.py filesystem scan script (see ingest-pipeline.md)