Skip to content

Add documents

kennis corpus add takes files, directories or URLs, and writes them into exactly one collection. There is no "add to all three" - where a document belongs is a decision, not a default.

kennis corpus add <sources>... --collection <literature|docs|notes>

The three shorthands -l, -d and -n mean the same as --collection literature|docs|notes.

A paper

kennis corpus add paper.pdf -l

PDF, DOCX, PPTX and XLSX are converted to markdown first. See Conversion below.

If you know the paper's identifier, supply it rather than letting kennis infer one. It decides the document's own identifier, so getting it right matters:

kennis corpus add paper.pdf -l --identifier arxiv:1101.1764
kennis corpus add paper.pdf -l --identifier 10.1088/0004-637X/728/1/27

To fetch by identifier without a local file:

kennis corpus add arxiv:1101.1764 -l

A citekey is derived from the paper's first author, title and year, which arXiv gives for an arXiv identifier and the DOI's registry for a DOI, asked through doi.org once the paper's text is in hand. Override a derived citekey with --citekey, and a detected title with --title.

A paper with no copy kennis may fetch - behind a publisher, or an arXiv paper arXiv has no rendering of - is refused, with its page named. On a terminal, corpus add then asks for each one: follow the page, download the paper through your institution's access if you have it, and give the path (Tab completes it). Enter skips that paper; Ctrl-C skips the rest. The file is added as corpus add <file> -l --identifier <its identifier> would add it. A pipe or a script is never asked, and the refusal says the same thing in words.

kennis asks arXiv only what its robots.txt files allow, as often as they ask. On 2026-10-18 arxiv.org asked for 15 seconds between requests and export.arxiv.org, arXiv's API, allowed none, so a paper's title, authors and year come from its abstract page and its text from arXiv's HTML rendering: two requests, about half a minute a paper. kennis reads the files rather than these figures, so it follows them when they change.

A note

kennis corpus add meeting.md -n

A note keeps the filename it arrived with. To write one directly instead of adding a file, use kennis remember.

A documentation site

kennis corpus add -d https://stimela.readthedocs.io/en/latest/

kennis reads the site's own page list, or follows its links when it has none, and saves each page under a project named from the site, here stimela. The address decides which pages are taken: only those inside its folder. Add a documentation site explains choosing the address and the project, what is kept from each page, adding a site again, and what kennis does to stay within what a site permits.

A directory

kennis corpus add ~/papers/ -l

Every readable file in it, converted as needed.

Grouping

--group files documents into a subdirectory of the collection:

kennis corpus add paper.pdf -l --group radio-astronomy

Groups are ordinary directories and can nest: --group radio/calibration files the paper in calibration, inside radio, and creates both if they are not there. They are what --group filters on at search time. The window draws them nested, and its Group fields offer every level already held.

Keeping the source

By default kennis keeps the markdown and discards the source bytes. To keep both:

kennis corpus add paper.pdf -l --keep-original

Or set corpus.keep_original = true to make it the default.

Conversion

Anything that is not already markdown or plain text goes through a converter.

mineru is the default. It runs locally, costs nothing, and is installed with kennis.

datalab is hosted. It is chosen only by setting conversion.backend and supplying an API key, because sending a document to a third party is never something kennis does by default. See Keep credentials out of the config.

Write a note directly

kennis remember "Cosine cuts only mean anything per-model."
kennis remember --from draft.md --title "Retrieval notes"

remember writes into notes and updates the notes index in the same command - once an index exists. Before the first kennis corpus index there is nothing to update, and it says not indexed and tells you so. Pass --no-index to skip the update when adding several in a row.

Then index

Adding a document does not make it searchable. Indexing does:

kennis corpus index                        # all three collections
kennis corpus index --collection docs      # just one

The first dense index downloads the embedding model - about 65 MB for the default - and kennis prints a line saying so before it starts.

Reading does not require an index:

kennis read <handle>              # works on an unindexed document
kennis read <handle> --chunks 3   # needs the index, since chunks live there