← all questions
Ground Knowledge

Power tools: the CLI & local app

This website is the easy, keyless way to read and contribute. The command-line tool and the local web console are for power users who want to cold-start a whole question, label sources automatically with their own AI key, batch-import citations, or curate the knowledge base — then push the result back here.

Why these exist

The portal does no AI work and holds no API key — contributing here means you fetch a source, copy a labelling prompt into your own chatbot, and paste the JSON back. That keeps the server safe and free to run. The local tools remove the copy-paste: with your own AI key they label automatically, and they can do things the website can't:

Everything except automatic labelling works with no API key — finding, fetching, the local store, the viewer, push/pull and the manual (chatbot) path all run keyless, exactly like this website.

Install

You need Python 3.9+ and git. The core engine, viewer, fetching, the manual path and the local store need no third-party packages.

# 1. Get the code
git clone https://github.com/Zhenia-Magic/epistemic-coverage.git
cd epistemic-coverage

# 2. (optional) extras — only for full-text PDF, .docx, or running the portal yourself
pip install -r requirements.txt

That's it — python cli.py --help should now list every command.

Configure (.env)

Copy the template and fill in what you need. A key is only required for automatic labelling; leave it blank to use the manual / chatbot path.

# copy the template, then edit .env
cp .env.example .env
ANTHROPIC_API_KEYYour AI key for automatic labelling. Web search / deep research need Anthropic.
… or any one ofNVIDIA_API_KEY (free, build.nvidia.com), OPENAI_API_KEY, DEEPSEEK_API_KEY, MISTRAL_API_KEY, GROQ_API_KEY, GEMINI_API_KEY, OPENROUTER_API_KEY — all label fetched text fine. Set NVIDIA alongside Anthropic and Claude searches while NVIDIA labels for free. The local app also lets you paste a key and pick the provider.
EPISTEMIC_SEARCH_PROVIDER / EPISTEMIC_LABEL_PROVIDERPin each phase to one provider by id (anthropic, nvidia, openai, …) instead of the automatic split. A pin whose key isn't set is ignored. The local console's "Models & access" panel sets these live.
EPISTEMIC_MODEL / EPISTEMIC_SEARCH_MODEL / EPISTEMIC_LABEL_MODELPin the model. The SEARCH/LABEL variants set each phase independently; plain EPISTEMIC_MODEL applies to both when they share a provider.
EPISTEMIC_LABEL_MODELS / EPISTEMIC_RATE_LIMIT_RPMList 2+ label models (comma-separated) to run a multi-model ENSEMBLE and combine by majority vote — a less model-dependent label. The rate cap (default 40/min) paces the free provider so the fan-out stays under its limit.
EPISTEMIC_PORTALThis portal's URL for push/pull — e.g. https://groundknowledge.org.
EPISTEMIC_CONTACT_EMAILYour email → OpenAlex/Crossref "polite pool" (faster, higher limits).
EPISTEMIC_ADMIN_TOKENOnly if you run a portal and want to push whole-KB replacements.

The local app (browser console)

Prefer clicking to typing? Launch a local web console that drives the same find → fetch → label → merge flow in your browser — including a panel to paste your API key and to push/pull cases to this portal.

python cli.py ui            # opens http://localhost:8765
python cli.py ui --port 9000 --no-open

CLI command reference

Every command is python cli.py <command>. Add --build to most mutating commands to regenerate the static viewer afterwards.

Create & inspect

init <id> "question"Start a new, empty knowledge base.
show <kb>Print a summary of the KB.
assess <kb>Print the metrics (distribution, independence, cruxes, blindspots).
build <kb…>Render the standalone HTML viewer for one or more cases.

Add sources

research <kb>One-shot cold start. Emits a single prompt for a browsing chatbot that discovers and labels sources. --apply to auto-merge with a key.
discover <kb>Find candidate sources (--source api = OpenAlex, no key; web / both use AI search).
ingest <kb> <url>Fetch one source and label it. --dry-run writes a prompt to paste into a chatbot; --apply labels with your key.
ingest-batch <kb> …Fetch + label many at once. --bundle (with --dry-run) packs them into ONE file to upload to a chatbot.
harvest <kb>Discover + ingest in one step.
add <kb> <delta>Merge a hand-written / chatbot-returned delta JSON into the KB.

Curate

dups <kb>List likely-duplicate entities worth merging.
merge <kb> <type> <src> <dst>Fold one entity (position/dataset/factor/…) into another.
rename <kb> <type> <ref> "label"Rename an entity.
tidy <kb>Prettify id-style / slug labels for display.

Citations & sync

import-citations <kb> <file>Import a Zotero/Mendeley/EndNote export (.ris, .bib, .csl-json) and label each entry.
export <kb> --format bibtex|ris|cslExport the KB's sources as a citation file.
questionsList the questions on the portal.
pull <id>Download a question's KB from the portal to your machine.
push <kb>Send your local sources up to the portal.

A typical workflow

Cold-start a new question locally, then publish it here:

# 1. create it
python cli.py init eggs "Do eggs increase cardiovascular disease risk?"

# 2. find + label sources automatically (needs an AI key in .env)
python cli.py harvest cases/eggs.kb.json --k 12 --build

# 3. no key? do it the manual way — get one file, label it in your chatbot, merge it back
python cli.py ingest-batch cases/eggs.kb.json --from finds.json --dry-run --bundle
python cli.py add cases/eggs.kb.json delta.json --build

# 4. look at it
python cli.py assess cases/eggs.kb.json

# 5. publish to the portal
python cli.py push cases/eggs.kb.json --as "Your name"

Push & pull (sync with this portal)

Set EPISTEMIC_PORTAL in .env (or pass --portal). A new or empty question pushes with no token (the server strips any trust records — confirmations, verified quotes, the curated badge — so a keyless push lands proposed/unverified). Replacing a question that already has sources needs the portal admin token in EPISTEMIC_ADMIN_TOKEN or --token:

python cli.py questions                 # browse what's here
python cli.py pull <question-id>        # grab it locally
python cli.py push cases/new.kb.json                        # new question: keyless
python cli.py push cases/your.kb.json --token "$EPISTEMIC_ADMIN_TOKEN"  # replace a populated one
Source-by-source contributions are keyless too — anyone can push new sources through the browser contribution flow. Only replacing a knowledge base that already has sources is gated by the portal's admin token.

Full source & README on GitHub →