Skip to main content
skill CX Codex

arxiv · wanshuiyin — Claude Code skill: search and download papers

Searches arXiv, downloads PDFs into a local folder and writes a short summary. Handy when you need literature on a topic without leaving the chat.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add wanshuiyin/Auto-claude-code-research-in-sleep --skill arxiv -a claude-code
Open on GitHub

What arxiv does

The skill takes a query or a bare arXiv ID like 2301.07041. It hits the arXiv API, prints a table with ID, title, authors, date and category, and for a single ID shows the full author list plus the abstract. Downloaded PDFs land in papers/ inside the project, and you can point it elsewhere.

Under the hood there is a Python script, arxiv_fetch.py, with an inline Python fallback when the script cannot be found. Options go straight into the arguments: - max: 20 raises the result count, - dir: literature/ sets another folder, - download grabs the first result's PDF, - download: all grabs every one. Default is 10 results, and the skill advises a one-second pause between downloads — arXiv starts throttling otherwise.

You need Python 3 and network access. Files under 10 KB get rejected, since they are usually an error page rather than a paper. If the project has a research-wiki/ folder, results are also ingested there.

What it helps with

  • find recent papers on a topic without browsing arXiv by hand
  • download a specific paper's PDF by its ID
  • keep a set of papers inside the project folder
  • read an abstract and author list without opening the full paper
  • feed found papers into the project's research wiki

Example prompts for the agent

  • /arxiv "attention mechanism" - max: 20
  • /arxiv "2301.07041" - download
  • /arxiv "graph neural networks" - dir: literature/ - download: all

How to install arxiv

1Skills CLI (Vercel)

npx skills add wanshuiyin/Auto-claude-code-research-in-sleep --skill arxiv -a claude-code

2Manually: put the files in place

~/.claude/skills/arxiv/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/arxiv/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about arxiv

How do I install arxiv in Claude?

Run npx skills add wanshuiyin/Auto-claude-code-research-in-sleep --skill arxiv -a claude-code. The skill lands at ~/.claude/skills/arxiv/SKILL.md.

What does the arxiv skill do?

It searches arXiv by query or ID, shows a results table, downloads PDFs to a local folder and builds a short summary with the abstract and key points.

What does the arxiv skill need to run?

Python 3 and network access to the arXiv API. Downloads under 10 KB are dropped as error pages, and the skill advises a one-second gap between fetches.

Source text

SKILL.md · MIT
---
name: arxiv
description: Search, download, and summarize academic papers from arXiv. Use when user says "search arxiv", "download paper", "fetch arxiv", "arxiv search", "get paper pdf", or wants to find and save papers from arXiv to the local paper library.
argument-hint: "[query-or-arxiv-id]"
allowed-tools: Bash(*), Read, Write
---

# arXiv Paper Search & Download

Search topic or arXiv paper ID: $ARGUMENTS

## Constants

- **PAPER_DIR** - Local directory to save downloaded PDFs. Default: `papers/` in the current project directory.
- **MAX_RESULTS = 10** - Default number of search results.
- **ARXIV_FETCHER** — canonical name `arxiv_fetch.py`, resolved per
  [`shared-references/integration-contract.md`](../shared-references/integration-contract.md) §2
  (Policy D1 — primary + fallback cascade). If unresolved (canonical
  chain exhausted), fall back to the inline Python alternative
  documented in Step 2.

> Overrides (append to arguments):
> - `/arxiv "attention mechanism" - max: 20` - return up to 20 results
> - `/arxiv "2301.07041" - download` - download a specific paper by ID
> - `/arxiv "query" - dir: literature/` - save PDFs to a custom directory
> - `/arxiv "query" - download: all` - download all result PDFs

## Workflow

### Step 1: Parse Arguments

Parse `$ARGUMENTS` for directives:

- **Query or ID**: main search term or a bare arXiv ID such as `2301.07041` or `cs/0601001`
- **`- max: N`**: override MAX_RESULTS (e.g., `- max: 20`)
- **`- dir: PATH`**: override PAPER_DIR (e.g., `- dir: literature/`)
- **`- download`**: download the first result's PDF after listing
- **`- download: all`**: download PDFs for all results

If the argument matches an arXiv ID pattern (`YYMM.NNNNN` or `category/NNNNNNN`), skip the search and go directly to Step 3.

### Step 2: Search arXiv

Resolve `$ARXIV_FETCHER` via the canonical strict-safe chain (see
[`shared-references/integration-contract.md`](../shared-references/integration-contract.md) §2):

