Skip to content

Configuration ​

mosaic reads its settings from ~/.config/mosaic/config.toml. Every key has a default, so the file only holds what you change. You edit it with mosaic config flags or by hand; this page lists every key and the flag that sets it.

Where things live ​

WhatDefault locationKey
Configuration~/.config/mosaic/config.toml
Browser sessions (mosaic auth login)~/.config/mosaic/sessions/
Cache: papers, downloads, searches, watches, vector index~/.local/share/mosaic/cache.dbdb_path
Downloaded PDFs~/mosaic-papers/download_dir

mosaic writes the configuration file the first time a mosaic config flag changes something, readable by you only (mode 0600: it holds API keys). Until then the defaults apply.

Reading and changing it ​

bash
mosaic config --show                                # print the merged configuration as JSON
mosaic config --unpaywall-email you@example.org     # change one setting, then save
mosaic config --download-dir ~/papers --rate-limit-delay 2

mosaic config with no flag prints the configuration too. Several flags combine in one call. Keys that have no flag (marked "edit the file" below) go into the TOML file directly; mosaic merges the file over its defaults when it starts, and logs a warning for a value of the wrong type or an unknown source name.

A first setup usually needs one line, the e-mail that Unpaywall requires to find open PDFs:

bash
mosaic config --unpaywall-email you@example.org

Top-level keys ​

KeyDefaultFlagMeaning
download_dir~/mosaic-papers--download-dirWhere PDFs are saved; --download-dir on search, get, import overrides it per run
db_path~/.local/share/mosaic/cache.db--db-pathThe SQLite cache
filename_pattern{year}_{source}_{author}_{title}--filename-patternName of a downloaded PDF, see File names
rate_limit_delay1.0--rate-limit-delaySeconds between two arXiv requests
custom_sources[]edit the fileExtra JSON APIs searched like built-in sources: Custom sources

File names ​

filename_pattern builds the name of every PDF that search --download, get, get --handoff and import save. The same placeholders work in obsidian.filename_pattern for note names.

PlaceholderValueWhen missing
{year}publication year0000
{source}source that returned the paper (arXiv, DOAJ, Crossref, ...)
{author}first word of the first author's name, as the source lists itUnknown
{title}title, punctuation removed, cut to 60 characters, spaces as _
{doi}DOI with characters other than letters, digits, . and - replaced by _no_doi
{journal}journal name, cleaned like the titleno_journal

{author} is a family name for sources that list "Family, Given" (Crossref: 2005_Crossref_Boyd_...) and a given name for those that list "Given Family" (arXiv, DOAJ: 2004_arXiv_Jose_...). Already downloaded papers are recognised by the cache, so changing the pattern renames nothing and downloads nothing twice; new downloads use the new pattern.

bash
mosaic config --filename-pattern "{year}_{journal}_{author}_{title}"

Sources ​

Each source has a table [sources.<name>] with enabled = true and, for some, more keys. --enable-source NAME and --disable-source NAME (repeatable) switch sources on and off by config name:

Config name--sourceExtra keys
arxivarxiv
semantic_scholarssapi_key
sciencedirectsdapi_key
springersp
springer_apispringerapi_key
doajdoaj
europepmcepmc
cochranecochrane
openalexoa
basebase
corecoreapi_key
nasa_adsadsapi_key
ieeeieeeapi_key
zenodozenodoapi_key
crossrefcrossref
dblpdblp
halhal
pubmedpubmedapi_key
pmcpmcapi_key
biorxivrxiv
pedropedroacknowledge_fair_use, fetch_details, rate_limit_delay
scopusscopusapi_key, inst_token
bash
mosaic config --disable-source base --disable-source zenodo

What each source covers and needs: Sources.

API keys ​

KeyFlagGet it at
sources.semantic_scholar.api_key--ss-keysemanticscholar.org/product/api
sources.sciencedirect.api_key--elsevier-keydev.elsevier.com
sources.scopus.api_key--scopus-keydev.elsevier.com (same Elsevier key)
sources.scopus.inst_token--scopus-inst-tokenElsevier support, through your library
sources.springer_api.api_key--springer-keydev.springernature.com
sources.core.api_key--core-keycore.ac.uk/services/api
sources.nasa_ads.api_key--ads-keyui.adsabs.harvard.edu
sources.ieee.api_key--ieee-keydeveloper.ieee.org
sources.zenodo.api_key--zenodo-keyzenodo.org
sources.pubmed.api_key, sources.pmc.api_key--ncbi-key (sets both)ncbi.nlm.nih.gov

CORE, NASA ADS, IEEE Xplore and the Springer Nature API are skipped until their key is set; the others work without one.

ScienceDirect (Elsevier) ​

