# Personal Experience: Managing JabRef via JabKit + Claude Code

**URL:** <https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089>\
**Category:** Features\
**Created:** [May 3, 2026, 3:36am UTC](https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089 "2026-05-03T03:36:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hasibagen](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.jabref.org/hasibagen/32/2565_2.png) [@hasibagen](https://discourse.jabref.org/u/hasibagen)\
**Post date:** [May 3, 2026, 3:36am UTC](https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089/1 "2026-05-03T03:36:09Z")

</div>

JabKit + Claude Code

* * *

Please vote if you support this proposal:

_Poll ([view on site](https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089/1))_

> **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:

👉 Wrap it as a Claude Code skill (`/jabkit`)  
👉 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”.

👉 I’m especially looking forward to **more capabilities being added to JabKit in the future**

* * *

## System Environment

```auto
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

### ✅ Step 1: Install JBang

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

```

Key points:

- Installs **Temurin JDK 17 automatically**

- JDKs are cached in:

After setup, I had:

- System JDK 21

- JBang JDK 17

- JabKit-required JDK 25

They coexist without issues.

* * *

### ⚠ Step 1.5: PATH Configuration (Important)

Add to `~/.bashrc`:

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

```

Otherwise:

👉 Claude Code’s non-interactive shell won’t find `jbang`

* * *

### ✅ Step 2: Install JabKit (Reliable Method)

```auto
jbang app install --java 25 jabkit@jabref

```

What happens:

- Downloads **JDK 25** (required by JabKit)

- Installs CLI at:

Wrapper:

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

```

* * *

### ❌ Step 3: What Didn’t Work — `npx`

I tried:

```auto
npx @jbangdev/jbang jabkit@jabref

```

Result: **failed**

Likely reasons:

- Java version requirement not properly forwarded

- JDK resolution conflict

👉 Conclusion:  
**Use JBang directly, not npx**

* * *

### 🔄 Step 4: Updating JabKit

Since it’s a SNAPSHOT build:

```auto
jbang --fresh jabkit@jabref --help

```

Or:

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

```

* * *

## Claude Code Skill Setup

Location:

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

```

* * *

### Skill Metadata

```auto
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

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

```

* * *

### 2. Add via PDF

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

```

* * *

### 3. Batch Import Example

```auto
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:

- ✅ 5 papers added

- ⚠ 3 skipped (duplicate DOI)

- ❌ 0 failures

* * *

### 4. Quality Checks

```auto
jabkit check-integrity
jabkit check-consistency

```

* * *

### 5. Citation Tracing

```auto
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?”

👉 Everything runs through natural language + the skill

* * *

## Insights from JabRef Source Code

While building this, I checked `jabref-main`:

- All 12 commands live in:

- External changes are detected via `DatabaseChangeMonitor`

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

* * *

## Known Issues

### ⚠ External Change Notifications

When JabKit modifies `.bib` while JabRef is open:

> “The library has been modified by another program”

Current state:

- ❌ Cannot disable

- ❌ No auto-accept option

**Workaround:**

👉 Close the library before running batch operations

* * *

### ⚠ File Path Handling

After importing:

- `file` fields contain absolute paths

- “Copy linked files”:

👉 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.

---

<div class="post-metadata">

**Author:** ![hasibagen](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.jabref.org/hasibagen/32/2565_2.png) [@hasibagen](https://discourse.jabref.org/u/hasibagen)\
**Post date:** [May 3, 2026, 5:12am UTC](https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089/2 "2026-05-03T05:12:19Z")

</div>

Appendix: JabKit Skill for Claude Code

````auto

***

# 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.

````

---

<div class="post-metadata">

**Author:** ![Siedlerchr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.jabref.org/siedlerchr/32/216_2.png) [@Siedlerchr](https://discourse.jabref.org/u/Siedlerchr)\
**Post date:** [May 3, 2026, 5:34pm UTC](https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089/3 "2026-05-03T17:34:13Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![koppor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.jabref.org/koppor/32/5_2.png) [@koppor](https://discourse.jabref.org/u/koppor)\
**Post date:** [May 3, 2026, 6:03pm UTC](https://discourse.jabref.org/t/personal-experience-managing-jabref-via-jabkit-claude-code/9089/4 "2026-05-03T18:03:06Z")

</div>

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

> [@hasibagen](#):
>
> Many rough edges remain (especially around GUI sync and file handling)

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.