```bash
cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" || exit 1
if [ -z "${ARIS_REPO:-}" ] && [ -f .aris/installed-skills.txt ]; then
    ARIS_REPO=$(awk -F'\t' '$1=="repo_root"{print $2; exit}' .aris/installed-skills.txt 2>/dev/null) || true
fi
if [ -z "${ARIS_REPO:-}" ] && [ -f "$HOME/.aris/repo" ]; then
    ARIS_REPO=$(cat "$HOME/.aris/repo" 2>/dev/null) || true
fi
ARXIV_FETCHER=".aris/tools/arxiv_fetch.py"
[ -f "$ARXIV_FETCHER" ] || ARXIV_FETCHER="tools/arxiv_fetch.py"
[ -f "$ARXIV_FETCHER" ] || { [ -n "${ARIS_REPO:-}" ] && ARXIV_FETCHER="$ARIS_REPO/tools/arxiv_fetch.py"; }
[ -f "$ARXIV_FETCHER" ] || ARXIV_FETCHER=""
```

**If `$ARXIV_FETCHER` is non-empty**, run:

```bash
python3 "$ARXIV_FETCHER" search "QUERY" --max MAX_RESULTS
```

**If `$ARXIV_FETCHER` is empty** (Policy D1 cascade), fall back to inline Python:

```bash
python3 - <<'PYEOF'
import json
import urllib.parse
import urllib.request
import xml.etree.ElementTree as ET

NS = "http://www.w3.org/2005/Atom"
query = urllib.parse.quote("QUERY")
url = (f"http://export.arxiv.org/api/query"
       f"?search_query={query}&start=0&max_results=MAX_RESULTS"
       f"&sortBy=relevance&sortOrder=descending")
with urllib.request.urlopen(url, timeout=30) as r:
    root = ET.fromstring(r.read())
papers = []
for entry in root.findall(f"{{{NS}}}entry"):
    aid = entry.findtext(f"{{{NS}}}id", "").split("/abs/")[-1].split("v")[0]
    title = (entry.findtext(f"{{{NS}}}title", "") or "").strip().replace("\n", " ")
    abstract = (entry.findtext(f"{{{NS}}}summary", "") or "").strip().replace("\n", " ")
    authors = [a.findtext(f"{{{NS}}}name", "") for a in entry.findall(f"{{{NS}}}author")]
    published = entry.findtext(f"{{{NS}}}published", "")[:10]
    cats = [c.get("term", "") for c in entry.findall(f"{{{NS}}}category")]
    papers.append({
        "id": aid,
        "title": title,
        "authors": authors,
        "abstract": abstract,
        "published": published,
        "categories": cats,
        "pdf_url": f"https://arxiv.org/pdf/{aid}.pdf",
        "abs_url": f"https://arxiv.org/abs/{aid}",
    })
print(json.dumps(papers, ensure_ascii=False, indent=2))
PYEOF
```

Present results as a table:

```text
| # | arXiv ID   | Title               | Authors        | Date       | Category |
|---|------------|---------------------|----------------|------------|----------|
| 1 | 2301.07041 | Attention Is All... | Vaswani et al. | 2017-06-12 | cs.LG    |
```

### Step 3: Fetch Details for a Specific ID

When a single paper ID is requested (either directly or from Step 2):

```bash
python3 "$ARXIV_FETCHER" search "id:ARXIV_ID" --max 1
# or fallback:
python3 -c "
import urllib.request, xml.etree.ElementTree as ET
NS = 'http://www.w3.org/2005/Atom'
url = 'http://export.arxiv.org/api/query?id_list=ARXIV_ID'
with urllib.request.urlopen(url, timeout=30) as r:
    root = ET.fromstring(r.read())
# print full details ...
"
```

Display: title, all authors, categories, full abstract, published date, PDF URL, abstract URL.

### Step 4: Download PDFs

When download is requested, for each paper ID to download:

```bash
# Using fetch script:
python3 "$ARXIV_FETCHER" download ARXIV_ID --dir PAPER_DIR

# Fallback:
mkdir -p PAPER_DIR && python3 -c "
import pathlib
import sys
import urllib.request

out = pathlib.Path('PAPER_DIR/ARXIV_ID.pdf')
if out.exists():
    print(f'Already exists: {out}')
    sys.exit(0)
req = urllib.request.Request(
    'https://arxiv.org/pdf/ARXIV_ID.pdf',
    headers={'User-Agent': 'arxiv-skill/1.0'},
)
with urllib.request.urlopen(req, timeout=60) as r:
    out.write_bytes(r.read())
print(f'Downloaded: {out} ({out.stat().st_size // 1024} KB)')
"
```

After each download:

- Confirm file size > 10 KB (reject smaller files - likely an error HTML page)
- Add a 1-second delay between consecutive downloads to avoid rate limiting
- Report: `Downloaded: papers/2301.07041.pdf (842 KB)`

### Step 5: Summarize

For each paper (downloaded or fetched by API):

```markdown
## [Title]

- **arXiv**: [ID] - [abs_url]
- **Authors**: [full author list]
- **Date**: [published]
- **Categories**: [cs.LG, cs.AI, ...]
- **Abstract**: [full abstract]
- **Key contributions** (extracted from abstract):
  - [contribution 1]
  - [contribution 2]
  - [contribution 3]
- **Local PDF**: papers/[ID].pdf (if downloaded)
```