ScienceDirect searches with the Elsevier API when sources.sciencedirect.api_key is set, and otherwise through a saved browser session (mosaic auth login), if one is valid. Create the key at dev.elsevier.com, under "Manage API Keys"; a new key can take up to 15 minutes to activate, and answers HTTP 401 until then. In API mode mosaic asks for open-access articles only. The browser session sees what your institution subscribes to. Scopus works the same way with its own key and inst_token. Sessions: Authenticated access.

bash
mosaic config --elsevier-key KEY --scopus-key KEY

PEDro ​

KeyDefaultFlag
acknowledge_fair_usefalse--pedro-fair-use / --no-pedro-fair-use
fetch_detailsfalse--pedro-fetch-details / --no-pedro-fetch-details
rate_limit_delay3.0--pedro-rate-limit-delay

PEDro stays off until acknowledge_fair_use is true: Sources, PEDro.

Unpaywall ​

KeyFlag
unpaywall.email--unpaywall-email

Unpaywall wants an e-mail address with each request and has no account. Without it, get and --download use only the PDF links the sources return. mosaic also sends this address to OpenAlex, Crossref and the citation providers, which serve identified clients faster.

Institutional proxy ​

KeyDefaultFlag
proxy.url""--proxy-url

The address of a paper behind your institution's proxy (EZproxy), with {doi} where the DOI goes. With it set, get --auto opens each paper there instead of at doi.org. --proxy-url none removes it. See Authenticated access, institutional proxy.

bash
mosaic config --proxy-url 'https://biblioproxy.cnr.it:2481/{doi}'

Zotero ​

KeyDefaultFlag
zotero.api_key""--zotero-key
zotero.user_id0set by --zotero-key

With no key, --zotero talks to the Zotero desktop app on this computer. --zotero-key stores a web API key and looks up your user ID at once. Details: Zotero.

Obsidian ​

KeyDefaultFlag
obsidian.vault_path""--obsidian-vault
obsidian.subfolderpapers--obsidian-subfolder
obsidian.filename_pattern{year}_{author}_{title}--obsidian-filename-pattern
obsidian.tags["paper"]--obsidian-tag (repeatable; replaces the list)
obsidian.wikilinkstrue--obsidian-wikilinks / --no-obsidian-wikilinks

Details: Obsidian.

LLM ​

One model serves --sort relevance, --summarise, compare, ask and chat.

KeyDefaultFlagMeaning
llm.provider""--llm-provideropenai (also any OpenAI-compatible server) or anthropic
llm.api_key""--llm-api-keyKey; any non-empty string for a local server
llm.model""--llm-modelEmpty: gpt-4o-mini (openai) or claude-haiku-4-5-20251001 (anthropic)
llm.base_url""--llm-base-urlOpenAI-compatible server, e.g. http://localhost:11434/v1 for Ollama (/v1 is added when missing)
llm.timeout0--llm-timeoutSeconds to wait for one answer; 0 keeps the built-in 2–3 minutes. Raise it for large local models

mosaic uses the LLM only when both provider and api_key are set. A local Ollama server:

bash
mosaic config --llm-provider openai --llm-base-url http://localhost:11434/v1 --llm-api-key ollama --llm-model qwen3:8b

RAG ​

Settings for mosaic index, ask, chat and search --semantic (Asking your library).

KeyDefaultFlagMeaning
rag.embedding_model""--embedding-modelEmbedding model; required to index
rag.embedding_base_url""--embedding-base-urlEmbedding server; empty: llm.base_url, or OpenAI
rag.embedding_api_key""--embedding-api-keyEmpty: llm.api_key
rag.embedding_provider""edit the fileNot used: embeddings always go through the OpenAI embeddings API (cloud OpenAI, or the server at embedding_base_url)
rag.top_k10--rag-top-kPapers retrieved per question
rag.chunk_size512edit the fileTokens per text chunk (counted as 4 characters each)
rag.chunk_overlap50--chunk-overlapTokens shared by consecutive chunks
rag.full_text_indextrue--full-text-index / --no-full-text-indexIndex the text of downloaded PDFs; needs pymupdf installed
rag.auto_indexfalse--rag-auto-index / --no-rag-auto-indexIndex new papers after every search and get

Change the embedding model and the stored vectors no longer match: run mosaic index --reindex.

Citation graph ​

KeyDefaultMeaning
rag.citations.enabledfalseBoost retrieval with citation links, and fetch them on every mosaic index
rag.citations.boost_alpha0.3Weight of the boost; 0 turns it off
rag.citations.providers["openalex", "crossref"]Where citation links come from, in order; opencitations also works
rag.citations.expand_neighborsfalseAdd papers one citation away to the retrieved set

These keys have no flags: edit the file.

toml
[rag.citations]
enabled = true
boost_alpha = 0.3

Details: Citation graph.

See also: tutorial: getting the PDFs, maintenance recipes, mosaic config.

Released under GPL-3.0-or-later, BSD-2-Clause, BSD-3-Clause or MIT, at your choice.