Personal Experience: Managing JabRef via JabKit + Claude Code

JabKit + Claude Code


Please vote if you support this proposal:

  • I would like to have this feature, too!
  • I don’t care.
0 voters

TL;DR — I wrapped JabKit (JabRef’s CLI toolkit) as a Claude Code skill and now manage my entire .bib library through natural language. This post documents what worked, what didn’t, and how to reproduce the setup.


Background

I’m a cognitive neuroscience researcher (RSA / fNIRS / EEG), using JabRef to manage a growing bibliography.

My typical pain points:

  • Importing PDFs from scattered Zotero-style directories

  • Cleaning metadata and deduplication

  • Searching and maintaining .bib files

  • Repetitive manual workflows

After discovering JabKit, I decided to experiment with a different approach:

:backhand_index_pointing_right: Wrap it as a Claude Code skill (/jabkit)
:backhand_index_pointing_right: Drive the entire bibliography workflow via natural language


A Quick Disclaimer

I’m not a professional developer—this setup is a personal experiment built out of curiosity.

  • I’m very interested in seeing official improvements to JabKit and JabRef workflows

  • I’d love to see more people explore this direction together

  • Tools like OpenCode / OpenClaw seem to follow a similar philosophy, so there’s clearly a broader pattern here

This is just one possible implementation, not a “best practice”.

:backhand_index_pointing_right: I’m especially looking forward to more capabilities being added to JabKit in the future


System Environment

OS: Ubuntu 24.04.4 LTS
Java: OpenJDK 21 (apt)
JabRef GUI: 5.15
JabKit: 6.0-alpha.341
Node.js: installed (for npx testing)
Shell: bash


Installation: What Worked vs What Didn’t

:white_check_mark: Step 1: Install JBang

curl -Ls https://sh.jbang.dev | bash -s - app setup

Key points:

  • Installs Temurin JDK 17 automatically

  • JDKs are cached in:

    ~/.jbang/cache/jdks/
    
    

After setup, I had:

  • System JDK 21

  • JBang JDK 17

  • JabKit-required JDK 25

They coexist without issues.


:warning: Step 1.5: PATH Configuration (Important)

Add to ~/.bashrc:

export PATH="$HOME/.jbang/bin:$HOME/.jbang/currentjdk/bin:$PATH"
export JAVA_HOME=$HOME/.jbang/currentjdk
alias j!=jbang

Otherwise:

:backhand_index_pointing_right: Claude Code’s non-interactive shell won’t find jbang


:white_check_mark: Step 2: Install JabKit (Reliable Method)

jbang app install --java 25 jabkit@jabref

What happens:

  • Downloads JDK 25 (required by JabKit)

  • Installs CLI at:

    ~/.jbang/bin/jabkit
    
    

Wrapper:

exec jbang run --java 25 jabkit@jabref "$@"


:cross_mark: Step 3: What Didn’t Work — npx

I tried:

npx @jbangdev/jbang jabkit@jabref

Result: failed

Likely reasons:

  • Java version requirement not properly forwarded

  • JDK resolution conflict

:backhand_index_pointing_right: Conclusion:
Use JBang directly, not npx


:counterclockwise_arrows_button: Step 4: Updating JabKit

Since it’s a SNAPSHOT build:

jbang --fresh jabkit@jabref --help

Or:

jbang app install --fresh --force jabkit@jabref


Claude Code Skill Setup

Location:

~/.claude/skills/jabkit/SKILL.md


Skill Metadata

Environment:
- JBang: ~/.jbang/bin/jbang
- JabKit: ~/.jbang/bin/jabkit
- PATH must include ~/.jbang/bin


Commands Covered

Category Commands
Literature collection doi-to-bibtex, convert, fetch
Library management search, citationkeys generate
PDF management pdf update
Quality checks check-integrity, check-consistency
Citation network get-citing-works, get-cited-works
Preferences preferences

Core Workflows

1. Add via DOI

jabkit doi-to-bibtex <DOI> >> library.bib


2. Add via PDF

jabkit convert \
  --input=<pdf> \
  --input-format=pdfMerged \
  --output=/tmp/entry.bib \
  --output-format=bibtex


3. Batch Import Example

import subprocess

for pdf in find_pdfs(pdf_dir):
    subprocess.run([
        "jabkit", "convert",
        "--input", pdf,
        "--input-format", "pdfMerged",
        "--output", out_file,
        "--output-format", "bibtex"
    ])

Results:

  • :white_check_mark: 5 papers added

  • :warning: 3 skipped (duplicate DOI)

  • :cross_mark: 0 failures


4. Quality Checks

jabkit check-integrity
jabkit check-consistency


5. Citation Tracing

jabkit get-citing-works
jabkit get-cited-works


What Changed (Before vs After)

Before

  • Manual DOI lookup → copy → paste

  • Painful batch workflows

  • No structured quality checks

  • Limited citation tracing


After

I can just say:

  • “Add this PDF to my library”

  • “Find all papers by Zhai”

  • “Check my library quality”

  • “What cites this paper?”

:backhand_index_pointing_right: Everything runs through natural language + the skill


Insights from JabRef Source Code