### Step 6: Update Research Wiki (if active)

**Required when `research-wiki/` exists in the project**; skip silently
otherwise. When the wiki dir exists, resolve `$WIKI_SCRIPT` per the
canonical chain at
[`shared-references/wiki-helper-resolution.md`](../shared-references/wiki-helper-resolution.md)
(Variant B — warn-and-skip), then ingest every paper returned by this
invocation:

```bash
if [ -d research-wiki/ ]; then
  cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" || exit 1
  ARIS_REPO="${ARIS_REPO:-$(awk -F'\t' '$1=="repo_root"{print $2; exit}' .aris/installed-skills.txt 2>/dev/null)}"
  if [ -z "${ARIS_REPO:-}" ] && [ -f "$HOME/.aris/repo" ]; then
    ARIS_REPO=$(cat "$HOME/.aris/repo" 2>/dev/null) || true
  fi
  WIKI_SCRIPT=".aris/tools/research_wiki.py"
  [ -f "$WIKI_SCRIPT" ] || WIKI_SCRIPT="tools/research_wiki.py"
  [ -f "$WIKI_SCRIPT" ] || { [ -n "${ARIS_REPO:-}" ] && WIKI_SCRIPT="$ARIS_REPO/tools/research_wiki.py"; }
  [ -f "$WIKI_SCRIPT" ] || {
    echo "WARN: research_wiki.py not found; arxiv results delivered, wiki ingest skipped. Fix: bash tools/install_aris.sh or smart_update.sh (refreshes ~/.aris/repo), export ARIS_REPO, or cp <ARIS-repo>/tools/research_wiki.py tools/." >&2
    WIKI_SCRIPT=""
  }
  if [ -n "$WIKI_SCRIPT" ]; then
    for each arxiv_id in results:
        python3 "$WIKI_SCRIPT" ingest_paper research-wiki/ \
            --arxiv-id "<arxiv_id>"
  fi
fi
```

The helper handles metadata fetch, slug, dedup, page creation, index
rebuild, and log append in a single call — **do not handwrite
`papers/<slug>.md`**. See
[`shared-references/integration-contract.md`](../shared-references/integration-contract.md)
for the canonical-helper rule. Missed ingests can be backfilled later
with `python3 "$WIKI_SCRIPT" sync research-wiki/ --arxiv-ids <id1>,<id2>,...`
after resolving `$WIKI_SCRIPT` as above.

### Step 7: Final Output

Summarize what was done:

- `Found N papers for "query"`
- `Downloaded: papers/2301.07041.pdf (842 KB)` (for each download)
- `Wiki-ingested N papers` (if `research-wiki/` was present)
- Any warnings (rate limit hit, file too small, already exists)

Suggest follow-up skills:

```text
/research-lit "topic"     - multi-source review: Zotero + Obsidian + local PDFs + web
/novelty-check "idea"     - verify your idea is novel against these papers
```

## Key Rules

- Always show the arXiv ID prominently - users need it for citations and reproducibility
- Verify downloaded PDFs: file must be > 10 KB; warn and delete if smaller
- Rate limit: wait 1 second between consecutive PDF downloads; retry once after 5 seconds on HTTP 429
- Never overwrite an existing PDF at the same path - skip it and report "already exists"
- Handle both arXiv ID formats: new (`2301.07041`) and old (`cs/0601001`)
- PAPER_DIR is created automatically if it does not exist
- If the arXiv API is unreachable, report the error clearly and suggest using `/research-lit` with `- sources: web` as a fallback

© wanshuiyin · MIT · wanshuiyin/Auto-claude-code-research-in-sleep

Similar skills

Everything for Science and research →

arxiv by other authors comes first.

From the same set78

semantic-scholar Finds journal and conference papers through the Semantic Scholar API: venue metadata, citation counts and a one-line summary. CX Codex +1 614installs research-lit Searches for papers on a topic, finds related work and summarizes the key ideas. Useful when you need a literature review without digging through arXiv by hand. CX Codex +1 614installs idea-discovery Automates an end-to-end research idea pipeline from literature survey to novelty check and experiment planning. Handy for scoping new research directions from scratch. CX Codex +1 580installs idea-creator Generates, validates, and ranks research ideas from a broad direction. Use it when you need candidate topics to investigate further. CX Codex +1 580installs auto-review-loop Runs an autonomous multi-round research review loop. It applies fixes and queries an external reviewer until reaching the target score or round limit. CX Codex +1 566installs research-review Sends your work to an external reviewer — Claude, Gemini, Claude or Claude — for a critical read. Useful when you want outside eyes on ideas, a paper or experiment results. CX Codex +1 561installs paper-writing Automates scientific paper writing from a narrative report to a compiled LaTeX PDF. Chains five sub-skills through two review and improvement rounds. CX Codex +1 561installs grant-proposal Turns research ideas and literature into a structured grant proposal: aims, budget justification, timeline, agency-specific formatting. CX Codex +1 560installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor