Awesome-Agent-Skills-for-Empirical-Research mendeley-api
Manage references and search Mendeley's catalog via REST API
install
source · Clone the upstream repo
git clone https://github.com/brycewang-stanford/Awesome-Agent-Skills-for-Empirical-Research
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/brycewang-stanford/Awesome-Agent-Skills-for-Empirical-Research "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/43-wentorai-research-plugins/skills/writing/citation/mendeley-api" ~/.claude/skills/brycewang-stanford-awesome-agent-skills-for-empirical-research-mendeley-api && rm -rf "$T"
manifest:
skills/43-wentorai-research-plugins/skills/writing/citation/mendeley-api/SKILL.mdsource content
Mendeley REST API
Overview
Mendeley provides a reference management platform with a REST API for programmatic access to personal libraries, group collections, and the Mendeley Catalog — a crowdsourced database of 200M+ academic documents. The API supports OAuth 2.0 authentication, CRUD operations on documents/folders/annotations, and catalog search with rich metadata. Free tier available with registration.
Authentication
Mendeley uses OAuth 2.0 with client credentials or authorization code flow.
# 1. Register app at https://dev.elsevier.com/ # 2. Get access token via client credentials (for catalog search) curl -X POST "https://api.mendeley.com/oauth/token" \ -d "grant_type=client_credentials" \ -d "scope=all" \ -d "client_id=$MENDELEY_CLIENT_ID" \ -d "client_secret=$MENDELEY_CLIENT_SECRET" # Response: { "access_token": "...", "expires_in": 3600, "token_type": "bearer" }
API Endpoints
Base URL
https://api.mendeley.com
Catalog Search
Search across Mendeley's 200M+ document database:
# Search by title/keywords curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/catalog?query=deep+learning+NLP&limit=20" # Search by DOI curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/catalog?doi=10.1038/nature14539" # Search by title curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/catalog?title=attention+is+all+you+need"
User Library
# List documents in personal library curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/documents?limit=50&sort=created&order=desc" # Get document details curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/documents/{doc_id}" # Add document to library curl -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/vnd.mendeley-document.1+json" \ -d '{"title":"My Paper","type":"journal","year":2025,"authors":[{"first_name":"A","last_name":"B"}]}' \ "https://api.mendeley.com/documents"
Folders and Groups
# List folders curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/folders" # List group documents curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/documents?group_id={group_id}"
Annotations
# Get annotations for a document curl -H "Authorization: Bearer $TOKEN" \ "https://api.mendeley.com/annotations?document_id={doc_id}"
Query Parameters
| Parameter | Description | Example |
|---|---|---|
| Free-text search | |
| DOI lookup | |
| Title search | |
| Author filter | |
| From year | |
| To year | |
| Results per page (max 500) | |
| Sort field | , , |
| Sort direction | or |
| Response detail | (bibliographic), (reader counts) |
Catalog Response
{ "id": "abc123-...", "title": "Attention Is All You Need", "type": "conference_proceedings", "year": 2017, "authors": [ {"first_name": "Ashish", "last_name": "Vaswani"} ], "source": "NeurIPS", "identifiers": { "doi": "10.5555/3295222.3295349", "arxiv": "1706.03762" }, "keywords": ["attention mechanism", "transformer"], "abstract": "The dominant sequence transduction models...", "reader_count": 15432, "link": "https://www.mendeley.com/catalogue/..." }
Python Usage
import os import requests CLIENT_ID = os.environ["MENDELEY_CLIENT_ID"] CLIENT_SECRET = os.environ["MENDELEY_CLIENT_SECRET"] TOKEN_URL = "https://api.mendeley.com/oauth/token" BASE_URL = "https://api.mendeley.com" def get_token() -> str: """Obtain access token via client credentials.""" resp = requests.post(TOKEN_URL, data={ "grant_type": "client_credentials", "scope": "all", "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, }) resp.raise_for_status() return resp.json()["access_token"] def search_catalog(query: str, limit: int = 20, min_year: int = None) -> list: """Search the Mendeley catalog.""" token = get_token() params = {"query": query, "limit": limit, "view": "bib"} if min_year: params["min_year"] = min_year resp = requests.get( f"{BASE_URL}/catalog", headers={"Authorization": f"Bearer {token}"}, params=params, ) resp.raise_for_status() results = [] for doc in resp.json(): results.append({ "title": doc.get("title"), "authors": [f"{a['first_name']} {a['last_name']}" for a in doc.get("authors", [])], "year": doc.get("year"), "source": doc.get("source"), "doi": doc.get("identifiers", {}).get("doi"), "readers": doc.get("reader_count", 0), }) return results def lookup_by_doi(doi: str) -> dict: """Look up a single document by DOI.""" token = get_token() resp = requests.get( f"{BASE_URL}/catalog", headers={"Authorization": f"Bearer {token}"}, params={"doi": doi, "view": "bib"}, ) resp.raise_for_status() items = resp.json() return items[0] if items else {} # Example papers = search_catalog("federated learning privacy", min_year=2023) for p in papers: print(f"[{p['year']}] {p['title']} — readers: {p['readers']}")
Reader Statistics
Mendeley tracks how many users have saved each paper, providing a real-time measure of scholarly interest (unlike citation counts which lag by months).
def get_popular_papers(topic: str, limit: int = 10) -> list: """Find most-read papers on a topic via reader counts.""" results = search_catalog(topic, limit=limit) return sorted(results, key=lambda x: x["readers"], reverse=True)
Rate Limits
| Tier | Requests/hour | Catalog access |
|---|---|---|
| Free | 150 | Read-only catalog + personal library |
| Institutional | Higher | Full API access |