While building this, I checked jabref-main:

  • All 12 commands live in:

    jabkit/src/main/java/org/jabref/toolkit/commands/
    
    
  • External changes are detected via DatabaseChangeMonitor

  • There is currently no option to auto-accept external changes


Known Issues

:warning: External Change Notifications

When JabKit modifies .bib while JabRef is open:

“The library has been modified by another program”

Current state:

  • :cross_mark: Cannot disable

  • :cross_mark: No auto-accept option

Workaround:

:backhand_index_pointing_right: Close the library before running batch operations


:warning: File Path Handling

After importing:

  • file fields contain absolute paths

  • “Copy linked files”:

    • copies files

    • does not always update links

:backhand_index_pointing_right: I’ve opened a separate Discourse issue for this


Practical Tips

  1. Use JBang, not npx

  2. Always specify --java 25

  3. Ensure PATH is set in .bashrc

  4. Use --fresh regularly

  5. Close JabRef GUI before batch operations


References

  • JabKit Documentation

  • JBang Documentation

  • JabRef GitHub

  • JabKit Source Code


Final Thoughts

This workflow significantly reduces friction in managing a .bib library, especially for batch operations and metadata handling.

That said, this is still an early-stage, experimental setup.

  • There’s clear potential for tighter integration

  • Many rough edges remain (especially around GUI sync and file handling)

  • A more official workflow could make this much more accessible

If others are experimenting with similar setups (Claude Code, OpenCode, OpenClaw, etc.), I’d be very interested to hear how you approached it.

Appendix: JabKit Skill for Claude Code



***

# JabKit — JabRef CLI Toolkit for Claude Code

Run the JabRef CLI toolkit via JBang to support reference management, format conversion, PDF metadata extraction, DOI queries, citation networks, and more.

## Environment

- **JBang path:** `~/.jbang/bin/jbang`
- **JabKit path:** `~/.jbang/bin/jabkit` (Requires `export PATH="$HOME/.jbang/bin:$PATH"` first)
- **Java:** Temurin JDK 25 (Auto-managed by JBang, cached at `~/.jbang/cache/jdks/25`)
- **Version:** 6.0-alpha.341 (SNAPSHOT development build)

## Prerequisites

You must set the PATH before calling JabKit:

```bash
export PATH="$HOME/.jbang/bin:$PATH"
```

To update JabKit: `jbang app install --fresh --force jabkit@jabref`

## Command Cheat Sheet

### 1. doi-to-bibtex — Convert DOI to BibTeX

```bash
jabkit doi-to-bibtex <DOI> [<DOI>...]
```

- Fetches complete metadata via the CrossRef API.
- Supports batch DOI processing.
- Outputs to stdout (in BibTeX format).
- **Usage:** Call this when adding new references to the library.

### 2. convert — Format Conversion

```bash
jabkit convert --input=<file> --input-format=<fmt> --output=<file> --output-format=<fmt>
```

**Key Input Formats:**
- `bibtex` — BibTeX file
- `pdfMerged` — PDF (extracts entry from PDF metadata, supports auto DOI matching)
- `pdfGrobid` — PDF (parsed via GROBID)
- `ris` — RIS format
- `medline` — Medline/PubMed
- `endnote` — EndNote

**Key Output Formats:**
- `bibtex` — BibTeX (Default)
- `ris` — RIS format
- `html` — HTML page
- `title-md` — Markdown titles
- `yaml` — CSL YAML
- `pdf` — Writes BibTeX metadata into the PDF's XMP
- `bib` — Embeds BibTeX into the PDF

**Special Usage — Extracting Metadata from PDF:**
```bash
jabkit convert --input=<path_to_pdf> --input-format=pdfMerged --output=<out.bib> --output-format=bibtex
```

**Output to stdout instead of a file:**
```bash
jabkit convert --input=<file> --input-format=pdfMerged --output-format=ris
```

**Field Formatting:** `--field-formatters=<formatter>`

### 3. search — Library Search

```bash
jabkit search --query="<query>" --input=<bib_file> [--output=<out.bib>] [--output-format=<fmt>]
```

- Uses JabRef's built-in search engine (supports advanced search syntax).
- **Search syntax example:** `(author=bock or title|keywords="computer methods") and not(author=sager)`
- **Time range:** `Year=1989-2005`
- Defaults to BibTeX output, but other formats can be specified.

### 4. fetch — Online Database Search

```bash
jabkit fetch --provider=<ProviderName> --query="<search term>" [--output=<out.bib>]
```

**Available Providers:** CrossRef, Google Scholar, Medline PubMed, MathSciNet, Springer, arXiv, CiteSeer, IEEEXplore, INSPIRE-HEP, zbMATH, etc.

### 5. pdf update — Write PDF Metadata

```bash
jabkit pdf update --input=<bib_file> --input-format=bibtex -k <citationKey> --format=xmp,bibtex-attachment [--update-linked-files]
```

- Writes metadata from the library directly into the PDF files.
- `--format`: `xmp` (XMP metadata), `bibtex-attachment` (Embeds BibTeX).
- `-k all` applies the update to all entries.
- **Note:** Requires the entries in the library to already have linked PDF paths.

### 6. check-integrity — Integrity Check

```bash
jabkit check-integrity --input=<bib_file> [--output-format=errorformat|txt|csv] [--allow-integer-edition]
```

- Checks entry field types, DOI formats, author names, etc.
- **Returns:** 0 = Normal, Non-zero = Issues found.

### 7. check-consistency — Consistency Check

```bash
jabkit check-consistency --input=<bib_file> [--output-format=txt|csv]
```

- Checks for field consistency among similar entries.
- **Returns:** 0 = Consistent, 1 = Inconsistencies found.

### 8. citationkeys generate — Generate Citation Keys

```bash
jabkit citationkeys generate --input=<bib_file> [--output=<out.bib>] [--pattern=<pattern>] [--transliterate] [--avoid-overwrite]
```

- Automatically generates keys for entries missing a citation key.
- `--pattern`: Custom pattern (e.g., `[auth][year]`).
- `--transliterate`: Transliterates non-ASCII characters.
- `--avoid-overwrite`: Prevents overwriting existing keys.

### 9. generate-bib-from-aux — Generate Sub-library from .aux File

```bash
jabkit generate-bib-from-aux --aux=<aux_file> --input=<bib_file> [--output=<out.bib>]
```

- Extracts a subset of cited references from a `.aux` file generated by LaTeX compilation.
- Ideal for generating a minimal `.bib` file for paper submissions.

### 10. get-cited-works / get-citing-works — Citation Network

```bash
jabkit get-cited-works <DOI> [--provider=OpenCitations|CrossRef|OpenAlex|SemanticScholar|All]
jabkit get-citing-works <DOI> [--provider=OpenCitations|CrossRef|OpenAlex|SemanticScholar|All]
```

- `get-cited-works`: What papers this document cites (reference list).
- `get-citing-works`: What papers cite this document (cited by).
- **Default provider:** OpenCitations.

### 11. pseudonymize — Pseudonymization

```bash
jabkit pseudonymize --input=<bib_file> [--output=<out.bib>] [--key=<keys.csv>] [-f]
```

- Generates an anonymized version of the library, perfect for data sharing.
- Automatically creates `.pseudo.bib` and `.pseudo.csv` (key mapping table).

### 12. preferences — Preferences Management

```bash
jabkit preferences reset          # Reset to default
jabkit preferences import <file>  # Import from a file
jabkit preferences export <file>  # Export to a file
```

## Typical Workflows

### Add New Reference (via DOI)
```bash
jabkit doi-to-bibtex 10.1016/j.cognition.2024.105951 >> library.bib
```

### Add New Reference (via PDF)
```bash
jabkit convert --input=<pdf> --input-format=pdfMerged --output=/tmp/entry.bib --output-format=bibtex
cat /tmp/entry.bib >> library.bib
```

### Add New Reference (via Online Fetch)
```bash
jabkit fetch --provider=CrossRef --query="machine learning nature" --output=/tmp/fetch.bib
```

### Batch Write PDF Metadata
```bash
jabkit pdf update --input=library.bib --input-format=bibtex -k all --format=xmp,bibtex-attachment --update-linked-files
```

### Library Quality Check
```bash
jabkit check-integrity --input=library.bib --output-format=csv
jabkit check-consistency --input=library.bib --output-format=txt
```

### Search and Export Subset
```bash
jabkit search --query="author=Zhai" --input=library.bib --output=zhai_papers.bib
```

### Citation Tracing
```bash
jabkit get-citing-works 10.1093/cercor/bhad116
jabkit get-cited-works 10.1093/cercor/bhad116
```

## Notes

1. **SNAPSHOT Version:** Because JabKit uses `6.0-SNAPSHOT`, JBang may require the `--fresh` flag to pull the latest dependencies.
2. **DBus Warning:** It is completely normal to see a `Using transport dbus-java-transport-native-unixsocket` warning printed during startup.
3. **File Paths:** Always use absolute paths. Paths with non-English characters (e.g., Chinese) have been tested and work perfectly.
4. **Log Output:** `stderr` contains INFO/DEBUG log lines, while `stdout` contains the actual output data—ensure you separate them when processing programmatically.
5. **Format Guessing:** If `--input-format` is omitted or set to `*`, the format will be automatically detected.

Thanks a lot this is really cool I guess @koppor will be happy about this as well :slight_smile:

Thank you so much for diving into this. This is one of the reasons why we worked on JabKit. Stilll in early stages, but ready to be expanded

This is really a tough topic. We think on this back and forth.

Current options, I see:

  1. Switch from JabKit to JabSrv - this is an HTTP interface for JabRef. If JabRef is online, each modification is already visible in the GUI. If JabRef is offline, JabSrv works on the file system. - Disclaimer: There is currently no auto switch between standalone http server and JabGui - needs to be implemetned
  2. Refine JabKit to route commands to JabGui if JabGui is online. - Background: We wanted to have JabKit very seperate from JabGui to have a small binary executable also usable in some non-UI environments (cloud backends etc). But we also see that users like to use this as interface to the JabGui. Not sure how we continue here.