{
  "markdown": "# Bibverify\n\n<!-- mcp-name: io.github.Hylouis233/bibverify -->\n\n<p align=\"center\">\n  <strong>Verify bibliographic existence and metadata consistency without destructive edits.</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"README_CN.md\">Chinese</a> · <a href=\"#install\">Install</a> · <a href=\"#quick-start\">Quick start</a> · <a href=\"#mcp-and-ai-assistants\">MCP</a> · <a href=\"#development\">Development</a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://pypi.org/project/bibverify/\"><img src=\"https://img.shields.io/pypi/v/bibverify.svg\" alt=\"PyPI\"></a>\n  <a href=\"https://pypi.org/project/bibverify/\"><img src=\"https://img.shields.io/pypi/pyversions/bibverify.svg\" alt=\"Python versions\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"MIT License\"></a>\n  <a href=\"https://github.com/Hylouis233/bibverify/actions/workflows/ci.yml\"><img src=\"https://github.com/Hylouis233/bibverify/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n</p>\n\nBibverify is a BibTeX metadata verification tool for researchers, editors, automation, and AI assistants. It starts with exact DOI, PMID, PMCID, or arXiv identifiers and then scores candidates from title, author, year, venue, and pagination evidence.\n\nBibverify evaluates whether a bibliographic record can be located in the queried sources and whether its metadata agrees. It does not prove that research findings are true, data is authentic, or a venue is reputable. A missing database record is not evidence that a reference is fabricated. By default, the source `.bib` file is never overwritten.\n\n## Highlights\n\n- Identifier-first lookup for DOI, PMID, PMCID, and arXiv IDs.\n- Crossref, OpenAlex, Semantic Scholar, PubMed, Europe PMC, CORE, DBLP, arXiv, bioRxiv, and more.\n- Explainable multi-signal matching across identifiers, title, authors, year, venue, and pages. A resolvable DOI with a materially different title becomes `identifier_conflict` instead of being hidden by title search.\n- Structured provider outcomes distinguish a genuine no-match from rate limiting, authentication, network, parsing, and provider failures.\n- Non-destructive merging preserves `abstract`, `keywords`, `file`, `note`, and custom fields that providers do not return; conflicting persistent identifiers are never overwritten automatically.\n- A shared connection pool with retries, exponential backoff, and `Retry-After` support for `429/5xx` responses.\n- An expiring SQLite cache for successful GET responses; failures are never cached.\n- Cross-platform path, encoding, Unicode filename, UTF-8 BOM, and CRLF handling.\n- JSON output, stable exit codes, a Python API, and an MCP server built on the official SDK.\n- Atomic output writes and byte-preserving backups.\n\n## Requirements\n\n- Windows, macOS, or Linux\n- Network access to the enabled metadata APIs\n- Python 3.11–3.14 when using the Python distribution; npm, containers, and native packages bundle their runtime\n\nGitHub Actions tests all three operating systems across all four supported Python versions.\n\n## Install\n\nThe current published release is v0.3.0. This branch prepares v0.4.0; commands marked **v0.4.0**\nbecome usable only after their linked npm, GHCR, or GitHub Release artifact has been published.\n\nRun without a permanent installation:\n\n```bash\nuvx bibverify --version\n```\n\nStarting with v0.4.0, Node.js users can use the zero-dependency npm launcher. It downloads the\nmatching native release, verifies `SHA256SUMS`, and forwards every argument and exit code:\n\n```bash\nnpx --yes @hylouis233/bibverify --version\npnpm dlx @hylouis233/bibverify --version\nbunx --bun @hylouis233/bibverify --version\n```\n\nFor a persistent CLI in an isolated Python environment, use `uv tool` or `pipx`:\n\n```bash\nuv tool install bibverify\n```\n\n```bash\npipx install bibverify\n```\n\nInside a virtual environment, regular pip also works:\n\n```bash\npython -m pip install --upgrade bibverify\n```\n\nEach release also provides smoke-tested native packages on\n[GitHub Releases](https://github.com/Hylouis233/bibverify/releases). Beginning with v0.4.0, the\nrelease matrix covers Windows x64 plus macOS and glibc 2.28+ Linux on both x64 and ARM64. musl-based\nLinux users should use the Python package or container image. Windows ARM64 is not published natively\nyet because an MCP runtime dependency does not currently provide Windows ARM64 wheels; npm\nautomatically uses the tested x64 build under Windows 11 emulation, or you can use the ARM64 container\ninstead.\n\nThe same release publishes a multi-architecture container:\n\n```bash\ndocker run --rm ghcr.io/hylouis233/bibverify:0.4.0 --version\n```\n\nPackage-manager manifests are generated from the final release bytes, not from unverified build\ninputs. Homebrew, Scoop, and WinGet are not live catalog entries yet: v0.4.0 will attach submission-\nready manifests to GitHub Release, after which each external catalog still requires onboarding or\nreview. See [Distribution channels](#distribution-channels) for rollout status.\n\n## Quick start\n\n### Convert a DOI to BibTeX\n\n```bash\nbibverify doi 10.1038/nature12373 --key example2013\n```\n\nFor a machine-readable response:\n\n```bash\nbibverify doi 10.1038/nature12373 --json\n```\n\n### Verify a `.bib` file\n\nCreate a starter configuration:\n\n```bash\nbibverify config init\n```\n\nPlace `references.bib` next to the configuration and run:\n\n```bash\nbibverify check --config config.json\n```\n\nYou can override the input and output paths from the command line:\n\n```bash\nbibverify check references.bib --config config.json --output-dir bibverify-output\n```\n\nInspect results without writing any file:\n\n```bash\nbibverify check references.bib --dry-run --json\n```\n\nAfter reviewing the report, explicitly apply high-confidence field updates. Bibverify creates a byte-for-byte backup first:\n\n```bash\nbibverify check references.bib --apply\n```\n\nPowerShell example:\n\n```powershell\npy -m bibverify check '.\\Bibliography\\references.bib' --output-dir '.\\Verification results'\n```\n\nThe v0.2 forms remain available for compatibility, although new scripts should use subcommands:\n\n```bash\nbibverify config.json\nbibverify --doi 10.1038/nature12373 --key example2013\n```\n\n## Configuration\n\nA minimal configuration looks like this:\n\n```json\n{\n  \"language\": \"EN\",\n  \"bib_file\": \"references.bib\",\n  \"encoding\": \"auto\",\n  \"output_dir\": \"bibverify-output\",\n  \"user_info\": {\n    \"email\": \"your_email@example.com\",\n    \"app_name\": \"Bibverify\"\n  }\n}\n```\n\nSee [`config_template.json`](config_template.json) for every commonly used option.\n\nPath behavior is intentionally predictable:\n\n- Relative `bib_file` and `output_dir` values are resolved from the directory containing `config.json`, not the shell's current directory.\n- If `output_dir` is omitted, output is written next to the input bibliography.\n- `encoding: \"auto\"` tries UTF-8 with BOM, UTF-8, and GB18030. It does not fall back to Latin-1 and silently turn unknown bytes into mojibake.\n\n### API keys and email\n\nKeys can be stored in a local configuration, but environment variables are safer and harder to commit accidentally:\n\n| Environment variable | Used for |\n|---|---|\n| `BIBVERIFY_EMAIL` | Crossref polite pool and contact information |\n| `BIBVERIFY_OPENALEX_API_KEY` | OpenAlex |\n| `BIBVERIFY_SEMANTIC_SCHOLAR_API_KEY` | Semantic Scholar |\n| `BIBVERIFY_PUBMED_API_KEY` | PubMed/NCBI |\n| `BIBVERIFY_CORE_API_KEY` | CORE |\n\nPowerShell:\n\n```powershell\n$env:BIBVERIFY_EMAIL = 'you@example.com'\n$env:BIBVERIFY_OPENALEX_API_KEY = '...'\nbibverify check --config config.json\n```\n\nBash or Zsh:\n\n```bash\nexport BIBVERIFY_EMAIL='you@example.com'\nexport BIBVERIFY_OPENALEX_API_KEY='...'\nbibverify check --config config.json\n```\n\n### Query and matching settings\n\n```json\n{\n  \"query_settings\": {\n    \"delay_between_requests\": 0.5,\n    \"timeout\": 10,\n    \"connect_timeout\": 3.05,\n    \"read_timeout\": 20,\n    \"max_retries\": 3,\n    \"backoff_factor\": 0.5,\n    \"stop_on_first_match\": true,\n    \"match_threshold\": 0.86,\n    \"ambiguous_threshold\": 0.68,\n    \"auto_update_threshold\": 0.92,\n    \"cache_enabled\": true,\n    \"cache_ttl_hours\": 168,\n    \"cache_path\": \".bibverify-cache.sqlite3\"\n  }\n}\n```\n\n`connect_timeout` and `read_timeout` separately bound connection setup and response reads; the compatibility `timeout` field remains available. `match_threshold` controls automatic candidate acceptance, `ambiguous_threshold` controls which plausible candidates enter review, and `auto_update_threshold` is an additional gate for field changes. Higher values are more conservative. Relative cache paths are resolved from the config directory.\n\nThe official bioRxiv `details` route does not provide arbitrary title search. Bibverify therefore calls bioRxiv only for an exact `10.1101/...` DOI and leaves title-only discovery to providers whose contracts support it, such as Crossref and Europe PMC.\n\n## CLI reference\n\n```text\nbibverify check [BIB_FILE] [--config PATH] [--output-dir DIR] [--format txt|json|jsonl|csv] [--dry-run|--apply] [--json]\nbibverify doi DOI [--key KEY] [--config PATH] [--json]\nbibverify config init [--output PATH] [--force]\nbibverify doctor [--config PATH] [--json]\nbibverify providers list [--json]\nbibverify cache clear [--config PATH]\nbibverify benchmark [--dataset PATH]\nbibverify mcp [--config PATH] [--workspace-root DIR] [--transport stdio|streamable-http]\nbibverify agent init [--target generic|codex|claude|cursor] [--output PATH]\nbibverify skill export [--target ...]\n```\n\nExit codes:\n\n| Code | Meaning |\n|---:|---|\n| `0` | Verification completed and metadata is consistent |\n| `1` | Runtime error reserved for uncategorized command failures |\n| `2` | Metadata differences or high-confidence updates exist |\n| `3` | Ambiguous, not-found, or identifier-conflict entries require review |\n| `4` | A provider was unavailable and verification is incomplete |\n| `5` | The input file, configuration, or entry is invalid |\n\nWith `--json`, stdout contains JSON only. Diagnostics go to stderr, which keeps the command safe for CI and scripts.\n\n## Output files\n\nFor an input named `references.bib`, Bibverify may create:\n\n- `bibverify_report_<timestamp>.<format>`: complete states, candidates, provider errors, confidence, and field provenance in `txt`, `json`, `jsonl`, or `csv`.\n- `references_backup_<timestamp>.bib`: byte-for-byte copy of the source.\n- `references_updated_<timestamp>.bib`: complete bibliography after non-destructive merging; omitted when nothing changes.\n- `references_review_<timestamp>.bib`: ambiguous, not-found, unavailable-source, identifier-conflict, or invalid entries; omitted when nothing needs review.\n\nThe report-level `complete` value is true only when every entry completed verification. A rate-limited or unreachable provider makes it false even if another source found a candidate. Each `field_diffs` record includes original/suggested values, source, confidence, normalized equivalence, action, and reason.\n\nEach output can be disabled independently through `output_settings`. `--dry-run` overrides those settings and performs zero writes. The default command only writes proposals; only `--apply` changes the source after a backup.\n\n## Provider ranking\n\nStatic priority is only the starting point:\n\n1. A DOI promotes Crossref and uses its exact endpoint first. A resolvable DOI with a materially different title stops as `identifier_conflict`.\n2. PMID, PMCID, or biomedical hints promote PubMed and Europe PMC.\n3. An arXiv identifier promotes arXiv.\n4. Computer-science venue hints promote DBLP.\n\nUnpaywall is currently treated as open-access enrichment, not as a primary bibliographic metadata provider. Provider states distinguish `matched`, `no_match`, `ambiguous`, `rate_limited`, `auth_error`, `network_error`, `parse_error`, `provider_error`, and `skipped`.\n\n## MCP and AI assistants\n\nBibverify uses the official MCP Python SDK and supports local stdio and Streamable HTTP transports.\n\nStart a stdio server:\n\n```bash\nbibverify mcp --config config.json --workspace-root .\n```\n\nMCP client configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"bibverify\": {\n      \"command\": \"bibverify\",\n      \"args\": [\"mcp\", \"--config\", \"config.json\"]\n    }\n  }\n}\n```\n\nThe npm launcher can be used directly by Node-oriented MCP clients:\n\n```json\n{\n  \"mcpServers\": {\n    \"bibverify\": {\n      \"command\": \"npx\",\n      \"args\": [\"--yes\", \"@hylouis233/bibverify\", \"mcp\"]\n    }\n  }\n}\n```\n\nContainerized stdio MCP keeps the current directory as the only writable workspace:\n\n```bash\ndocker run --rm -i -v \"$PWD:/workspace\" ghcr.io/hylouis233/bibverify:0.4.0 \\\n  mcp --workspace-root /workspace\n```\n\nStart Streamable HTTP:\n\n```bash\nbibverify mcp --transport streamable-http --config config.json\n```\n\nMCP treats the configuration directory as its workspace root by default. It rejects config or `.bib` reads outside that root and blocks report, cache, or update writes outside it. Broaden access only by explicitly setting `--workspace-root` when starting the server. The official MCP SDK handles protocol negotiation, schemas, structured results, progress, and cancellation.\n\nAvailable tools:\n\n- `doi_to_bibtex`\n- `rank_lookup_sources`\n- `explain_update_diff`\n- `verify_bib_file`\n\nGenerate setup files for Codex, Claude, Cursor, or a generic MCP client:\n\n```bash\nbibverify agent init --target codex --output .bibverify-agent --config config.json\nbibverify doctor --config config.json\n```\n\n## Distribution channels\n\n| Channel | Command or artifact | Availability |\n|---|---|---|\n| PyPI | `python -m pip install bibverify` | Published |\n| uv | `uvx bibverify` or `uv tool install bibverify` | Published |\n| pipx | `pipx install bibverify` | Published |\n| npm | `npx --yes @hylouis233/bibverify` | Planned for v0.4.0; not published yet |\n| pnpm / Bun | `pnpm dlx @hylouis233/bibverify` / `bunx --bun @hylouis233/bibverify` | Planned for v0.4.0; not published yet |\n| GHCR | `docker pull ghcr.io/hylouis233/bibverify:0.4.0` | Planned for v0.4.0; not published yet |\n| Native | Windows x64; macOS and glibc 2.28+ Linux x64/ARM64 | Planned for v0.4.0; not published yet |\n| Homebrew | Release asset `bibverify.rb` | Submission manifest planned for v0.4.0; catalog not live |\n| Scoop | Release asset `bibverify.json` | Submission manifest planned for v0.4.0; catalog not live |\n| WinGet | Release assets `Hylouis233.Bibverify*.yaml` | Submission manifests planned for v0.4.0; catalog not live |\n| MCP Registry | [`io.github.Hylouis233/bibverify`](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.Hylouis233%2Fbibverify/versions/latest) | Published discovery metadata; install through one of the package entries above |\n\nThe npm package is a small launcher rather than a second implementation. The verification engine\nremains the same Python codebase across PyPI, npm, native packages, and containers. Release assets\ninclude `SHA256SUMS`; npm verifies the selected binary before execution, and Homebrew, Scoop, and\nWinGet manifests pin the same release hashes.\n\n## Python API\n\n```python\nfrom bibverify.checker import BibTeXChecker\n\nchecker = BibTeXChecker(\"config.json\")\nsummary = checker.run()\nprint(summary[\"counts\"])\n```\n\n`from bib_check import BibTeXChecker` remains compatible during the 0.3 release line, but new code should use the package import above.\n\n## Development\n\n```bash\ngit clone https://github.com/Hylouis233/bibverify.git\ncd bibverify\npython -m venv .venv\n```\n\nAfter activating the environment:\n\n```bash\npython -m pip install -e \".[dev]\"\npython -m pytest\npython -m ruff check src tests tools bib_check.py\npython -m ruff format --check src tests tools bib_check.py\npython -m mypy\npython -m build\npython -m twine check dist/*\npython -m bibverify benchmark --dataset benchmarks/cases.json\npython -m pip_audit . --strict\n(cd npm && npm ci && npm test && npm pack --dry-run)\ndocker build --tag bibverify:dev .\n```\n\nCI tests Windows, macOS, and Linux on Python 3.11–3.14, including provider fixtures, golden write-safety tests, lint, typing, coverage, the offline benchmark, dependency auditing, Python and npm package builds, a container smoke test, and a CycloneDX SBOM. GitHub Actions are pinned to commit SHAs, while the MCP Publisher is version-pinned and SHA-256 verified. PyPI and npm use Trusted Publishing with provenance attestations, and GHCR publishes multi-architecture images with an SBOM and build provenance.\n\n`benchmarks/cases.json` is a small offline regression set covering short-title false positives, DOI conflicts, preprint title variants, Unicode/LaTeX, and fabricated author combinations. It is not a complete scientific evaluation and its scores must not be interpreted as real-world performance ceilings. Contributions of broader, redistributable, human-labeled cases are welcome.\n\n## Citation\n\nIf Bibverify supports your research, please cite:\n\n```bibtex\n@software{bibverify2025,\n  title = {Bibverify: A Multi-Platform BibTeX Reference Verification Tool},\n  author = {Hong Liu},\n  year = {2025},\n  url = {https://github.com/Hylouis233/bibverify},\n  doi = {10.5281/zenodo.17338090}\n}\n```\n\n## License\n\n[MIT License](LICENSE)\n",
  "bytes": 17007,
  "sha": "a53bf071c9f06ce04d4b4c5145d1ad7f9ee80fe695fb847e0856fc73316af1c7",
  "repo_slug": "hylouis233/bibverify",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_hylouis233_bibverify_554f5906/readme"
}