ECDO Corpus

← Search docs

ECDO is a local-first hybrid search + RAG system over a corpus of anomaly-research, geology, earth-history / polar-motion, and Hermetic literature. Documents are extracted from PDFs/EPUBs with MinerU, chunked, embedded (nomic-embed-text via Ollama), and indexed in LanceDB. Search fuses dense-vector, lexical (boolean), and reciprocal-rank-fusion results.

Search functions

Query syntax (boolean, case-insensitive)

SyntaxMeaning
wordRequired term — AND with other bare words.
"exact phrase"Phrase that must appear verbatim.
+requiredExplicit required token.
-excluded / NOT excludedToken must not appear.
!fuzzy termSoft / substring match — bonus only, not mandatory.
A NEAR BA and B co-occur within ~8 words (windowed).
A OR BEither clause may match (OR across clauses).
A AND BExplicit AND (default for bare words).
OR model: the query splits on OR into clauses. A document matches if any clause is satisfied; within a clause, terms are AND'd. So volcano OR earthquake mantle means (volcano) OR (earthquake AND mantle) — OR binds looser than AND.

Modes

ModeBehaviour
hybrid defaultVector + lexical, fused with RRF. Best general recall.
vectorDense semantic similarity only.
lexicalPure boolean / keyword — operators apply strictly.

Options

Examples

volcano earthquake              # both words
volcano OR earthquake         # either word
volcano OR earthquake mantle  # (volcano) OR (earthquake AND mantle)
"hermetic" OR "kybalion"        # either phrase
polar motion NOT noise         # both words, exclude "noise"
mars NEAR water                  # co-occurrence within 8 words
catastrophism !comet             # term + soft bonus, not mandatory

Agent API

Base URL: http://127.0.0.1:8800 (also reachable on the LAN / Tailscale IP on port 8800). All responses are JSON. search is also available as a GET for convenience.

MethodEndpointDescription
POST / GET/api/v1/search?q=&top_k=&mode=&target=&fold= Ranked chunks. Honors all search syntax + modes. target scopes to a classified category; fold=false returns raw chunks.
GET/api/v1/doc?rel=<rel_path> Full extracted text of a source document (chunks joined) plus the chunk list.
GET/api/v1/chunk?rel=<rel>&idx=<n> A single chunk by index.
GET/api/v1/image?rel=<rel>&name=<file>&b64=1 Image artifact — base64 JSON (b64=1) for direct reuse, or raw binary otherwise.
GET/api/v1/artifacts?rel=<rel> PDF / JSON / image metadata for a document.
GET/api/v1/doi?rel=<rel>&title=<t> DOI — embedded in the PDF header, else a Crossref fallback (title-guarded).
GET/api/v1/health · /api/v1/stats Engine + UI status; indexed chunk count; live queue depth.
GET/api/parse-query?q= Parsed operators (phrases / required / excluded / fuzzy / near / segments) — powers the syntax chips.

Ingestion queue control

Let agents prioritise active research: promote existing queue items to the front, or add already-ingested corpus docs (present under RAG/ but not yet queued) to the front for re-processing. New files dropped into the RAG folder are automatically unshifted to the front of the queue.

MethodEndpointDescription
GET/api/ingest-queue Full queue: paused, parallel, queue_len, active (in-flight jobs w/ progress), and the ordered queue list.
POST/api/ingest-settings {paused, parallel} Pause (or set parallel 0–8) / resume ingestion.
POST/api/ingest-reorder {order:[rel_keys]} Replace the queue order with the given full rel_key list.
POST/api/ingest-promote {rel_keys:[...]} Move existing queue items to the FRONT (top), preserving listed order. Ignores unknown keys.
POST/api/ingest-add {rel_keys:[...], manual?} Add existing corpus docs (not yet queued) to the FRONT; already-queued docs are promoted, not duplicated.
POST/api/upload (multipart file) Upload a new document to the RAG folder; it is placed at the top of the queue (manual).

Example requests

curl -X POST http://127.0.0.1:8800/api/v1/search \
     -H 'Content-Type: application/json' \
     -d '{"query":"polar motion earth rotation","top_k":8,"mode":"hybrid"}'

curl "http://127.0.0.1:8800/api/v1/search?q=volcano%20OR%20earthquake&top_k=5"

curl "http://127.0.0.1:8800/api/v1/doc?rel=root/1908kybalion/1908kybalion/vlm/1908kybalion.md"

curl "http://127.0.0.1:8800/api/v1/image?rel=root/x/vlm/x.md&name=fig1.png&b64=1"

Python client

A zero-dependency client is bundled at the repo root (ecdo_client.py) — usable from any Python 3, or as a CLI:

python3 ecdo_client.py search "polar motion" --top-k 8 --mode hybrid
python3 ecdo_client.py doc "root/1908kybalion/1908kybalion/vlm/1908kybalion.md"
python3 ecdo_client.py image "root/x/vlm/x.md" "fig1.png" --out /tmp/fig1.png
python3 ecdo_client.py health
python3 ecdo_client.py stats

Hermes provider (MCP)

ECDO is also registered as a Hermes local search provider (MCP server ecdo, enabled). Tools: search, get_text, get_chunk, list_artifacts, get_image (base64), get_doi, health — usable alongside SearXNG / web search.

hermes mcp list     # ecdo → enabled, 7 tools
hermes mcp test ecdo  # connectivity + tool discovery

Ingesting documents

Drop source files into RAG/ — including subfolders (the ingestor traverses recursively). Supported: .pdf .epub .jpg .jpeg .png .webp .tiff .bmp. The daemon picks them up automatically; MinerU's own working trees (vlm/, images/, .mineru_output/) are excluded. The status bar shows live queue depth.

Note: the web UI is plain HTTP with no authentication (LAN / Tailscale only). Do not expose port 8800 to the public internet without adding auth.

← Back to search