Resolve papers (arXiv id / DOI / title) to canonical, normalized BibTeX for agents and humans
Project description
bibcite
Resolve papers (arXiv id / DOI / title) to canonical, normalized BibTeX, and manage .bib files so agents never hand-edit them.
The publication-matching cascade is ported from PaperMemory's bibMatcher: DBLP → Semantic Scholar → Google Scholar → CrossRef → Unpaywall. A match must have an identical normalized title, a plausible year, and a non-preprint venue.
Venue names are canonicalized against the @string table vendored in src/bibcite/data/strings.bib (journals / conferences / workshops), including year-aware rules (NIPS before 2018 vs NeurIPS, WACV before 2017).
Entry types are strict: conference/workshop papers become @inproceedings + booktitle, journal papers @article + journal, and unpublished arXiv preprints @misc + howpublished = {arXiv preprint arXiv:ID}.
Types coming from authoritative source BibTeX (DBLP) are preserved.
After every write, the file is formatted with bibtex-tidy using the canonical flags in bibfile.TIDY_ARGS (requires bibtex-tidy on PATH or npx).
Install
# from a local checkout (development)
uv tool install --editable .
# from git, no checkout needed
uv tool install git+https://github.com/leo1oel/bibcite
# once published to PyPI (package name bibcite-cli, command name bibcite)
uv tool install bibcite-cli # or: uvx --from bibcite-cli bibcite ...
# plus, once (required for the tidy step):
npm install -g bibtex-tidy
To use your own venue table instead of the vendored one, set BIBCITE_STRINGS=/path/to/strings.bib or place it at ~/.config/bibcite/strings.bib.
Environment variables that make the sources faster/more reliable:
| Variable | Effect |
|---|---|
OPENALEX_API_KEY |
OpenAlex refuses anonymous search with 503 under load; a free key makes it dependable |
S2_API_KEY |
Semantic Scholar private quota (~1 req/s) instead of the shared global pool |
BIBCITE_MAILTO |
Your contact email for the CrossRef/OpenAlex/Unpaywall polite pools |
BIBCITE_CORE_SOURCES |
Override which sources count as "core" for published_check verdicts (default dblp,semanticscholar,crossref,openalex) |
BIBCITE_NO_CACHE=1 |
Disable the local match cache |
Usage
# Preview the BibTeX for a paper (nothing written)
bibcite get 1706.03762
bibcite get "Attention is all you need"
bibcite get 10.1109/CVPR52688.2022.01167
# Resolve and write into a .bib file, dedupe, then bibtex-tidy; prints the final key
bibcite add refs.bib 2103.14030 --json
# Add a raw BibTeX entry you already have (venue still canonicalized, file still tidied)
bibcite add refs.bib --bibtex "$(pbpaste)"
# Batch add (one query per line; shares rate-limit state, tidies once)
bibcite add refs.bib --from ids.txt
# Overwrite a bad existing entry (keeps its key), or delete one
bibcite add refs.bib <query> --replace
bibcite remove refs.bib <key>
# One-shot cleanup: upgrade preprints → tidy → lint
bibcite fix refs.bib
# Upgrade every arXiv entry in a file to its published version (bibMatcher, CLI-style)
bibcite upgrade refs.bib --dry-run
# Just format, or just lint (check is read-only)
bibcite tidy refs.bib
bibcite check refs.bib
add/upgrade/check/fix/remove print a machine-readable JSON result on stdout (action, key, venue, source, ...); all diagnostics go to stderr.
add is idempotent: an existing entry returns action: exists with its key, and an existing arXiv entry matched to a published version is upgraded in place, keeping its citation key.
Exit codes: 0 success, 2 paper not found (ask for a better identifier), 3 sources/tool failure (retry later).
Successful matches are cached at ~/.cache/bibcite/published.json (published papers only — preprint status is never cached); bypass with --no-cache or BIBCITE_NO_CACHE=1.
Entries marked pubstate = {preprint} are treated as confirmed preprint-only and muted from check/upgrade.
For agents
Never edit .bib files by hand.
Call bibcite add <file> <query> --json and use the returned key in \cite{...}.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bibcite_cli-0.5.2.tar.gz.
File metadata
- Download URL: bibcite_cli-0.5.2.tar.gz
- Upload date:
- Size: 47.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b625a09cf59c5c9087ad9c94f02cb226ef4abf06ab619990aa1b34660ac2ff1
|
|
| MD5 |
032d0f8be811d6d69f4c9776e0f6550c
|
|
| BLAKE2b-256 |
4eb3eeda31875379abac0b07b323db6c67235f05de245d1e3fd1d8ab26ef4387
|
File details
Details for the file bibcite_cli-0.5.2-py3-none-any.whl.
File metadata
- Download URL: bibcite_cli-0.5.2-py3-none-any.whl
- Upload date:
- Size: 37.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51eafc560a9d9d4c7e0ae23447a6ad41a1507003292742cc5ba221bb61b46c82
|
|
| MD5 |
7ff9d8ae0a4aca5cb68abe3a47327eca
|
|
| BLAKE2b-256 |
0a397115098c86857578add52b8289d0adac5817edc27b686bf905c8dccd4fe9
|