
Literature Search Arxiv
- 1.9k installs
- 2.6k repo stars
- Updated July 7, 2026
- google-deepmind/science-skills
literature-search-arxiv is an agent skill that apply literature-search-arxiv agent skill workflows from documented skill.md guidance.
About
literature-search-arxiv is an agent skill from google-deepmind/science-skills that apply literature-search-arxiv agent skill workflows from documented skill.md guidance. # arXiv Search and Retrieval ## Prerequisites 1. **`uv`**: Read the `uv` skill and follow its Setup instructions to ensure `uv` is installed and on PATH. 2. **User Notification**: If LICENSE_NOTIFICATION.txt does not already exist in this skill directory then (1) prominently notify the user to check the terms at https://info.arxiv.o Developers invoke literature-search-arxiv during idea/research work for documentation tasks. The skill documents triggers, prerequisites, and step-by-step workflows grounded in SKILL.md. Compatible with Claude Code, Cursor, and Codex agent runtimes that load marketplace skills. Review the Security Audits panel on this listing before installing in production environments.
- arXiv Search and Retrieval
- 1. **`uv`**: Read the `uv` skill and follow its Setup instructions to ensure
- `uv` is installed and on PATH.
- 2. **User Notification**: If LICENSE_NOTIFICATION.txt does not already exist in
- this skill directory then (1) prominently notify the user to check the terms
Literature Search Arxiv by the numbers
- 1,851 all-time installs (skills.sh)
- +105 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #188 of 1,879 Documentation skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
literature-search-arxiv capabilities & compatibility
- Capabilities
- arxiv search and retrieval · 1. **`uv`**: read the `uv` skill and follow its · `uv` is installed and on path. · 2. **user notification**: if license_notificatio · this skill directory then (1) prominently notify
- Use cases
- orchestration
What literature-search-arxiv says it does
1. **`uv`**: Read the `uv` skill and follow its Setup instructions to ensure
2. **User Notification**: If LICENSE_NOTIFICATION.txt does not already exist in
this skill directory then (1) prominently notify the user to check the terms
npx skills add https://github.com/google-deepmind/science-skills --skill literature-search-arxivAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.9k |
|---|---|
| repo stars | ★ 2.6k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 7, 2026 |
| Repository | google-deepmind/science-skills ↗ |
What it does
Apply literature-search-arxiv agent skill workflows from documented SKILL.md guidance.
Who is it for?
Developers working on documentation during idea tasks.
Skip if: Tasks outside Documentation scope described in SKILL.md.
When should I use this skill?
Apply literature-search-arxiv agent skill workflows from documented SKILL.md guidance.
What you get
Completed documentation workflow aligned with SKILL.md steps.
- Filtered arXiv paper search results
By the numbers
- Queries arXiv's corpus of 2.4 million papers
- Documents 8 field prefixes including ti:, au:, abs:, and cat:
Files
arXiv Search and Retrieval
Prerequisites
1. `uv`: Read the uv skill and follow its Setup instructions to ensure uv is installed and on PATH. 2. User Notification: If LICENSE_NOTIFICATION.txt does not already exist in this skill directory then (1) prominently notify the user to check the terms at https://info.arxiv.org/help/api/index.html and to always check the license of the papers retrieved by the skill for any restrictions, then (2) create the file recording the notification text and timestamp.
Core Rules
- Terms of Use: You MUST respect arXiv's Terms of Use.
- Maximum 1 request every 3 seconds.
- The provided utility scripts handle rate limiting automatically. Always
use these scripts rather than writing your own curl/python requests.
- If this skill is used, ensure this is mentioned in the output AND list the
URLs of all papers that were used in producing the output.
Utility Scripts
1. Search and Extract Metadata
Search arXiv and return a clean JSON array of matching papers.
uv run scripts/search_arxiv.py --query "au:einstein AND ti:relativity" \
--max_results 5 2>/dev/null > /tmp/arxiv_search_results.jsonImportant: The tool outputs a large JSON result to stdout. Requesting 100+
results will produce a massive JSON that might exceed your context length.
Limit--max_results(e.g., 5-10) or paginate carefully using--start.
Always redirect output to a file and parse it separately, otherwise terminal
output will be truncated.
Returned Metadata: JSON results include id, title, summary, published, authors, pdf_url, primary_category, doi, journal_ref, and comment. Note: the doi field only contains DOI information in case the paper has an external DOI and if only an arXiv-issued DOI exists, this is DOI is not returned.
Options:
-
--query: Search string. See
references/query_syntax.md for advanced syntax.
-
--id_list: Comma-separated list of arXiv IDs to fetch directly (e.g.,
1706.03762v5).
-
--start: Pagination offset (default 0). -
--max_results: Number of results to return (default 10). -
--sort_by:relevance,lastUpdatedDate, orsubmittedDate. (Use
--sort_by submittedDate --sort_order descending for the most recent papers).
-
--sort_order:ascendingordescending.
2. Download Paper (PDF or HTML)
Download the full text of a paper to your local workspace for reading.
uv run scripts/download_paper.py --id 1706.03762 --format pdf --output attention.pdfOptions:
-
--id: The arXiv ID (e.g.,1706.03762or1706.03762v5). -
--format:pdforhtml. Note: HTML is only available for newer papers. -
--output: Filepath to save the downloaded document.
Important: when downloading papers, make sure you download them to a
location where you do not overwrite other files and do not clutter existing
directory structure.
3. Download Paper Source (tar.gz)
Download the LaTeX source files of a paper to your local workspace. Note that not all papers have source available.
uv run scripts/download_paper_source.py --id 2010.11645 --output source.tar.gzOptions:
-
--id: The arXiv ID (e.g.,2010.11645). -
--output: Filepath to save the downloaded tar.gz file.
Caution: Care should be exercised when untar'ing the downloaded file for
security and to avoid cluttering your filesystem, as archives may contain many
files or unexpected directory structures.
>
Safe Extraction Requirements: NEVER extract directly into your working
directory! Always extract into a dedicated new directory: `bash mkdir
paper_source && tar -xzf source.tar.gz -C paper_source`
Reference
- Advanced Query Syntax: See
references/query_syntax.md for prefixes (au, ti, abs), booleans, and date filtering.
Workflow
1. Search for papers using search_arxiv.py. Review the JSON summaries. 2. If full text is needed, use download_paper.py to fetch the PDF or HTML. 3. If downloading a PDF, verify the PDF is not empty or corrupted. 4. Read the downloaded file using standard file reading tools.
arXiv Query Syntax Reference
When using scripts/search_arxiv.py --query "...", you can use the following advanced search features. The script automatically handles URL encoding.
Field Prefixes
Prefix your search terms to target specific fields:
ti:Titleau:Authorabs:Abstractco:Commentjr:Journal Referencecat:Subject Category (e.g.,cat:cs.AI)rn:Report Numberall:All fields
Boolean Operators
Combine terms using AND, OR, and ANDNOT. Example: au:del_maestro ANDNOT ti:checkerboard
Grouping and Phrases
- Parentheses `()`: Group boolean expressions.
Example: au:del_maestro ANDNOT (ti:checkerboard OR ti:Pyrochlore)
- Double Quotes `""`: Search for exact phrases.
Example: au:del_maestro AND ti:"quantum criticality"
Date Filtering
Filter by the date submitted to arXiv. Format: [YYYYMMDDHHMM TO YYYYMMDDHHMM] (GMT). Example: au:del_maestro AND submittedDate:[202301010600 TO 202401010600]
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Downloads the source (tar.gz) of a paper from arXiv given its ID.
This script allows downloading the LaTeX source files of arXiv papers
and saving them to a specified output file path.
"""
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "scienceskillscommon",
# ]
# [tool.uv.sources]
# scienceskillscommon = { path = "../../scienceskillscommon" }
# ///
import argparse
import os
import sys
import urllib.error
from science_skills.skills.scienceskillscommon import http_client
_CLIENT = http_client.HttpClient("https://export.arxiv.org/", qps=1.0 / 3.0)
def parse_args() -> argparse.Namespace:
"""Parses command-line arguments for the download script.
Returns:
argparse.Namespace: An object containing the parsed arguments.
"""
parser = argparse.ArgumentParser(
description="Download paper source (tar.gz) from arXiv"
)
parser.add_argument(
"--id", type=str, required=True, help="arXiv ID (e.g., 2010.11645)"
)
parser.add_argument(
"--output",
type=str,
required=True,
help="Output file path for the tar.gz file",
)
return parser.parse_args()
def download_source(args: argparse.Namespace):
"""Downloads the source of a paper from arXiv based on the provided arguments.
This function fetches the source (tar.gz) from arXiv using the
specified ID, saving it to the given output path. It includes
error handling for common issues like 404 Not Found and network errors,
and enforces a rate limit after each download attempt.
Args:
args: An argparse.Namespace object containing: - id (str): The arXiv ID of
the paper. - output (str): The file path where the tar.gz will be saved.
"""
# Ensure ID is clean
paper_id = args.id.strip()
url = f"https://export.arxiv.org/e-print/{paper_id}"
print(f"Attempting to download source from {url}...")
try:
content = _CLIENT.fetch_bytes(url)
out_dir = os.path.dirname(args.output)
if out_dir:
os.makedirs(out_dir, exist_ok=True)
with open(args.output, "wb") as f:
f.write(content)
print(f"Success! Saved to {args.output}")
except urllib.error.HTTPError as e:
if e.code == 404:
print(
f"Error 404: Source not found (ID: {paper_id}). Not all papers have"
" source available.",
file=sys.stderr,
)
else:
raise
if __name__ == "__main__":
main_args = parse_args()
download_source(main_args)
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Downloads a paper from arXiv given its ID.
This script allows downloading arXiv papers in either PDF or HTML format
and saving them to a specified output file path.
"""
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "scienceskillscommon",
# ]
# [tool.uv.sources]
# scienceskillscommon = { path = "../../scienceskillscommon" }
# ///
import argparse
import os
import sys
import urllib.error
from science_skills.skills.scienceskillscommon import http_client
_CLIENT = http_client.HttpClient("https://arxiv.org/", qps=1.0 / 3.0)
def parse_args() -> argparse.Namespace:
"""Parses command-line arguments for the download script.
Returns:
argparse.Namespace: An object containing the parsed arguments.
"""
parser = argparse.ArgumentParser(
description="Download paper from arXiv (PDF or HTML)"
)
parser.add_argument(
"--id", type=str, required=True, help="arXiv ID (e.g., 2305.10601)"
)
parser.add_argument(
"--format",
type=str,
choices=["pdf", "html"],
required=True,
help="Download format",
)
parser.add_argument(
"--output", type=str, required=True, help="Output file path"
)
return parser.parse_args()
def download_paper(args: argparse.Namespace):
"""Downloads a paper from arXiv based on the provided arguments.
This function fetches a paper (either PDF or HTML) from arXiv using the
specified ID and format, saving it to the given output path. It includes
error handling for common issues like 404 Not Found and network errors,
and enforces a rate limit after each download attempt.
Args:
args: An argparse.Namespace object containing: id (str) -- The arXiv ID of
the paper; format (str) -- The desired format ("pdf" or "html"); output
(str) -- The file path where the paper will be saved.
"""
# Ensure ID is clean
paper_id = args.id.strip()
if args.format == "pdf":
url = f"https://arxiv.org/pdf/{paper_id}.pdf"
elif args.format == "html":
url = f"https://arxiv.org/html/{paper_id}"
else:
raise ValueError(f"Unsupported format: {args.format}")
print(f"Attempting to download {args.format.upper()} from {url}...")
try:
content = _CLIENT.fetch_bytes(url)
out_dir = os.path.dirname(args.output)
if out_dir:
os.makedirs(out_dir, exist_ok=True)
with open(args.output, "wb") as f:
f.write(content)
print(f"Success! Saved to {args.output}")
except urllib.error.HTTPError as e:
if e.code == 404:
if args.format == "html":
print(
"Error 404: HTML format is not available for this paper (ID:"
f" {paper_id}). Older papers may only have PDFs. Try downloading"
" with --format pdf",
file=sys.stderr,
)
else:
print(
f"Error 404: Paper not found (ID: {paper_id}). Check the ID.",
file=sys.stderr,
)
else:
raise
if __name__ == "__main__":
main_args = parse_args()
download_paper(main_args)
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Searches the arXiv API and returns results in a clean JSON format.
This script allows querying the arXiv API using either a search query string
or a list of arXiv IDs. It parses the XML response and outputs a JSON object
containing the search results.
"""
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "scienceskillscommon",
# ]
# [tool.uv.sources]
# scienceskillscommon = { path = "../../scienceskillscommon" }
# ///
import argparse
import json
import sys
import urllib.parse
import xml.etree.ElementTree as ET
from science_skills.skills.scienceskillscommon import http_client
_BASE_URL = "http://export.arxiv.org/api/query?"
_CLIENT = http_client.HttpClient(_BASE_URL, qps=1.0 / 3.0)
def parse_args() -> argparse.Namespace:
"""Parses command-line arguments for the arXiv search script.
Returns:
argparse.Namespace: An object containing the parsed command-line arguments.
"""
parser = argparse.ArgumentParser(
description="Search arXiv API and return clean JSON"
)
parser.add_argument(
"--query",
type=str,
help="Search query string (e.g., 'au:einstein AND ti:relativity')",
)
parser.add_argument(
"--id_list", type=str, help="Comma-separated list of arXiv IDs"
)
parser.add_argument("--start", type=int, default=0, help="Pagination offset")
parser.add_argument(
"--max_results", type=int, default=10, help="Number of results to return"
)
parser.add_argument(
"--sort_by",
type=str,
choices=["relevance", "lastUpdatedDate", "submittedDate"],
help="Sort by",
)
parser.add_argument(
"--sort_order",
type=str,
choices=["ascending", "descending"],
help="Sort order",
)
return parser.parse_args()
def strip_namespace(tag: str) -> str:
if tag.startswith("{"):
return tag.split("}", 1)[1]
return tag
def search_arxiv(args: argparse.Namespace):
"""Searches the arXiv API and prints results as a JSON string.
Constructs a query to the arXiv API based on the provided arguments,
fetches the XML response, parses it, and prints a JSON object containing
the extracted paper information.
Args:
args: An argparse.Namespace object containing the search parameters (query,
id_list, start, max_results, sort_by, sort_order).
"""
params = {"start": args.start, "max_results": args.max_results}
if args.query:
params["search_query"] = args.query
if args.id_list:
params["id_list"] = args.id_list
if args.sort_by:
params["sortBy"] = args.sort_by
if args.sort_order:
params["sortOrder"] = args.sort_order
# Use quote_plus to ensure spaces become '+' as required by arXiv API
query_string = urllib.parse.urlencode(
params, quote_via=urllib.parse.quote_plus
)
url = _BASE_URL + query_string
results = []
xml_data = _CLIENT.fetch_bytes(url)
root = ET.fromstring(xml_data)
for entry in root.findall("{http://www.w3.org/2005/Atom}entry"):
paper = {}
authors = []
for child in entry:
tag = strip_namespace(child.tag)
if tag == "id":
# Extract just the ID part (e.g., http://arxiv.org/abs/2305.10601v1
# -> 2305.10601v1)
if child.text:
paper["id"] = child.text.split("/abs/")[-1]
elif tag == "title":
paper["title"] = (
child.text.replace("\n", " ").strip() if child.text else ""
)
elif tag == "summary":
paper["summary"] = (
child.text.replace("\n", " ").strip() if child.text else ""
)
elif tag == "published":
paper["published"] = child.text
elif tag == "author":
for name_node in child.findall("{http://www.w3.org/2005/Atom}name"):
authors.append(name_node.text)
elif tag == "link":
if child.get("title") == "pdf":
paper["pdf_url"] = child.get("href")
elif tag == "primary_category":
paper["primary_category"] = child.get("term")
elif tag in {"doi", "journal_ref", "comment"}:
paper[tag] = child.text
paper["authors"] = authors
results.append(paper)
print(
json.dumps(
{
"status": "success",
"results_count": len(results),
"papers": results,
},
indent=2,
)
)
if __name__ == "__main__":
main_args = parse_args()
if not main_args.query and not main_args.id_list:
print(
json.dumps(
{
"status": "error",
"message": "Must provide either --query or --id_list",
},
indent=2,
)
)
sys.exit(1)
search_arxiv(main_args)
Related skills
How it compares
Use literature-search-arxiv for arXiv-specific CLI queries; use general web search skills when sources beyond preprints are required.
FAQ
What does literature-search-arxiv do?
Apply literature-search-arxiv agent skill workflows from documented SKILL.md guidance.
When should I use literature-search-arxiv?
During idea research work for documentation.
Is literature-search-arxiv safe to install?
Review the Security Audits panel on this listing before production use.