arxiv-mcp
You can use this MCP server to search, inspect, extract from, and analyze arXiv papers.
Search arXiv papers with query syntax, category filters, sorting, and page size.
Fetch full metadata for one paper by modern or legacy arXiv ID.
Download a paper’s PDF and extract text from its first pages.
Summarize category activity with sampled daily submission counts and frequent title terms.
Read Markdown paper cards and the arXiv category taxonomy as resources.
Use a
literature_reviewprompt to guide multi-step topic research with citations.
Provides tools for searching arXiv papers, retrieving paper metadata, extracting text from PDFs, and analyzing category submission trends through the arXiv API.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@arxiv-mcp find recent arXiv papers on retrieval-augmented generation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
arxiv-mcp
An MCP server that turns arXiv into a set of tools an LLM agent can call: search, fetch metadata, extract PDF text, and summarise how active a research category is.
Built as a learning project while studying for a CS degree, targeting LLM-application / agent engineering internships.
you / an agent
│ tools/call "search_papers"
▼
┌──────────────┐ throttled + cached HTTP ┌──────────────┐
│ arxiv-mcp │ ───────────────────────────▶ │ arXiv API │
│ (MCP server)│ ◀─────────────────────────── │ Atom feed │
└──────────────┘ retry w/ backoff └──────────────┘
│ validated pydantic models
▼
structuredContent the model can actually reason aboutWhat it exposes
Tools
Tool | What it does | Why it is not just a proxy |
| arXiv search with field syntax ( | Optional category filter is composed into |
| Full metadata for one paper | Strips version suffixes, validates both modern ( |
| Downloads the PDF and extracts text from the first pages | Reports page count, how many were parsed, and whether it truncated — so the model knows what it is missing |
| Submission volume per day + most frequent title terms, over a sample of the newest papers | An analysis tool, not a lookup: it aggregates and tokenises so an agent can answer "is this field heating up?" - the counts are a sample estimate, not the category's true volume |
Resources
arxiv://paper/{arxiv_id}— a Markdown card with the paper's full metadataarxiv://categories— the arXiv taxonomy the server can filter on
Prompts
literature_review(topic, max_papers)— a multi-step workflow that instructs an agent to check category trends first, try several phrasings, then group findings and cite every claim with anarxiv_id
Related MCP server: Research MCP Server
Install and run
pip install -e ".[pdf]" # the pdf extra enables get_pdf_text
arxiv-mcp # serves over stdioPoint any MCP host at it. For Claude Desktop / Claude Code:
{
"mcpServers": {
"arxiv": {
"command": "uv",
"args": ["run", "--with", "arxiv-mcp[pdf]", "arxiv-mcp"]
}
}
}To poke at it interactively:
uv run mcp dev src/arxiv_mcp/server.py # opens the MCP InspectorDesign notes
Rate limiting is a feature, not an afterthought. arXiv asks clients to keep requests
at least 3 seconds apart and to send a descriptive User-Agent. ArxivClient enforces
both: an asyncio.Lock serialises requests and a monotonic clock enforces the gap, so
concurrent tool calls cannot stampede the API. Getting rate-limited by arXiv would break
every tool at once.
Retries with full jitter, capped, and Retry-After-aware. Transient
429/5xx responses and transport errors are retried up to max_retries times
with a backoff of uniform(0, min(base * 2**attempt, cap)). The cap matters:
arXiv's rate limiter can sit on an IP for minutes, and unbounded backoff is
worse than a clear error. When the server sends Retry-After it is honoured
(subject to the same cap) instead of guessing.
This is not theoretical. During development the first version retried 3 times
with sub-second backoff and no Retry-After handling; testing against the live
API got the sandbox IP rate-limited, and the failure was slow and opaque. Both
the backoff and the error message (HTTP 429 rather than an empty string) were
rewritten after that.
The API URL is https://. http://export.arxiv.org answers 301 to
https://, which silently doubles every request and interacts badly with
retries. Found the same way - by actually running it.
Caching raw response bodies. Responses are cached keyed by the fully-built request
URL in SQLite with a TTL. Keying on the URL (rather than a hand-built cache key) means
the key is correct by construction. The server wires this in when it builds its client:
the database lives under the platform cache directory
(%LOCALAPPDATA%\arxiv-mcp\cache.sqlite on Windows, ~/.cache/arxiv-mcp/cache.sqlite
elsewhere), can be moved with ARXIV_MCP_CACHE_PATH, and is disabled with
ARXIV_MCP_CACHE=off. A read-only home directory degrades to "no cache" instead of
stopping the server - caching is an optimisation, not a requirement.
Error policy follows the MCP spec. Every failure is placed in one of three buckets:
Raised | Model sees | Used here for |
| the message, | paper not found, arXiv unreachable, empty search result |
| nothing — the request itself fails | missing optional dependency ( |
anything else | only | bugs |
The deciding question is "could a smarter model have avoided this?". A misspelled arXiv id can be corrected by the model, so it gets the message. A missing Python package cannot, so it is escalated to the host.
Models everywhere. Every tool returns a pydantic model, so clients receive validated
structuredContent instead of untyped strings. Bad arguments are rejected by the SDK's
schema validation before the handler runs, so the handlers do not re-validate type hints.
The arXiv layer has no MCP imports. arxiv_mcp.client is plain async code, which is
what makes it unit-testable without starting a server — see tests/test_client.py.
Tests
pytest # 55 tests
ruff check . # linttests/test_client.py— feed parsing, cache hit/miss, retry behaviour, identifier validation. HTTP is mocked withrespx, so nothing touches the network. Includes the backoff policy:Retry-Afterhonoured, capped, jittered.tests/test_server.py— the whole server exercised through an in-memory MCPClient: tool/resource/prompt discovery, structured output, and that each error surfaces in the right bucket. Also asserts the server actually hands aTTLCacheto its client (ARXIV_MCP_CACHE_PATH/ARXIV_MCP_CACHE=off), so the cache cannot silently become dead code again.tests/test_models.py,tests/test_cache.py— validation and TTL expiry.
Verification status
Check | Result |
| 55 passed |
| clean |
Live | returns "Attention Is All You Need", 3 authors, |
Live | returns daily counts and title terms |
Live | returns 3 results out of 1,029,300 matches |
Free-text search was the last endpoint confirmed live. During development the build
machine's shared egress IP was rate-limited (repeated 429/ReadTimeout on search
while id_list and cat: kept working), so for a while only the respx-mocked tests
covered the happy path. Re-run from a different egress and it returns results normally —
the earlier failures were the IP, not the client. The 3-second throttle and the capped
Retry-After-aware backoff exist precisely because that endpoint is easy to get wrong.
Limitations
search_papersreturns one page (max 100). arXiv'sstartoffset works but is not exposed as a tool argument.category_trendssamples the newest N papers once, sodaily_countsonly covers the days those papers span. For a busy category likecs.AIthat is a few days, not the requested 30-day window - it estimates activity, it does not count submissions.get_pdf_textneeds thepdfextra and is slow — it downloads the whole PDF.arXiv has no relevance-ranked "related papers" endpoint, so nothing here does citation-graph traversal.
The server holds one shared
ArxivClientwith a single throttle lock, so tool calls in one process are serialised 3 seconds apart. Fine for stdio single-user use, not a multi-tenant deployment.
Attribution
The code in this repository was written for this project. It follows the patterns in the MCP Python SDK documentation (which is MIT licensed) but contains no copied code.
License
MIT — see LICENSE.
Available Tools
4 toolscategory_trendsA
Summarise recent submission volume and the most common title terms in a category.
Inputs: category (required), sample_size, window_days. Returns: Submission-volume statistics for one arXiv category.
get_paperA
Fetch full metadata for a single arXiv paper by identifier.
Inputs: arxiv_id (required). Returns: A single arXiv preprint, flattened out of the Atom entry.
get_pdf_textA
Download a paper's PDF and extract text from its first pages.
Slow and bandwidth-heavy - use only when the abstract is insufficient.
Inputs: arxiv_id (required), max_pages. Returns: Text extracted from a paper's PDF.
search_papersB
Search arXiv and return a page of matching papers.
Inputs: query (required), sort_by, category, max_results. Returns: The result of an arXiv API query.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
search_papers (discovery), category_trends (aggregate stats), and get_pdf_text (heavy full-text path) are clearly distinct. get_paper and get_pdf_text both operate on a single paper by identifier, but the metadata-vs-full-text distinction and the explicit 'use only when the abstract is insufficient' caveat keep them separable.
Three of four tools follow a clean verb_noun snake_case pattern (search_papers, get_paper, get_pdf_text). category_trends breaks the pattern as a noun_phrase, though it remains readable and unambiguous.
Four tools is on the lean side but each covers a genuinely different retrieval mode (search, metadata, full text, trends) with no filler. It is slightly thin for a research-paper server but not under-scoped.
The core lifecycle — find papers, read metadata, read full text, observe category activity — is covered with no dead ends. Minor gaps exist: no author-based lookup, no listing of recent papers by date, and no citation/export (BibTeX) helper, which agents must approximate via search queries.
Maintenance
Related MCP Connectors
arXiv and OpenAlex/Crossref paper search (an open Google Scholar alternative) as agent tools.
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
GitHub, npm, PyPI, Stack Overflow, arXiv and OpenAlex paper search as agent tools.
Search arXiv and ACL Anthology, retrieve citations and references, and browse web sources to accel…
Related MCP Servers
- AlicenseBqualityNot gradedmaintenanceEnables AI assistants to search and retrieve academic papers from arXiv through MCP tools, supporting search by various criteria, detailed paper information, category browsing, and PDF content extraction.481 npm2-
- FlicenseNot gradedqualityDmaintenanceEnables searching and managing academic papers from arXiv with tools, resources, and prompt templates for literature review.1-
- FlicenseAqualityDmaintenanceEnables agents to search papers across Semantic Scholar and arXiv, read and extract text from arXiv PDFs, align records across sources, and produce structured literature-analysis digests.101-
- FlicenseNot gradedqualityDmaintenanceEnables searching arXiv papers, extracting paper information, listing paper topics, and generating structured research prompts through MCP tools, resources, and prompts.-