An open API service indexing awesome lists of open source software.

https://github.com/victortomaili/mendeley-cli

AI-agent-friendly CLI & JavaScript SDK for the Mendeley API
https://github.com/victortomaili/mendeley-cli

academic ai-agent bibtex citation cli mendeley nodejs oauth2 reference-manager scholar sdk

Last synced: 24 days ago
JSON representation

AI-agent-friendly CLI & JavaScript SDK for the Mendeley API

Awesome Lists containing this project

README

          

# ๐Ÿ”ฌ mendeley-cli

**AI-agent-friendly CLI & JavaScript SDK for the Mendeley API**

[![Node.js >= 22](https://img.shields.io/badge/node-%3E%3D22-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

_Query 100 M+ academic papers, manage your library, export BibTeX โ€” from the terminal._

[Getting started](#getting-started) ยท [CLI reference](#cli-reference) ยท [Library API](#library-api) ยท [AI agents](#built-for-ai-agents)

---

> [!IMPORTANT]
> **This is an unofficial, community-maintained project.**
> `mendeley-cli` is **not** affiliated with, endorsed by, or sponsored by
> Mendeley Ltd. or Elsevier. **Mendeley** and the Mendeley logo are trademarks
> of Mendeley Ltd. All trademarks are the property of their respective owners.
>
> By using this tool you confirm that you have read and accept the
> **[Mendeley Terms of Use](https://www.elsevier.com/legal/elsevier-mendeley-terms-and-conditions)**
> and the **[Elsevier Website Terms & Conditions](https://www.elsevier.com/legal/elsevier-website-terms-and-conditions)**.
> You are solely responsible for how you use this software and for complying
> with Mendeley's usage policies, rate limits, and applicable laws.
>
> Looking for the **official** resources?
>
> - Official website: **https://www.mendeley.com**
> - Official API docs: **https://dev.mendeley.com/**
> - Official Python SDK: **https://github.com/mendeley/mendeley-python-sdk**

---

## Why this exists

The official Mendeley SDK is Python-only and hasn't been updated in years. This project provides:

- **A shell CLI** (`mendeley`) that defaults to **text output** (LLM/human-friendly), with `--format json|tsv|ids` available for scripting and `jq`
- **A JavaScript library** (`import { Mendeley } from 'mendeley-cli'`) for Node.js 22+
- **Zero dependencies** (pure Node.js, no runtime deps)
- **PKCE auth** with automatic token refresh โ€” log in once, stay logged in
- **73 help pages** with examples, plus a `--skill` flag that dumps the full command surface as Markdown for LLM system prompts

## Getting started

```bash
# Install globally (recommended)
npm install -g mendeley-cli

# Or run directly from source
git clone https://github.com/VictorTomaili/mendeley-cli.git
cd mendeley-cli
npm install
npm link # makes 'mendeley' available system-wide
```

### Calling `mendeley` from another language (Python, etc.) on Windows

On Windows, `npm install -g` (or `pnpm add -g`) installs the
`mendeley` command as a **`mendeley.CMD`** shim. Windows'
`CreateProcess` (the native process launcher used by Python's
`subprocess.run`, Node's `child_process.spawn`, and most other
non-shell callers) does **not** auto-execute `.CMD` files โ€” only
the CMD shell does. As a result, a bare call like
`subprocess.run(["mendeley", "--version"])` fails with
`FileNotFoundError: [WinError 2]`, even though `mendeley --version`
works fine in any Windows terminal (#105).

**Fix โ€” pick one of these:**

```python
import subprocess, shutil

# Option A (recommended): resolve the full path to the .CMD shim
mendeley = shutil.which("mendeley.cmd") or shutil.which("mendeley")
subprocess.run([mendeley, "--version"])

# Option B: pass shell=True (works, but with quoting/security caveats)
subprocess.run(["mendeley", "--version"], shell=True)

# Option C: call node directly on the installed entry point
import subprocess, sys
node = sys.executable # or hard-code the Node.js path
# Find the installed bin/mendeley.js (adjust the global prefix path)
subprocess.run([node, r"C:\\Users\\me\\AppData\\Roaming\\npm\\node_modules\\mendeley-cli\\bin\\mendeley.js", "--version"])
```

In Node.js, the equivalent is `spawn(mendeleyPath, args, {shell: true})`
or resolving the `.cmd` path explicitly.

This only affects Windows and only non-shell callers. Linux and
macOS are unaffected (the shebang `#!/usr/bin/env node` is honoured).

### Configure credentials

Get your client ID at [dev.mendeley.com](https://dev.mendeley.com/):

```bash
mendeley auth set clientId YOUR_CLIENT_ID
mendeley auth set clientSecret YOUR_CLIENT_SECRET
mendeley auth set redirectUri http://localhost:11595
```

### Authenticate

The CLI does **not** open a browser or run a local callback server. It prints
the authorisation URL and prompts you to paste the redirect URL back after
logging in:

```bash
mendeley auth login
# 1. Open the printed URL in a browser and complete the Mendeley login
# 2. After approving, the browser redirects to http://localhost:โ€ฆ
# ("This site can't be reached" is normal โ€” the CLI isn't listening)
# 3. Copy the ENTIRE URL from the browser address bar
# 4. Paste it at the prompt
```

For headless servers / CI / AI agents, use the two-step flow instead:

```bash
mendeley auth url # prints a login URL + saves PKCE verifier
# ... visit URL in any browser, log in, copy the redirect URL ...
mendeley auth exchange "http://localhost:11595/?code=...&state=..."
```

### Verify

```bash
mendeley whoami
```

## CLI reference

Every command supports `--help` with full usage, options, and examples:

```bash
mendeley --help # top-level help
mendeley documents list --help # per-command help
mendeley --skill # full API as a skill document (for AI system prompts)
```

### Output formats

| Flag | Format | Use case |
| --------------------------- | ---------------------- | ------------------------- |
| `--format text` _(default)_ | Key-value | Quick reading, LLM use |
| `--format json` | JSON | AI agents, piping to `jq` |
| `--format tsv` | Tab-separated | Spreadsheet import |
| `--format ids` | Bare IDs, one per line | Piping to `xargs` |

### Commands

auth โ€” manage authentication

```
mendeley auth login # print URL, paste redirect URL back (no browser)
mendeley auth logout # delete saved token
mendeley auth status # show config (no secrets)
mendeley auth whoami # test token via /profiles/me
mendeley auth url # print login URL (headless step 1)
mendeley auth exchange # exchange code for token (headless step 2)
mendeley auth set # set clientId, clientSecret, redirectUri, host
mendeley auth unset # remove a credential
```

catalog โ€” browse the global Mendeley catalog (100 M+ papers)

```
mendeley catalog search "machine learning" --limit 10
mendeley catalog by-doi 10.1038/nature14539
mendeley catalog by-identifier --arxiv 1706.03762
mendeley catalog lookup --title "Attention is all you need"
mendeley catalog advanced-search --author Hinton --min-year 2017
mendeley catalog get
```

documents โ€” manage documents in your library

```
mendeley documents list --limit 50 --all
mendeley documents get
mendeley documents search "deep learning"
mendeley documents advanced-search --author LeCun --min-year 2018
mendeley documents create --title "My Paper" --type journal
mendeley documents create-from-file ./paper.pdf
mendeley documents update --data '{"title":"New Title"}'
mendeley documents delete
mendeley documents move-to-trash
mendeley documents attach-file ./supplement.pdf
mendeley documents add-note "important finding"
mendeley documents annotations
mendeley documents files
mendeley documents export-bibtex
```

library โ€” high-level library operations

```
mendeley library export-bibtex --out refs.bib
mendeley library export-json --out library.json
mendeley library dedupe --by doi
mendeley library stats
mendeley library recent --limit 5
mendeley library by-tag "to-read"
mendeley library add-by-doi 10.1038/nature14539
mendeley library add-by-arxiv 1706.03762
```

folders ยท groups ยท files ยท annotations ยท trash ยท profile

```
mendeley folders list --all
mendeley folders create "Reading List" --parent
mendeley folders documents
mendeley folders add-document

mendeley groups list
mendeley groups members
mendeley groups documents

mendeley files list --document
mendeley files download /tmp/papers

mendeley annotations list --document
mendeley annotations get
mendeley annotations update --data '{"text":"updated"}'
mendeley annotations delete

mendeley trash list
mendeley trash get
mendeley trash restore
mendeley trash delete --yes
mendeley trash empty --yes

mendeley profile me
mendeley profile get
```

## Library API

Use the SDK programmatically in any Node.js 22+ project:

```bash
npm install mendeley-cli
```

```js
import { Mendeley } from 'mendeley-cli';

const mendeley = new Mendeley({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'http://localhost:11595',
});

// Client-credentials flow (no user interaction)
const session = await mendeley.startClientCredentialsFlow().authenticate();

// Search the catalog
const results = await session.catalog.search('machine learning', { view: 'all' });
const page = await results.list({ pageSize: 10 });
console.log(`Found ${(await page.items).length} results`);

// Look up by DOI
const doc = await session.catalog.byIdentifier({ doi: '10.1038/nature14539' });
console.log(doc.title); // "Deep learning"
console.log(doc.year); // 2015
```

### Authorization-code flow with PKCE

```js
const flow = await mendeley.startAuthorizationCodeFlowAsync({ usePkce: true });
console.log('Visit:', flow.getLoginUrl());

// ... user completes login in browser ...
const session = await flow.authenticate(authorizationCode);
const me = await session.profiles.me;
console.log(`Hello, ${me.first_name}`);
```

## Built for AI agents

The CLI is designed as a **tool** that AI agents can call directly. Key design decisions:

1. **Text by default, JSON on demand** โ€” output defaults to LLM/human-friendly text; pass `--format json` for machine-parseable output
2. **`--skill` flag** โ€” prints the entire CLI surface as a Markdown document you can paste into a system prompt:

```bash
mendeley --skill > MENDELEY_SKILL.md
```

3. **Structured errors** โ€” errors are JSON objects with `ok: false` and a human-readable `error` field
4. **Headless auth** โ€” no browser is opened; the agent can run `mendeley auth login` to get a URL, or `mendeley auth url` + `mendeley auth exchange` for a two-step flow
5. **Every command documented** โ€” `--help` shows synopsis, description, options, arguments, and at least one example

### Example: AI agent workflow

```
Agent: I'll search the Mendeley catalog for papers about CRISPR.

$ mendeley catalog search "CRISPR gene editing" --limit 5 --format ids
> 436fcd07-37bf-36d8-9d86-3f073872c69d
> a105c9f1-b55f-382a-a4ce-90241d15ec77
> ...

Agent: Found 5 papers. Let me get details on the first one.

$ mendeley catalog get 436fcd07-37bf-36d8-9d86-3f073872c69d --format json
> { "title": "Current applications and future perspective of CRISPR/Cas9 ...", ... }

Agent: Would you like me to add this to your library?

$ mendeley library add-by-doi 10.1186/s12943-022-01518-8 --format json
> { "ok": true, "id": "...", "title": "..." }
```

## Environment variables

| Variable | Description |
| ------------------------ | ------------------------------------------------- |
| `MENDELEY_CLIENT_ID` | OAuth client ID (overrides credentials.json) |
| `MENDELEY_CLIENT_SECRET` | OAuth client secret |
| `MENDELEY_REDIRECT_URI` | OAuth redirect URI |
| `MENDELEY_HOST` | API base URL (default `https://api.mendeley.com`) |
| `MENDELEY_CONFIG` | Path to `credentials.json` |
| `MENDELEY_TOKEN_FILE` | Path to `token.json` |

## Development

```bash
git clone https://github.com/VictorTomaili/mendeley-cli.git
cd mendeley-cli
npm install
npm link # install global 'mendeley' command (symlink โ€” edits are live)

npm test # run the full test suite (unit + integration)
npm run test:unit
npm run test:integration
```

No build step โ€” this is plain ESM JavaScript targeting Node.js 22+.

### Project structure

```
bin/mendeley.js CLI entry point
lib/cli/ CLI framework (command parser, output, credentials)
commands/ One file per top-level subcommand
src/ JavaScript SDK
client.js Mendeley class โ€” entry point
session.js MendeleySession โ€” authenticated resource container
auth.js OAuth flow helpers (auth-code, client-credentials, PKCE)
resources/ REST resource classes
models/ JSON model classes with lazy fields
pagination.js Page iterator
response.js ResponseObject, LazyResponseObject
test/ unit + integration tests
```

## Security

Please **do not** file public GitHub issues for suspected vulnerabilities.
See [SECURITY.md](SECURITY.md) for the supported versions, how to report a
vulnerability privately, and our response timeline. Reports can be opened
via [GitHub Security Advisories](https://github.com/VictorTomaili/mendeley-cli/security/advisories/new)
or emailed to the maintainer.

## License

[Apache-2.0](LICENSE)

## Disclaimer

`mendeley-cli` is an **unofficial, community-maintained** project. It is **not**
affiliated with, endorsed by, or sponsored by **Mendeley Ltd.** or **Elsevier**.
**Mendeley** and the Mendeley logo are trademarks of Mendeley Ltd.; all other
trademarks are the property of their respective owners.

By installing or using this software you confirm that you have read and accept
the **[Mendeley Terms of Use](https://www.elsevier.com/legal/elsevier-mendeley-terms-and-conditions)**
and the **[Elsevier Website Terms & Conditions](https://www.elsevier.com/legal/elsevier-website-terms-and-conditions)**.
You are solely responsible for:

- complying with Mendeley's usage policies, acceptable-use rules, and rate limits;
- keeping your OAuth credentials, access tokens, and refresh tokens secure;
- ensuring your use of the API and any retrieved content complies with applicable
copyrights, licences, and laws.

The authors and contributors of this project provide the software **"as is"**
(see the Apache-2.0 licence) and accept **no responsibility or liability** for
any misuse, data loss, account suspension, or other consequence arising from
its use.

### Official resources

If you need vendor-supported tooling, please use the official resources:

- Official website: ****
- Official API documentation (Developer Portal): ****
- Official Python SDK: ****