Paper Search MCP
One-line summary: Paper Search MCP is an academic literature server that searches ~21 scholarly sources, then downloads and extracts text from the papers it finds.
Unified federated search —
search_papersqueries all configured sources concurrently, deduplicates results, and returns per-source stats and errors (optionalsourceslist,yearfilter for Semantic Scholar,max_results_per_source).Per-source search tools — Dedicated search functions for arXiv, PubMed, bioRxiv, medRxiv, Google Scholar, IACR ePrint, Semantic Scholar, Crossref, OpenAlex, PMC, CORE, Europe PMC, dblp, OpenAIRE, CiteSeerX, DOAJ, BASE, Zenodo, HAL, SSRN, and Unpaywall DOI lookup.
DOI/metadata lookup —
get_crossref_paper_by_doiandsearch_unpaywall(extracts the first DOI from text and returns at most one OA record).PDF downloads — Source-native
download_*tools for arXiv, bioRxiv, medRxiv, IACR, Semantic, and record-dependent ones for PMC, CORE, Europe PMC, CiteSeerX, DOAJ, BASE, Zenodo, HAL, OpenAIRE; PubMed, Crossref, dblp, OpenAlex, and SSRN explicitly return "not supported" messages.OA-first fallback chain —
download_with_fallbacktries source-native download, then OpenAIRE/CORE/Europe PMC/PMC discovery, then Unpaywall, then optional Sci-Hub (note: the schema defaultsuse_scihub=true, while the README says it is off unless explicitly enabled — setuse_scihub=falsefor strict OA behavior).Text extraction / read —
read_*_papertools fetch and parse PDFs into text for arXiv, bioRxiv, medRxiv, IACR, Semantic, and best-effort for CORE, Europe PMC, DOAJ, BASE, Zenodo, HAL, OpenAIRE, CiteSeerX; info-only or unsupported for PubMed, Crossref, dblp, OpenAlex, SSRN, and Sci-Hub.Optional API keys for richer results — Unpaywall email (required for Unpaywall), plus optional CORE, Semantic Scholar, OpenAlex, DOAJ, Zenodo, and IEEE keys; sources degrade gracefully without them.
Not available in this schema — OpenReview, Sci-Hub search, IEEE Xplore, ACM DL, Web of Science, and Scopus tools are described in the README but are not registered here (IEEE requires a key at startup anyway).
Enables searching and downloading academic papers from arXiv, returning results in a standardized format
Supports searching for academic papers through Google Scholar, integrated as one of the supported academic platforms
Provides search and download capabilities for academic papers from PubMed's database of biomedical literature
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., "@Paper Search MCP search arXiv for recent papers about large language models"
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.
Paper Search MCP
A Model Context Protocol (MCP) server for searching and downloading academic papers from multiple sources. The project follows a free-first strategy: prioritize open and public data sources, support optional API keys when they improve stability or coverage, and keep source-specific connectors extensible for advanced users.
Table of Contents
Related MCP server: Academic Paper MCP HTTP/SSE Server
Overview
paper-search-mcp is a Python-based tool for searching and downloading academic papers from various platforms. It provides tools for searching papers, downloading PDFs, and extracting text, making it ideal for researchers and AI-driven workflows. It can be used as an MCP server (for Claude Desktop and other MCP clients) or as a Claude Code skill with a CLI interface.
Project Principles
Free-First: Public and open sources are the default roadmap. Paid or restricted sources are not the core direction of this project.
Optional API Keys: API keys are supported only when they improve stability, rate limits, or metadata quality. The MCP should still be usable without them whenever possible.
LLM-Friendly Retrieval: Search results should be standardized, deduplicated, and as complete as possible for downstream LLM workflows.
Source Transparency: Different sources have different strengths. The MCP should make those tradeoffs explicit instead of pretending every source supports full-text retrieval.
MCP Authorization Compatibility
The bundled MCP server supports stdio (the default), sse, and streamable-http. Network transports bind to 127.0.0.1 by default. Optional OAuth protected-resource mode adds standard discovery, JWT bearer-token validation and required scopes to both HTTP transports, using an external authorization server.
Enable it with --auth oauth or PAPER_SEARCH_MCP_AUTH=oauth and the explicit issuer/JWKS/resource/audience/scope configuration in OAuth protected-resource setup. Invalid or incomplete HTTP auth settings fail startup. stdio remains independent of HTTP authentication. Local HTTP without OAuth configuration remains open; do not publish that listener directly. A protected remote deployment still needs TLS, rate limits and filesystem isolation. This feature does not host login/accounts or replace the external issuer's OAuth flow; live identity-provider interoperability must be validated for your deployment.
Features
Two-Layer Architecture:
Layer 1 (Unified Tooling): High-level
search_papersfor multi-source concurrent search & deduplication, anddownload_with_fallbackrelying on publisher open access links with sequential fallbacks.Layer 2 (Platform Connectors): Modular connectors for specific academic platforms (arXiv, PubMed, bioRxiv, Semantic Scholar, etc.) equipped with intelligent DOI extraction via regex text analysis or API fields.
Multi-Source Support: Search and download papers from arXiv, PubMed, bioRxiv, medRxiv, Google Scholar, IACR ePrint Archive, Semantic Scholar, Crossref, OpenAlex, PubMed Central (PMC), CORE, Europe PMC, dblp, OpenAIRE, CiteSeerX, DOAJ, BASE, Zenodo, HAL, SSRN, OpenReview, Unpaywall (DOI lookup), and optional Sci-Hub workflows.
Opt-in Fast Search: CLI search keeps broad coverage by default. Use
-s fast(OpenAlex, Crossref, arXiv, PubMed, Europe PMC) or-s fastest(OpenAlex and Crossref) when lower latency matters more than coverage.Standardized Output: Papers are returned in a consistent dictionary format via the
Paperclass.Free-First Design: Open and public sources are prioritized before any optional commercial or restricted integrations.
Optional API-Key Enhancement: Sources like Semantic Scholar can work better with a user-provided API key, but are not intended to force paid usage.
Discovery + Retrieval Workflow: Google Scholar and Crossref can be used for discovery and DOI backfilling, while open repositories and publisher links are used for lawful full-text resolution where available.
OA-First Fallback Chain:
download_with_fallbacknow follows source-native download → OpenAIRE/CORE/Europe PMC/PMC discovery → Unpaywall DOI resolution → optional Sci-Hub.Bounded reference lookups: OpenAlex references and citing papers from a DOI or OpenAlex ID, with explicit budgets and truncation metadata.
MCP Integration: Compatible with MCP clients for LLM context enhancement.
DeepSeek Harness (DSH) Integration: A dsh profile bundle (clone the repo,
npx @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add link:./dsh) exposing every tool asmcp__paper-search__*, with an optional guidance skill.Extensible Design: Easily add new academic platforms by extending the
academic_platformsmodule.
Source Strategy
The long-term goal is not to depend on a single search engine, but to combine multiple free and public sources with clear roles:
Open metadata backbone: Crossref, OpenAlex, Semantic Scholar, dblp, CiteSeerX, SSRN, Unpaywall (DOI-centric OA metadata).
Discipline-specific sources: arXiv, PubMed, PubMed Central, Europe PMC, IACR.
Open-access full-text sources: arXiv, PMC, CORE, OpenAIRE, DOAJ, BASE, Zenodo, HAL, publisher open-access links.
Discovery and DOI recovery: Google Scholar can be useful for finding titles, versions, and DOI clues when other public metadata sources are incomplete.
Recommended free-first roadmap:
Keep current public sources stable.
Add OpenAlex as a broad free metadata source.
Add PubMed Central and Europe PMC for stronger biomedical full-text access.
Add CORE and OpenAIRE for repository-based open-access retrieval.
Use Google Scholar mainly as a discovery fallback, not as the primary canonical source.
Platform Capability Matrix
This matrix reflects verified live-integration results from functional and end-to-end regression tests in this repository. Columns show the highest capability level observed under normal conditions.
Platform | Search | Download | Read | Notes |
arXiv | ✅ | ✅ | ✅ | Open API; reliable |
PubMed | ✅ | ❌ | ⚠️ info-only | Open API; reliable |
bioRxiv | ✅ | ✅ | ✅ | Open API; reliable |
medRxiv | ✅ | ✅ | ✅ | Open API; reliable |
Google Scholar | ⚠️ | ❌ | ❌ | Upstream bot-detection/rate limits can prevent search; reported as source errors |
IACR | ✅ | ✅ | ✅ | Open API; reliable |
Semantic Scholar | ✅ | ✅ (OA) | ✅ (OA) | Works without key (rate-limited); key improves limits; key rejection (403) retried automatically without key |
Crossref | ✅ | ❌ | ⚠️ info-only | Open API; reliable |
OpenAlex | ✅ | ❌ | ⚠️ info-only | Open API; free API key improves daily limits |
PMC | ✅ | ✅ (OA only) | ✅ (OA only) | OA PDFs only; direct download may be blocked by some proxy environments |
CORE | ✅ | ✅ (record-dependent) | ✅ (record-dependent) | Free key recommended; connector retries with backoff and falls back to key-less on 401/403 |
Europe PMC | ✅ | ✅ (OA) | ✅ (OA) | OA PDFs only; direct download may be blocked by some proxy environments |
dblp | ✅ | ❌ | ⚠️ info-only | Open API; reliable |
OpenAIRE | ✅ | ❌ | ❌ | Open API; retries 3× with escalating request profiles on transient 403 |
CiteSeerX | ⚠️ | ✅ (record-dependent) | ⚠️ | API endpoint intermittently unavailable / redirects to web archive |
DOAJ | ✅ | ⚠️ (URL-dependent) | ⚠️ (URL-dependent) | PDF availability varies by article; free key raises rate limits |
BASE | ⚠️ | ✅ (record-dependent) | ✅ (record-dependent) | OAI-PMH endpoint requires institutional IP registration; returns empty gracefully otherwise |
Zenodo | ✅ | ✅ (record-dependent) | ✅ (record-dependent) | Open API; reliable |
HAL | ✅ | ✅ (record-dependent) | ✅ (record-dependent) | Open API; reliable |
SSRN | ✅ (OpenAlex metadata) | ⚠️ best-effort | ⚠️ best-effort | Public discovery verified; SSRN page/PDF identity must be verified separately |
OpenReview | ✅ (anonymous API v2) | ⚠️ public-only | ⚠️ public-only | Search verified; exact-note lookup returned 403 in live PDF check; PDF success is mock-tested only |
Unpaywall | ✅ (DOI lookup) | ❌ | ❌ | Requires |
Sci-Hub (optional) | ⚠️ fallback-only | ✅ | ❌ | Optional; unstable mirrors; user responsibility |
IEEE Xplore 🔑 | ⚠️ configured metadata | ❌ | ❌ | Deterministic tests only; no live key-authenticated validation; metadata key does not grant full text |
ACM DL | ✅ (Crossref metadata) | ⚠️ | ⚠️ | Keyless search; direct PDF/read may be blocked by browser challenges; use OA fallback |
✅ = reliable in live tests. ⚠️ = works but subject to upstream instability or access restrictions. ❌ = not supported. 🔑 = key required. 🚧 = skeleton only.
Credential & API Key Requirements
All keys are optional unless noted. Configure them in ~/.config/paper-search-mcp/.env (preferred) or as shell exports.
Environment Variable | Provider | Required? | How to obtain |
| Unpaywall | Yes (Unpaywall disabled without it) | Any valid email; register at unpaywall.org |
| CORE | Recommended | Free at core.ac.uk/services/api |
| Semantic Scholar | Optional | Free at semanticscholar.org — improves rate limits |
| OpenAlex | Optional | Free at openalex.org/settings/api; increases the keyless daily budget 10x |
| OpenAlex | Optional | Contact email used in the OpenAlex |
| Google Scholar | Optional | Your HTTP/HTTPS proxy URL; does not guarantee access or remove provider limits |
| DOAJ | Optional | Free at doaj.org — raises hourly rate limit |
| Zenodo | Optional | Free at zenodo.org — required for private records |
| IEEE Xplore | Required to activate | Free at developer.ieee.org |
All variables follow the PAPER_SEARCH_MCP_<NAME> prefix scheme. Legacy names without the prefix (e.g. CORE_API_KEY, UNPAYWALL_EMAIL) are still supported for backward compatibility.
Known Upstream Limitations
Some search failures are caused by external provider instability, not by bugs in this project:
Source | Symptom | Cause | Workaround |
Google Scholar | Source error for HTTP/network failures, CAPTCHA, or persistent consent pages | Upstream rate limits, access checks, or connectivity | Reduce request frequency or use another public source; CAPTCHA is not solved automatically |
Semantic Scholar | 429 rate-limited responses | Anonymous access rate limit | Set |
OpenAlex | 403/429 or daily quota errors | Anonymous access daily limit | Set |
CORE | 500 / timeout errors | Unauthenticated rate limiting | Set |
OpenAIRE | Transient 403 responses | IP-based session rate limiting | Connector retries 3× per profile, escalating: plain session → XML Accept header → raw |
CiteSeerX | 404 via web archive redirect | PSU endpoint intermittently redirects to archive | No workaround; connector returns empty gracefully |
BASE | Search returns 0 results | OAI-PMH endpoint requires institutional IP registration | Register at base-search.net for API access; connector returns empty gracefully otherwise |
SSRN full text | HTTP 403 or identity unavailable | Public page/PDF delivery may be restricted | Search uses OpenAlex; download reports failure without login, redirects or HTML search fallback |
PMC / Europe PMC | PDF download ProxyError | Local proxy blocking direct HTTPS PDF download | Disable proxy or use |
Unpaywall | Skipped entirely |
| Set |
Google Scholar failures are exposed in errors.google_scholar by unified MCP
and CLI search, while successful sources still return their papers. Direct
Scholar searches raise GoogleScholarSearchError for those failures. A normal
empty result page still returns an empty list. If a later page fails, the source
is reported as failed rather than returning its earlier pages as complete.
Timeouts also raise a source error rather than implying that no papers exist.
After exhausted HTTP 403/429/503 retries or a CAPTCHA, the shared Scholar
connector enters a 60-second cooldown. Consecutive blocked searches extend it
exponentially up to 15 minutes; a valid upstream Retry-After can extend this
interval. A successful page resets the streak. Calls during cooldown fail
immediately with a retry interval and do not contact Scholar. Retries honor
valid Retry-After seconds or HTTP dates up to 24 hours. Longer instructions
pause automatic requests for the lifetime of this connector instead of retrying
earlier than the provider requested. Delays above 30 seconds are carried across
calls without sleeping in a worker. Concurrent calls share the same paced session. The connector does not rotate
identity between requests or solve CAPTCHAs. Cooldown state is process-local,
not a guarantee of an upstream quota or recovery after that interval.
For a survey, select alternative sources explicitly, for example MCP
search_papers(query, sources="google_scholar,openalex,semantic,crossref") or CLI
paper-search search "query" -s google_scholar,openalex,semantic,crossref.
Successful providers keep their own source labels and their papers even when
Scholar is cooling down. Alternatives have their own access/rate limits; they
are never silently returned as Google Scholar results.
Local PDF section extraction
extract_sections splits an already-downloaded PDF at recognized standalone
headings, preserving extracted text order and page spans with explicit limits
and truncation. Reads are confined to the configured download root; no network,
OCR, medical inference or new dependency is added. Labels are heuristic and may
be uncertain. See bounded PDF sections for access rules,
CLI usage and parser limitations.
arXiv PDF downloads and reads
arXiv downloads validate bare modern/legacy paper IDs, serialize and pace requests,
check HTTP status, stream at most 100 MiB to a same-directory temporary file, and
check the PDF header and parser before atomically replacing the destination.
A failed transfer or invalid PDF leaves an existing file unchanged. Downloads
use 10-second connect and 30-second read timeouts, not a hard total transfer
or parser runtime limit, and do not automatically retry denied responses.
read arxiv reports invalid/encrypted/image-only PDFs as errors rather than
successful empty output; it does not perform OCR or delete invalid cached files.
Optional Paid Platform Connectors (Phase 3)
IEEE Xplore provides opt-in metadata search, disabled until an existing API key is configured.
ACM Digital Library search is keyless and enabled by default, using Crossref metadata restricted to ACM DOI prefix 10.1145.
Platform | Env Var | Status |
IEEE Xplore |
| Metadata search with pagination; direct download/read remain unsupported |
ACM Digital Library | None | Crossref-backed search; PDF download/read depend on publisher access |
How to enable:
export PAPER_SEARCH_MCP_IEEE_API_KEY=<your_ieee_key> # free key at https://developer.ieee.org/With an IEEE key, ieee and its tools are registered at startup. See IEEE metadata limits and full-text boundaries. ACM (acm, search_acm, download_acm, and read_acm_paper) is always available. Legacy PAPER_SEARCH_MCP_ACM_API_KEY / ACM_API_KEY settings are no longer used and can be removed.
ACM downloads require an ACM DOI such as 10.1145/.... Publisher browser challenges may block scripted access; use download_with_fallback(source="acm", paper_id="10.1145/...", doi="10.1145/...") to try open repositories. read_acm_paper downloads a PDF into save_path before extracting text and can overwrite that file.
Free Source Expansion (Phase 4)
Additional public-source connectors are integrated into the MCP server:
zenodo: Official Zenodo REST API connector (search + record-dependent PDF/read support).hal: HAL public API connector (search + record-dependent PDF/read support).ssrn: OpenAlex-backed discovery with strict SSRN identity and validated best-effort public downloads.openreview: Anonymous public API v2 papers, excluding reviews/private notes; verified OpenReview-hosted PDF download/read.unpaywall: DOI-centric OA metadata source for standalone lookup (search_unpaywall) and fallback URL resolution.
SSRN integration remains compliance-first: it only attempts direct public PDF links exposed by SSRN pages. If login/restricted delivery is required, the connector returns a clear message instead of bypassing access controls.
Sci-Hub Notice
Sci-Hub support can remain available as an optional connector for users who explicitly choose to enable it, but it should not be treated as the default or recommended full-text path.
download_with_fallbackleaves Sci-Hub disabled by default. Passuse_scihub=trueonly when you explicitly choose to use it.Availability is unstable and mirrors change frequently.
Legal and policy risks vary by jurisdiction.
README and tool descriptions should clearly state that users are responsible for enabling and using it.
Open-access and publisher-permitted sources should be tried first whenever possible.
Installation
Choose the method that best fits your workflow. All methods support the same optional API keys.
Claude Code (Skill) — recommended for Claude Code users
Install as a Claude Code skill instead of an MCP server. This gives Claude automatic access to paper search when you mention finding papers, academic literature, etc. — no MCP configuration needed.
Prerequisites: uv and Claude Code.
Step 1 — Install the CLI:
uv tool install paper-search-mcpStep 2 — Install the skill:
mkdir -p ~/.claude/skills/paper-search
curl -fsSL https://raw.githubusercontent.com/openags/paper-search-mcp/main/claude-code/SKILL.md \
-o ~/.claude/skills/paper-search/SKILL.mdStep 3 (optional) — Configure API keys:
Create ~/.config/paper-search-mcp/.env for optional API keys (see Environment Variables).
That's it. Next time you start Claude Code, just ask it to find papers — the skill activates automatically. For example:
"Find me recent papers on CRISPR base editing"
"Search arxiv and semantic scholar for transformer attention mechanisms"
"Download the PDF for arxiv paper 2106.12345"
The skill uses a CLI (paper-search) that wraps the same library as the MCP server, outputting JSON for search/download and plain text for read.
paper-search download reports status: "ok" only when the returned path is a
readable, non-empty regular file with a PDF header. Connector error strings,
missing files, and saved HTML error pages produce a JSON error and exit code 1.
This lightweight check does not establish complete PDF integrity or paper identity;
those checks remain the responsibility of the source connector and the reader.
Choose sources explicitly when latency matters:
paper-search search "gender imbalance neuroscience references" -s fast -n 3
paper-search search "gender imbalance neuroscience references" -s fastest -n 3
paper-search search "gender imbalance neuroscience references" -s all -n 3
paper-search download semantic DOI:10.1038/s41593-020-0658-y -o ./downloadsThe CLI keeps -s all as its default broad source set. --exhaustive is an
accepted compatibility no-op because broad search is already the default.
Explicit -s selections always take precedence, including -s fast and
-s fastest. The broad preset includes the supported public sources;
optional paid sources are never added to these presets.
-s fast selects OpenAlex, Crossref, arXiv, PubMed, and Europe PMC. A nonblank
PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY (or legacy
SEMANTIC_SCHOLAR_API_KEY) also includes Semantic Scholar. -s fastest selects
only OpenAlex and Crossref. Presets are latency-oriented choices, not guarantees
of response time or exhaustive literature coverage. Anonymous Semantic Scholar
429 responses fail immediately; authenticated requests retain bounded retries.
Only selected searchers are constructed. Source lists and presets are honored
exactly: a DOI in the query never adds another source. Use -s unpaywall for a
DOI lookup, or include unpaywall explicitly in a comma-separated source list.
The broad all preset already includes it. MCP server search defaults are
unchanged.
To stop a slow source from holding up a CLI search, opt into a per-source deadline:
paper-search search "robot scientist" -s fast --source-timeout 45--source-timeout SECONDS must be positive and finite. It runs selected sources
in separate Python processes, at most four at once. Each source's budget starts
after OS process creation returns and includes Python/provider initialization,
search, serialization, and worker exit. Process creation, time waiting for a
worker slot, and process cleanup add overhead outside that budget. It is
not a deadline for the whole command. Timed-out workers are killed and reaped
before their slots are reused, so a blocked network call cannot hold up Python's
thread-executor shutdown. Successful sources keep their results and timed-out
sources appear in errors with a zero source_results count. Source selection,
labels, sorting, JSON fields, and partial-result exit status (0) are unchanged.
Subprocess startup adds overhead, especially for very small budgets. Without the
flag, existing connector-specific timeouts and in-process search are unchanged.
Sort search results by citation count or publication date:
paper-search search "transformer attention" --sources arxiv,semantic --sort citations
paper-search search "CRISPR" --sort date--sort relevance (the default) preserves the existing order: selected sources
in order, with each source's returned order unchanged. It does not compute a
cross-source relevance score. --sort citations orders highest counts first;
--sort date orders newest publication dates first. Sorting is client-side,
after deduplication, and only covers retrieved results (--max-results is per
source); it does not change source queries or search the full source collection
for its most-cited/newest papers. Ties retain their original order. Missing or
invalid values sort last; numeric citation strings are supported. Dates accept
ISO dates/timestamps, with naive timestamps and date-only values treated as UTC.
The default JSON output and selected sources are unchanged.
MCP tools from the CLI
paper-search tool calls the same registered tools as the MCP server, including
source-specific options and DOI lookup. Required arguments are positional;
optional arguments use kebab-case flags. Boolean flags use --flag and
--no-flag; omitted options retain their MCP defaults.
paper-search tool --help
paper-search tool --list # JSON tool list, schemas, and annotations
paper-search tool search_crossref --help
paper-search tool search_crossref "transformer attention" --filter from-pub-date:2024-01-01 --sort published --order desc --max-results 2
paper-search tool get_crossref_paper_by_doi 10.1038/nature12373
paper-search tool search_iacr "cryptography" --no-fetch-detailsObjects and lists return JSON; text and download paths return plain text. An
exception returns a JSON error with exit code 1; invalid CLI syntax exits with
code 2. A normal MCP result retains its original meaning, including error or
partial-result fields returned by the tool itself. --list shows only tools
enabled by the current configuration, so IEEE tools still require their API
key. The existing search, download, read, and sources commands are
unchanged. Tool calls keep the MCP tools' source selection and timeout behavior;
Sci-Hub fallback remains opt-in through --use-scihub.
Skill ZIP uploads and other Claude runtimes
The steps above install a local Claude Code skill at ~/.claude/skills/paper-search/SKILL.md, following the Claude Code skill layout. They do not require a ZIP upload.
GitHub's Download ZIP contains the entire repository, with the skill nested under paper-search-mcp-main/claude-code/. It is not a standalone skill archive. If an uploader reports that SKILL.md is nested too deeply, check the archive layout first. Anthropic's custom-skill packaging guide specifies a single skill folder at the archive root, with the skill file directly inside it:
paper-search-skill.zip
└── paper-search/
└── SKILL.mdTo create that layout for inspection or adaptation, run this from a repository checkout (requires Python 3; overwrites paper-search-skill.zip):
from zipfile import ZIP_DEFLATED, ZipFile
with ZipFile("paper-search-skill.zip", "w", compression=ZIP_DEFLATED) as archive:
archive.write("claude-code/SKILL.md", arcname="paper-search/SKILL.md")A reusable builder is also available: python scripts/build_skill_zip.py --output paper-search-skill.zip. It refuses to overwrite an existing file unless --force is supplied. Its archive layout, frontmatter, and byte-for-byte instruction contents are covered by offline tests.
This only packages the instructions; it does not bundle Python dependencies, install paper-search, or configure an MCP connection. The bundled skill expects a runtime that can execute the CLI and reach the academic services. Upload acceptance and execution in Claude web or another runtime have not been validated by this project. Check that runtime's current metadata, package-installation, network-access, and code-execution requirements before adapting the skill. If you want to use an MCP client instead, follow the MCP installation methods below; uploading a skill ZIP does not start or connect an external MCP server.
MCP Server Config file locations (for methods below)
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Method 1 — Smithery (one-command, recommended for Claude Desktop)
npx -y @smithery/cli install @openags/paper-search-mcp --client claudeSmithery automatically writes the correct config block for you. No manual JSON editing needed.
Method 2 — uvx (no install, always latest)
uvx runs the package directly from PyPI without a permanent install. Requires uv.
# Install uv (skip if already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh⚠️ macOS note:
uvxgenerated wrapper scripts rely onrealpath, which is not included in macOS by default. If you see arealpath: command not founderror, either install GNU coreutils (brew install coreutils) or use Method 3 (uv run) instead — it does not have this limitation.
Claude Desktop config:
{
"mcpServers": {
"paper-search-mcp": {
"command": "uvx",
"args": ["paper-search-mcp"],
"env": {
"PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
"PAPER_SEARCH_MCP_CORE_API_KEY": "",
"PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
"PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
"PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
"PAPER_SEARCH_MCP_IEEE_API_KEY": ""
}
}
}
}Method 3 — uv (persistent install)
uv tool install paper-search-mcpClaude Desktop config:
{
"mcpServers": {
"paper-search-mcp": {
"command": "uv",
"args": ["tool", "run", "paper-search-mcp"],
"env": {
"PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
"PAPER_SEARCH_MCP_CORE_API_KEY": "",
"PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
"PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
"PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
"PAPER_SEARCH_MCP_IEEE_API_KEY": ""
}
}
}
}Method 4 — pip (standard Python install)
pip install paper-search-mcpClaude Desktop config:
{
"mcpServers": {
"paper-search-mcp": {
"command": "python",
"args": ["-m", "paper_search_mcp.server"],
"env": {
"PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
"PAPER_SEARCH_MCP_CORE_API_KEY": "",
"PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
"PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
"PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
"PAPER_SEARCH_MCP_IEEE_API_KEY": ""
}
}
}
}If
pythonis not on your PATH, replace it with the full path (e.g./usr/bin/python3orC:\Python311\python.exe). Runwhich python3/where pythonto find it.
Method 5 — npx (via Smithery CLI, no local Python needed)
npx -y @smithery/cli run @openags/paper-search-mcpClaude Desktop config:
{
"mcpServers": {
"paper-search-mcp": {
"command": "npx",
"args": ["-y", "@smithery/cli", "run", "@openags/paper-search-mcp"],
"env": {
"PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
"PAPER_SEARCH_MCP_CORE_API_KEY": "",
"PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": ""
}
}
}
}Method 6 — Docker
docker build -t paper-search-mcp .
docker run --rm -i \
-e PAPER_SEARCH_MCP_UNPAYWALL_EMAIL=your@email.com \
-e PAPER_SEARCH_MCP_CORE_API_KEY=your_core_key \
paper-search-mcpClaude Desktop config:
{
"mcpServers": {
"paper-search-mcp": {
"command": "docker",
"args": ["run", "--rm", "-i", "paper-search-mcp"],
"env": {
"PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
"PAPER_SEARCH_MCP_CORE_API_KEY": "",
"PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
"PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
"PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
"PAPER_SEARCH_MCP_IEEE_API_KEY": ""
}
}
}
}Method 7 — Clone & run from source (development / recommended for macOS local)
This is the most reliable method on macOS — no wrapper scripts, no realpath issues.
# 1. Install uv (skip if already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Clone repo
git clone https://github.com/openags/paper-search-mcp.git
cd paper-search-mcp
# 3. Verify it runs (uv auto-resolves dependencies, no manual install needed)
uv run -m paper_search_mcp.serverClaude Desktop config (replace the directory path with your actual clone location):
{
"mcpServers": {
"paper-search-mcp": {
"command": "uv",
"args": [
"run",
"--directory", "/path/to/paper-search-mcp",
"-m", "paper_search_mcp.server"
],
"env": {
"PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
"PAPER_SEARCH_MCP_CORE_API_KEY": "",
"PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
"PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
"PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
"PAPER_SEARCH_MCP_IEEE_API_KEY": ""
}
}
}
}For example, if you cloned to /Users/mac/Pengsong/paper-search-mcp:
"args": ["run", "--directory", "/Users/mac/Pengsong/paper-search-mcp", "-m", "paper_search_mcp.server"]
uv runautomatically installs dependencies into an isolated environment on first run — nopip installorvenvneeded.
To run one shared network server instead of one stdio process per client:
paper-search-mcp --transport streamable-http --host 127.0.0.1 --port 8000 --path /mcpThe available transports are stdio, sse, and streamable-http. The default
remains stdio. The same network settings can be supplied with
PAPER_SEARCH_MCP_TRANSPORT, PAPER_SEARCH_MCP_HOST,
PAPER_SEARCH_MCP_PORT, and PAPER_SEARCH_MCP_PATH; command-line options take
precedence. With the default --auth none, binding to a non-loopback host such
as 0.0.0.0 exposes an unauthenticated server. For protected HTTP, configure
optional OAuth mode and keep the backend behind
TLS and appropriate deployment controls; otherwise use an authenticated gateway.
For active development, optionally install an editable copy:
uv venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
uv pip install -e ".[dev]"DeepSeek Harness (DSH)
Paper search is available inside DeepSeek Harness (dsh) as a profile bundle: it boots the MCP server and registers all its tools in any dsh profile as mcp__paper-search__*. The bundle only mounts a composition row — the MCP server itself is untouched.
Prerequisites: uv (the default launcher is uvx) and pnpm (dsh plugin forwards to pnpm). Commands below use the npx @deepseek-ai/dsh launcher (no global install needed); with a global dsh install, drop the prefix.
git clone https://github.com/openags/paper-search-mcp.git
cd paper-search-mcp
npx @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add link:./dshlink: updates the bundle configuration from the checkout. git pull does not update the separately launched PyPI server; see dsh/README.md for a source-checkout launcher and reproducible version selection. Replace web with your profile name; a missing profile is initialized automatically. Restart the profile (npx @deepseek-ai/dsh@0.2.0-rc.2 web, or relaunch) and the tools appear — e.g. mcp__paper-search__search_papers, mcp__paper-search__download_with_fallback, mcp__paper-search__search_arxiv.
API keys: just follow Environment Variables — the server auto-loads ~/.config/paper-search-mcp/.env. DSH deliberately scrubs credential-shaped ambient env vars from spawned processes, so shell exports do not reach the server; to forward variables explicitly, override the mcp-paper-search row in ~/.dsh/profiles/<name>/cordis.patch.yml (a config override replaces the whole object — see dsh/README.md for a complete example).
Optional skill with usage guidance (workflow, source table, tool mapping):
mkdir -p ~/.dsh/skills && cp -r dsh/skills/paper-search ~/.dsh/skills/Uninstall:
npx @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web remove paper-search-mcp-dsh
rm -rf ~/.dsh/skills/paper-searchRemoving the bundle reconciles its row out of the composition. It does not delete downloaded papers, package caches, or user-managed settings.
If you already run paper-search-mcp through your own @deepseek-ai/dsh-mcp-client row, remove that row (or give one of the two a distinct serverName) before adding the bundle — duplicate serverNames fail at load. The bundle package version tracks this checkout's Python project version; dsh/README.md documents alternate launchers (uv tool run, python -m, npx), environment forwarding, and development.
Environment Variables (.env file)
Instead of putting keys directly in the JSON config you can store them in the user config file (auto-loaded on startup):
mkdir -p ~/.config/paper-search-mcp
curl -fsSL https://raw.githubusercontent.com/openags/paper-search-mcp/main/.env.example \
-o ~/.config/paper-search-mcp/.env
$EDITOR ~/.config/paper-search-mcp/.envPAPER_SEARCH_MCP_UNPAYWALL_EMAIL=your@email.com
PAPER_SEARCH_MCP_CORE_API_KEY=
PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY=
PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN=
PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL=
PAPER_SEARCH_MCP_IEEE_API_KEY=To use a custom path: export PAPER_SEARCH_MCP_ENV_FILE=/absolute/path/to/.env
Legacy variable names without the
PAPER_SEARCH_MCP_prefix (e.g.CORE_API_KEY,UNPAYWALL_EMAIL) are still supported for backward compatibility.
Optional local search cache
Opt-in SQLite search caching adds TTL, size limits, status, and clearing. It is disabled by default and bypasses authenticated sources.
Contributing
We welcome contributions! Here's how to get started:
Fork the Repository: Click "Fork" on GitHub.
Clone and Set Up:
git clone https://github.com/yourusername/paper-search-mcp.git cd paper-search-mcp uv venv && source .venv/bin/activate uv pip install -e ".[dev]"Make Changes:
Add new platforms in
academic_platforms/.Update tests in
tests/.
Submit a Pull Request: Push changes and create a PR on GitHub.
Demo
TODO
Planned Academic Platforms
[√] arXiv
[√] PubMed
[√] bioRxiv
[√] medRxiv
[√] Google Scholar
[√] IACR ePrint Archive
[√] Semantic Scholar
[√] Crossref
[√] PubMed Central (PMC)
[√] CORE
[√] Europe PMC
[√] Sci-Hub warning and enablement docs
Development Tasks
[√] Fix Async search bugs and ensure reliable fast MCP events
[√] End-to-End full pipeline testing script (search, parse, download)
[√] Establish two-layer federated architecture (Layer 1 tool:
search_papers)[√] Ensure pervasive DOI extraction across metadata fields & abstract fallbacks
Citation graph & Paper relation context feature
[√] Expand full-stack OpenAlex provider
Priority Free and Open Sources
[√] PubMed Central (PMC)
[√] CORE
[√] OpenAlex
[√] Europe PMC
[√] OpenAIRE
[√] dblp
[√] CiteSeerX
[√] DOAJ
[√] BASE
[√] Zenodo
[√] HAL
[√] SSRN (discovery + best-effort full-text)
[√] Unpaywall (standalone DOI search source)
Optional and Non-Core Integrations
ResearchGate
JSTOR
ScienceDirect
Springer Link
[√] IEEE Xplore (optional skeleton — activate with
IEEE_API_KEY)[√] ACM Digital Library (keyless Crossref search; publisher PDF access varies)
Web of Science
Scopus
Star History
License
This project is licensed under the MIT License. See the LICENSE file for details.
Happy researching with paper-search-mcp! If you encounter issues, open a GitHub issue.
Explicit institutional metadata connectors
Web of Science Starter is available only through search_wos or an explicit
wos source (paper-search search 'TI=(machine learning)' -s wos). Supplying a
key does not add it to default, all, fast, or fastest searches. Supply
PAPER_SEARCH_MCP_WOS_API_KEY (legacy WOS_API_KEY also works) at runtime; the
connector does not create accounts or persist credentials. See
the institutional connector guide for limits,
errors, capability boundaries, and validation status.
Scopus is likewise explicit-only (-s scopus or MCP search_scopus), using
PAPER_SEARCH_MCP_SCOPUS_API_KEY (legacy SCOPUS_API_KEY). Metadata search defaults
to STANDARD. Abstract retrieval is available via paper-search read scopus ID
or MCP read_scopus_paper; ScienceDirect article retrieval requires explicit
--full-text / full_text=true and a verified DOI/PII match. The response labels
full_text, abstract_only, and unavailable separately. Neither connector's
live institutional entitlement has been validated by these fixture tests.
Available Tools
57 toolsdownload_arxivA
Download PDF of an arXiv paper.
Args: paper_id: arXiv paper ID (e.g., '2106.12345'). save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.
Inputs: paper_id (required), save_path. Returns: result
download_baseB
Download PDF for a paper from BASE.
Args: paper_id: BASE paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.
Inputs: paper_id (required), save_path. Returns: result
download_biorxivA
Download PDF of a bioRxiv paper.
Args: paper_id: bioRxiv DOI. save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.
Inputs: paper_id (required), save_path. Returns: result
download_citeseerxA
Download PDF for a paper from CiteSeerX.
Args: paper_id: CiteSeerX paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF or error message.
Inputs: paper_id (required), save_path. Returns: result
download_crossrefA
Attempt to download PDF of a CrossRef paper.
Args: paper_id: CrossRef DOI (e.g., '10.1038/nature12373'). save_path: Directory to save the PDF (default: './downloads'). Returns: str: Message indicating that direct PDF download is not supported.
Note: CrossRef is a citation database and doesn't provide direct PDF downloads. Use the DOI to access the paper through the publisher's website.
Inputs: paper_id (required), save_path. Returns: result
download_dblpC
Download PDF for a paper from dblp.
Note: dblp doesn't provide direct PDF access. This function returns an informative message.
Args: paper_id: dblp paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Message indicating that direct PDF download is not supported.
Inputs: paper_id (required), save_path. Returns: result
download_doajA
Download PDF for a paper from DOAJ.
Args: paper_id: DOAJ paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.
Inputs: paper_id (required), save_path. Returns: result
download_halB
Download PDF for a paper from HAL.
Args: paper_id: HAL paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.
Inputs: paper_id (required), save_path. Returns: result
download_iacrA
Download PDF of an IACR ePrint paper.
Args: paper_id: IACR paper ID (e.g., '2009/101'). save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.
Inputs: paper_id (required), save_path. Returns: result
download_medrxivA
Download PDF of a medRxiv paper.
Args: paper_id: medRxiv DOI. save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.
Inputs: paper_id (required), save_path. Returns: result
download_openaireA
Download PDF for a paper from OpenAIRE.
Args: paper_id: OpenAIRE paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF or error message.
Inputs: paper_id (required), save_path. Returns: result
download_openalexC
Download PDF for a paper from OpenAlex.
Args: paper_id: OpenAlex paper ID. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Error message, typically OpenAlex relies on extracted pdf_url instead of direct downloads.
Inputs: paper_id (required), save_path. Returns: result
download_pubmedB
Attempt to download PDF of a PubMed paper.
Args: paper_id: PubMed ID (PMID). save_path: Directory to save the PDF (default: './downloads'). Returns: str: Message indicating that direct PDF download is not supported.
Inputs: paper_id (required), save_path. Returns: result
download_scihubA
Download paper PDF via Sci-Hub (optional fallback connector).
Args: identifier: DOI, title, PMID, or paper URL. save_path: Directory to save the PDF. base_url: Sci-Hub mirror URL. Returns: Downloaded PDF path on success; error message on failure.
Inputs: identifier (required), save_path, base_url. Returns: result
download_semanticA
Download PDF of a Semantic Scholar paper.
Args: paper_id: Semantic Scholar paper ID, Paper identifier in one of the following formats: - Semantic Scholar ID (e.g., "649def34f8be52c8b66281af98ae884c09aef38b") - DOI: (e.g., "DOI:10.18653/v1/N18-3011") - ARXIV: (e.g., "ARXIV:2106.15928") - MAG: (e.g., "MAG:112218234") - ACL: (e.g., "ACL:W12-3903") - PMID: (e.g., "PMID:19872477") - PMCID: (e.g., "PMCID:2323736") - URL: (e.g., "URL:https://arxiv.org/abs/2106.15928v1") save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.
Inputs: paper_id (required), save_path. Returns: result
download_ssrnC
Download PDF for a paper from SSRN.
Note: SSRN connector is metadata-only and download is not supported.
Args: paper_id: SSRN paper identifier. save_path: Directory to save the PDF (unused). Returns: str: Error message from metadata-only SSRN connector.
Inputs: paper_id (required), save_path. Returns: result
download_with_fallbackA
Try source-native download, OA repositories, Unpaywall, then optional Sci-Hub.
Args: source: Source name (arxiv, biorxiv, medrxiv, iacr, semantic, crossref, pubmed, pmc, core, europepmc, citeseerx, doaj, base, zenodo, hal, ssrn). paper_id: Source-native paper identifier. doi: Optional DOI used for repository/unpaywall/Sci-Hub fallback. title: Optional title used for repository/Sci-Hub fallback when DOI is unavailable. save_path: Directory to save downloaded files. use_scihub: Whether to fallback to Sci-Hub after OA attempts fail. scihub_base_url: Sci-Hub mirror URL for fallback. Returns: Download path on success or explanatory error message.
Inputs: source (required), paper_id (required), doi, title, +3 more. Returns: result
download_zenodoA
Download PDF for a paper from Zenodo.
Args: paper_id: Zenodo paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.
Inputs: paper_id (required), save_path. Returns: result
get_crossref_paper_by_doiA
Get a specific paper from CrossRef by its DOI.
Args: doi: Digital Object Identifier (e.g., '10.1038/nature12373'). Returns: Paper metadata in dictionary format, or empty dict if not found.
Example: get_crossref_paper_by_doi("10.1038/nature12373")
Inputs: doi (required). Returns: result
read_arxiv_paperA
Read and extract text content from an arXiv paper PDF.
Args: paper_id: arXiv paper ID (e.g., '2106.12345'). save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.
Inputs: paper_id (required), save_path. Returns: result
read_base_paperB
Read and extract text content from a BASE paper.
Args: paper_id: BASE paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.
Inputs: paper_id (required), save_path. Returns: result
read_biorxiv_paperA
Read and extract text content from a bioRxiv paper PDF.
Args: paper_id: bioRxiv DOI. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.
Inputs: paper_id (required), save_path. Returns: result
read_citeseerx_paperA
Read and extract text content from a CiteSeerX paper.
Args: paper_id: CiteSeerX paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text or fallback abstract/error message.
Inputs: paper_id (required), save_path. Returns: result
read_crossref_paperA
Attempt to read and extract text content from a CrossRef paper.
Args: paper_id: CrossRef DOI (e.g., '10.1038/nature12373'). save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Message indicating that direct paper reading is not supported.
Note: CrossRef is a citation database and doesn't provide direct paper content. Use the DOI to access the paper through the publisher's website.
Inputs: paper_id (required), save_path. Returns: result
read_dblp_paperA
Attempt to read and extract text content from a dblp paper.
Note: dblp doesn't provide direct paper content access. This function returns an informative message.
Args: paper_id: dblp paper identifier. save_path: Directory where the PDF would be saved (unused). Returns: str: Message indicating that direct paper reading is not supported.
Inputs: paper_id (required), save_path. Returns: result
read_doaj_paperA
Read and extract text content from a DOAJ paper.
Args: paper_id: DOAJ paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.
Inputs: paper_id (required), save_path. Returns: result
read_hal_paperA
Read and extract text content from a HAL paper.
Args: paper_id: HAL paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.
Inputs: paper_id (required), save_path. Returns: result
read_iacr_paperA
Read and extract text content from an IACR ePrint paper PDF.
Args: paper_id: IACR paper ID (e.g., '2009/101'). save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.
Inputs: paper_id (required), save_path. Returns: result
read_medrxiv_paperA
Read and extract text content from a medRxiv paper PDF.
Args: paper_id: medRxiv DOI. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.
Inputs: paper_id (required), save_path. Returns: result
read_openaire_paperA
Attempt to read and extract text content from an OpenAIRE paper.
Args: paper_id: OpenAIRE paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text or error message.
Inputs: paper_id (required), save_path. Returns: result
read_openalex_paperC
Attempt to read and extract text content from an OpenAlex paper.
Args: paper_id: OpenAlex paper ID. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Message indicating that direct paper reading is not supported natively.
Inputs: paper_id (required), save_path. Returns: result
read_pubmed_paperD
Read and extract text content from a PubMed paper.
Args: paper_id: PubMed ID (PMID). save_path: Directory where the PDF would be saved (unused). Returns: str: Message indicating that direct paper reading is not supported.
Inputs: paper_id (required), save_path. Returns: result
read_semantic_paperA
Read and extract text content from a Semantic Scholar paper.
Args: paper_id: Semantic Scholar paper ID, Paper identifier in one of the following formats: - Semantic Scholar ID (e.g., "649def34f8be52c8b66281af98ae884c09aef38b") - DOI: (e.g., "DOI:10.18653/v1/N18-3011") - ARXIV: (e.g., "ARXIV:2106.15928") - MAG: (e.g., "MAG:112218234") - ACL: (e.g., "ACL:W12-3903") - PMID: (e.g., "PMID:19872477") - PMCID: (e.g., "PMCID:2323736") - URL: (e.g., "URL:https://arxiv.org/abs/2106.15928v1") save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.
Inputs: paper_id (required), save_path. Returns: result
read_ssrn_paperB
Read paper content from SSRN.
Note: SSRN connector is metadata-only and read is not supported.
Args: paper_id: SSRN paper identifier. save_path: Directory where the PDF is/will be saved (unused). Returns: str: Error message from metadata-only SSRN connector.
Inputs: paper_id (required), save_path. Returns: result
read_zenodo_paperA
Read and extract text content from a Zenodo paper.
Args: paper_id: Zenodo paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.
Inputs: paper_id (required), save_path. Returns: result
search_arxivB
Search academic papers from arXiv.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_baseA
Search academic papers from BASE (Bielefeld Academic Search Engine).
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_biorxivA
Search academic papers from bioRxiv.
Note: bioRxiv API filters by category name within the last 30 days, not full-text keyword search. Use a category keyword such as 'bioinformatics', 'neuroscience', 'cell biology', etc.
Args: query: Category name to filter by (e.g., 'bioinformatics', 'neuroscience'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_citeseerxB
Search academic papers from CiteSeerX digital library.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_coreB
Search academic papers from CORE.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_crossrefA
Search academic papers from CrossRef database.
CrossRef is a scholarly infrastructure organization that provides persistent identifiers (DOIs) for scholarly content and metadata. It's one of the largest citation databases covering millions of academic papers, journals, books, and other scholarly content.
Args: query: Search query string (e.g., 'machine learning', 'climate change'). max_results: Maximum number of papers to return (default: 10, max: 1000). filter: CrossRef filter string (e.g., 'has-full-text:true,from-pub-date:2020'). sort: Sort field ('relevance', 'published', 'updated', 'deposited', etc.). order: Sort order ('asc' or 'desc'). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results, filter, sort, +1 more. Returns: result
search_dblpA
Search academic papers from dblp computer science bibliography.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_doajA
Search academic papers from DOAJ (Directory of Open Access Journals).
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_europepmcA
Search academic papers from Europe PMC.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_google_scholarB
Search academic papers from Google Scholar.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_halB
Search academic papers from HAL open archive.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_iacrA
Search academic papers from IACR ePrint Archive.
Args: query: Search query string (e.g., 'cryptography', 'secret sharing'). max_results: Maximum number of papers to return (default: 10). fetch_details: Whether to fetch detailed information for each paper (default: True). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results, fetch_details. Returns: result
search_medrxivA
Search academic papers from medRxiv.
Note: medRxiv API filters by category name within the last 30 days, not full-text keyword search. Use a category keyword such as 'infectious_diseases', 'cardiovascular_medicine', 'oncology', etc.
Args: query: Category name to filter by (e.g., 'infectious_diseases', 'oncology'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_openaireA
Search academic papers from OpenAIRE European Open Access infrastructure.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_openalexA
Search academic papers from OpenAlex.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_papersA
Unified top-level search across all configured academic platforms.
Args: query: Search query string. max_results_per_source: Max results to fetch from each selected source. sources: Comma-separated source names or 'all'. Available: arxiv,pubmed,biorxiv,medrxiv,google_scholar,iacr,semantic,crossref,openalex,pmc,core,europepmc,dblp,openaire,citeseerx,doaj,base,zenodo,hal,ssrn,unpaywall year: Optional year filter for Semantic Scholar only. Returns: Aggregated dictionary with per-source stats, errors, and deduplicated papers.
Inputs: query (required), max_results_per_source, sources, year. Returns: result
search_pmcB
Search academic papers from PubMed Central (PMC).
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_pubmedB
Search academic papers from PubMed.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_semanticA
Search academic papers from Semantic Scholar.
Args: query: Search query string (e.g., 'machine learning'). year: Optional year filter (e.g., '2019', '2016-2020', '2010-', '-2015'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), year, max_results. Returns: result
search_ssrnA
Search metadata records from SSRN.
Note: SSRN connector is metadata-only and does not support direct PDF download.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
search_unpaywallA
Lookup a DOI via Unpaywall and return OA metadata.
Unpaywall is DOI-centric and does not support generic keyword search.
This tool extracts the first DOI from query and returns at most one record.
Args: query: DOI string or text containing a DOI. max_results: Kept for API consistency; Unpaywall returns max 1 record. Returns: List with one paper metadata dict when DOI is resolvable, else empty list.
Inputs: query (required), max_results. Returns: result
search_zenodoB
Search academic papers from Zenodo open repository.
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Inputs: query (required), max_results. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 57 tools
The tools are highly ambiguous due to extensive overlap across sources; for example, download_arxiv and download_semantic both download PDFs, and search_arxiv and search_semantic both search papers, making it difficult for an agent to choose the right tool without deep knowledge of each source. The descriptions clarify the source but not the functional distinction, leading to potential misselection when the agent doesn't care about the specific source.
Tool names follow a perfectly consistent verb_noun pattern throughout, with all tools using snake_case and clear prefixes like download_, read_, search_, and get_. This predictability makes it easy for an agent to understand the action and target, such as download_arxiv_paper or search_crossref.
With 57 tools, the count is extremely high for a paper search server, far exceeding the typical well-scoped range of 3-15 tools. This creates a bloated and overwhelming interface that is difficult for an agent to navigate efficiently, as many tools are redundant across sources rather than adding unique functionality.
The tool set is highly complete for the domain of paper search and retrieval, covering download, read, search, and metadata retrieval across numerous academic sources. There are no obvious gaps; the tools provide full lifecycle coverage from discovery to content extraction, including a unified search tool for convenience.
Maintenance
Related MCP Connectors
Academic research MCP server for paper search, citation checks, graphs, and deep research.
Zotero MCP server for Claude and ChatGPT: search, citations, safe writes, PDF passages and pages.
Search and download academic papers from arXiv, PubMed, bioRxiv, medRxiv, Google Scholar, Semantic…
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that allows Claude AI to search, explore, and compare arXiv papers efficiently through a custom-built local server.419MIT
- AlicenseNot gradedqualityDmaintenanceA MCP server for academic literature retrieval, aggregating multiple data sources like arXiv, Crossref, OpenAlex, PubMed, and Semantic Scholar to provide search, details, citations, trends, and recommendations.4MIT
- FlicenseAqualityDmaintenanceA local MCP server for searching and reading arXiv papers, enabling paper search, retrieval, and summarization through Claude.6-
- AlicenseNot gradedqualityDmaintenanceMCP server for searching, downloading, and reading academic papers from multiple sources such as arXiv, Google Scholar, and Elsevier.5MIT
Appeared in Searches
- Official Consensus.app MCP server for AI-powered research and academic search
- A server for accessing full-text research articles via DOI
- A server for finding academic papers to perform sentiment analysis and develop a consumer-facing voice chatbot
- A tool for finding relevant academic publications and open-source projects on GitHub
- A server for finding academic and scholarly articles