arxiv-mcp
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-mcpfind 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 | An analysis tool, not a lookup: it aggregates and tokenises so an agent can answer "is this field heating up?" |
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.
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 # 53 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.tests/test_models.py,tests/test_cache.py— validation and TTL expiry.
Verification status
Check | Result |
| 53 passed |
| clean |
Live | returns "Attention Is All You Need", 3 authors, |
Live | returns daily counts and title terms |
Live | rate-limited from the dev IP — see below |
The free-text search endpoint is the one thing not verified end-to-end from the
machine this was built on: arXiv rate-limited that IP (the sandbox shares an
egress address with other traffic) and kept returning 429/ReadTimeout for
search queries while id_list and cat: queries kept succeeding. The client
handles it correctly — it retries with backoff, then raises a ToolError with
the HTTP status — but the happy path for search is covered by the respx-mocked
tests, not by a live call. Run it once from a residential connection to confirm.
Limitations
search_papersreturns one page (max 100). arXiv'sstartoffset works but is not exposed as a tool argument.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
ArxivClient; there is no per-session configuration.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| category | Yes | arXiv category, e.g. 'cs.AI' or 'cs.LG'. | |
| sample_size | No | How many recent papers to sample. | |
| window_days | No | How far back to look. |
Output Schema
| Name | Required | Description |
|---|---|---|
| sampled | Yes | Papers examined (bounded by arXiv's page limit). |
| category | Yes | arXiv category, e.g. 'cs.AI'. |
| window_days | Yes | How many days back the sample covers. |
| daily_counts | Yes | ISO date -> number of submissions. |
| top_title_terms | Yes | [term, count] pairs from paper titles, most frequent first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses what is computed (volume and title-term frequency) but says nothing about data source, freshness, whether results are cached or sampled live, or limitations of using a recent sample; 'recent' is left ambiguous in the description despite window_days existing in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with zero waste, front-loading the verb and the two key outputs. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value structure needn't be explained, and all three parameters are fully documented in the schema. The description covers the tool's purpose adequately for a simple summary operation, though it could add a brief note on recency or usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and each parameter already has a clear description, so the schema does the heavy lifting. The description mentions 'recent' and 'category' but adds no syntax or format details beyond what the schema provides; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Summarise') and two concrete outputs (submission volume and common title terms) scoped to a category. This is plainly distinguishable from the sibling tools search_papers, get_paper, and get_pdf_text, which operate on individual papers rather than aggregate trends.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when the tool is useful (to get a category-level trend summary), but gives no explicit when-to-use/when-not-to-use guidance or named alternatives. An agent can infer it is the aggregate-view counterpart to search_papers, but that routing is not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_paperA
Fetch full metadata for a single arXiv paper by identifier.
| Name | Required | Description | Default |
|---|---|---|---|
| arxiv_id | Yes | arXiv identifier, with or without version. Modern form '2401.12345', legacy form 'cs.LO/0112017'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| doi | No | Journal DOI when one is registered. |
| title | Yes | Paper title, whitespace-normalised. |
| abs_url | Yes | Canonical abstract page. |
| authors | Yes | Author names in the order arXiv lists them. |
| comment | No | Author comment, e.g. page count or venue. |
| pdf_url | Yes | Canonical PDF URL. |
| updated | Yes | Date of the latest revision. |
| version | No | Version of the record that was returned. |
| abstract | Yes | Abstract text, whitespace-normalised. |
| arxiv_id | Yes | Bare arXiv identifier without version, e.g. '2401.12345'. |
| published | Yes | Date of v1 submission. |
| categories | Yes | All categories the paper is tagged with. |
| journal_ref | No | Journal reference, when present. |
| primary_category | Yes | Primary arXiv category, e.g. 'cs.AI'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavior burden. 'Fetch' signals a non-mutating read and 'full metadata' characterizes the payload, but nothing is said about behavior on an unknown or malformed identifier, version resolution defaults, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the verb and the resource, with no filler. Nothing could be removed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and the sole parameter is richly described, so this short description is close to sufficient for a simple lookup tool. A note on how an identifier with versus without a version is resolved would close the remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single arxiv_id parameter is fully documented with modern and legacy forms. The description adds nothing beyond 'by identifier', so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch') and resource ('full metadata for a single arXiv paper'), and the word 'single' implicitly contrasts with the bulk-oriented search_papers sibling. It stops short of naming or explicitly distinguishing itself from any sibling, so a 4 rather than a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer it should call this when it already holds a paper identifier, and that search_papers is the discovery alternative. There is no explicit when-to-use/when-not-to-use statement or named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| arxiv_id | Yes | arXiv identifier, e.g. '2401.12345'. | |
| max_pages | No | How many pages to parse. |
Output Schema
| Name | Required | Description |
|---|---|---|
| text | Yes | Extracted text, pages joined by form feeds. |
| arxiv_id | Yes | |
| truncated | Yes | True when the PDF was longer than max_pages. |
| page_count | Yes | Pages in the downloaded PDF. |
| extracted_pages | Yes | Pages that were actually parsed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral load and does so well: it discloses cost/latency characteristics (slow, bandwidth-heavy) and the extraction scope limit (first pages only). It does not mention failure modes for bad or unavailable arXiv IDs, which is the remaining gap for a network-dependent tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the action stated first and the cost/when-to-use caveat immediately after. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter fetch tool with a full schema and an output schema, the description covers purpose, cost, and invocation conditions adequately. Minor gaps are error behavior and how much text typically comes back, but the output schema covers return shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both arxiv_id and max_pages are already well documented in the schema with format examples and bounds. The phrase "first pages" loosely reinforces max_pages but adds no new parameter semantics, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: download a paper's PDF and extract text from its first pages. It implicitly contrasts with the abstract-level tools, but never names search_papers or get_paper, so the differentiation is by implication rather than explicit routing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"use only when the abstract is insufficient" is a clear positive condition plus an implicit exclusion, and "slow and bandwidth-heavy" reinforces the threshold for calling it. It stops short of naming the cheaper alternative tool the agent should try first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_papersB
Search arXiv and return a page of matching papers.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search text. arXiv field syntax is supported, e.g. 'retrieval augmented generation', 'au:hinton AND cat:cs.NE', 'ti:"chain of thought"'. | |
| sort_by | No | Ranking to apply. | relevance |
| category | No | Optional arXiv category filter, e.g. 'cs.AI'. | |
| max_results | No | Page size. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | The query that produced this result. |
| start | Yes | Zero-based offset into the full result set. |
| papers | Yes | The papers in this page. |
| sort_by | Yes | Sort order arXiv applied. |
| returned | Yes | Number of papers actually returned in this page. |
| total_results | Yes | Total matches arXiv reports, ignoring pagination. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It implies a read-only paginated search by saying 'return a page', but does not disclose rate limits, arXiv API constraints, or pagination mechanics. This is minimally adequate for a simple read operation but leaves notable gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. It states the action and result format efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is conceptually simple, the input schema is fully documented, and an output schema exists. The description is complete enough for an agent to call the tool correctly, though it could have added sibling-routing guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents query syntax, sort options, category filtering, and page size. The description adds no parameter meaning beyond what the schema provides, which is acceptable at this coverage level.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: search arXiv and return matching papers. An agent can distinguish it from get_paper and get_pdf_text, though the description does not explicitly name those siblings as alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance and does not mention when to choose get_paper, get_pdf_text, or category_trends instead. Usage is only implied by the word 'search'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
category_trends - First observed
get_paper - First observed
get_pdf_text - First observed
search_papers
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
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
Search GitHub, npm, PyPI, StackOverflow, ArXiv from one MCP — built for coding agents.
Search arXiv and ACL Anthology, retrieve citations and references, and browse web sources to accel…
- WauldoOAuthcom.wauldo
Stateless agentic tools over MCP: concept extraction, long-context, knowledge graph, planning.
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.453 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.-