Semantic Scholar MCP Server
[CI]
[codecov]
[PyPI version]
[PyPI downloads/30d]
[DOI]
[Provenance: SLSA + SBOM]
[Docker]
[GitHub Release]
[License: MIT]
[MCP]
[Python 3.11-3.13 recommended]
[Glama score]
[Awesome MCP Servers]
A 14-tool Semantic Scholar MCP server for academic research workflows. Direct access to 200M+ papers from Semantic Scholar — paper search, citation graph traversal, author profiles, and recommendations — from any Model Context Protocol client (e.g., Claude Desktop, Claude Code, Cursor, Cline, Continue, and others).
Every release ships verifiable supply-chain provenance: Sigstore-signed SLSA build-provenance attestations on the wheel, sdist, and container image; PEP 740 attestations on the PyPI upload; and a CycloneDX SBOM — so you can prove the artifact you installed was built from this repo. See Provenance & supply chain.
Author: Santiago Maniches · ORCID 0009-0005-6480-1987 · TOPOLOGICA LLC
Research authorship: Santiago Maniches independently directs and maintains this project and is the sole scientific author of its research contributions. AI-assisted tools have supported coding, documentation, and internal review; they do not constitute scientific coauthors or independent validation. Semantic Scholar content and reused software and methods are attributed to their respective sources.
Quick start
Runtime support (October 2026). Python 3.11–3.13 are the recommended,
CI-tested interpreters. Python 3.10 reached upstream end of life on October 1,
2026 and no longer receives security fixes. The package retains
Requires-Python >=3.10 and a legacy Python 3.10 compatibility test to avoid
breaking existing installs, but Python 3.10 is not a security-supported
runtime. Migrate deployed clients to Python 3.11 or newer. Python 3.14+
remains outside the declared CI verification matrix; installability is not a
claim of tested support. The development dependency security audit runs on
Python 3.12 and checks its hash-pinned closure, not every legacy environment.
No API key is needed to start. Set SEMANTIC_SCHOLAR_API_KEY to use your
assigned Semantic Scholar quota and avoid the shared unauthenticated pool.
Semantic Scholar currently assigns introductory API keys a 1 request/second
limit across all endpoints. Claude Desktop, Docker, pip, and remote
(Streamable HTTP) setups are in Installation.
Provenance & supply chain
A research tool is only as trustworthy as the chain from its source to the
binary you run. Every release of this server ships cryptographically
verifiable supply-chain evidence, all generated in CI from the tagged commit:
Verify the wheel and the container image against their attestations with the
GitHub CLI:
The full supply-chain posture, including the known-limitations list, is in
SECURITY.md. This is release-time provenance (proving how
the artifact was built); the server does not currently attach a per-response
receipt to individual API results.
How it compares
There is no public Semantic Scholar MCP standard, so the most useful
comparison is against the obvious alternative: calling the
Semantic Scholar REST API yourself from an
agent. Everything in the right-hand column is plumbing this server already owns
and the caller would otherwise reimplement.
Installation
Option 1: One-Line Install (Recommended)
Option 2: Claude Code
Option 3: Claude Desktop (Windows)
Add to %APPDATA%\Claude\claude_desktop_config.json:
Option 4: Claude Desktop (macOS)
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
Option 5: pip / From Source
Option 6: Docker
Option 7: Remote server (Streamable HTTP) — requires ≥ 1.5.0
See Remote access (Streamable HTTP) for client
configuration, per-request API keys, and deployment guidance.
Note: An API key is optional for most public Semantic Scholar endpoints. This
server conservatively throttles unkeyed requests to about one per second,
but anonymous users share an upstream pool. Semantic Scholar can return HTTP
429 even when this server respects its local interval. For dependable,
sustained research workflows, configure an assigned API key.
See Known Limitations.
Architecture
Module responsibilities (src/semantic_scholar_mcp/):
Design choices worth knowing
- Single
httpx.AsyncClient per process. Created lazily, closed in the FastMCP lifespan teardown. Amortizes connection setup; respects keep-alive limits. The lifespan is reference-counted: under the Streamable HTTP transport the SDK enters it per request, so teardown only runs when the last holder exits.
- Rate limit is enforced at the client, not the API. A semaphore + last-request timestamp ensures we never exceed the per-tier interval even when the MCP host issues tool calls in parallel.
- Retry is bounded and jittered. Up to
MAX_RETRIES = 3, base 1 s, capped at 30 s. Honors Retry-After when present.
- Errors are typed. Status codes map onto a small exception hierarchy so callers can branch on
AuthenticationError vs RateLimitError vs NotFoundError instead of parsing strings.
- Input validation is pre-flight. Paper IDs are checked before any outbound request; bad IDs never hit the wire.
- Version is single-source.
__version__ is derived from importlib.metadata.version("s2-mcp-server"), so bumping pyproject.toml is sufficient; release-please bumps the manifest, server.json (×2 paths), CITATION.cff, and .zenodo.json in lockstep on every release.
Configuration
API Key Options
You can provide your API key in three ways:
-
Environment Variable (recommended for persistent use):
-
Per-request HTTP header (Streamable HTTP transport only): send
x-api-key: your-key with each request — see
Remote access (Streamable HTTP).
-
Per-Request Parameter (overrides env var):
Deprecated: per-request api_key is deprecated and will be removed
in v2.0.0. Tool-call arguments may be visible in MCP transcripts, client
logs, and the LLM's tool-call history. Use the SEMANTIC_SCHOLAR_API_KEY
environment variable instead. See SECURITY.md for details.
Get a free API key at: https://www.semanticscholar.org/product/api
Claude Desktop Setup
Add to your Claude Desktop config file:
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Then restart Claude Desktop.
Remote access (Streamable HTTP)
stdio remains the default transport. --transport http serves the same 14
tools over the MCP Streamable HTTP transport,
which is what remote clients — claude.ai custom connectors, Smithery
listings, mcp-remote bridges — connect to.
Requires s2-mcp-server ≥ 1.5.0. Earlier releases (≤ 1.4.0) do not
parse CLI flags: they silently ignore --transport http and start a stdio
server instead, never opening the port.
Flags and environment variables
CLI flags beat environment variables. The server is stateless and returns
JSON by default — the configuration recommended for production Streamable
HTTP deployments — and no tool relies on sessions, streaming, or
server-initiated messages, so there is no functional trade-off.
Per-request API keys (bring your own key)
When served over HTTP, each request may carry its own Semantic Scholar API
key; concurrent users never share or observe each other's keys. Sources, in
precedence order:
x-api-key HTTP header (recommended)
SEMANTIC_SCHOLAR_API_KEY query parameter (Smithery session config)
api_key query parameter
- Legacy base64
?config= parameter (older Smithery deployments)
A request without a key falls back to the server's SEMANTIC_SCHOLAR_API_KEY
environment variable, or to keyless public-tier access.
Client configuration
Claude Code
JSON config (clients that accept a url)
claude.ai custom connectors require a public HTTPS URL and accept either
authless servers or OAuth — API keys in the connector URL are not supported
by claude.ai. Host the server with the key supplied server-side
(SEMANTIC_SCHOLAR_API_KEY env var) and register the public /mcp URL as
the connector.
Smithery lists remote servers by URL (smithery mcp publish <url>); the
per-request key extraction above is compatible with Smithery session config
out of the box.
Security notes
- The HTTP transport performs no authentication of inbound callers. The
default bind is loopback (
127.0.0.1). Expose it publicly only behind a
TLS-terminating reverse proxy.
- The built-in Uvicorn request access log is disabled to avoid recording URL
credentials, but proxies, gateways and other upstream systems may still log
full request URLs. Query parameters, including base64
?config=, are not
safe places for secrets. Prefer the x-api-key header or a server-side
environment variable. See SECURITY.md.
- See SECURITY.md for the project's broader threat model.
Supported ID Formats
The server accepts the following paper identifier formats:
Tools Reference
1. semantic_scholar_search_papers
Search for academic papers with advanced filters.
Parameters:
Example:
JSON Example:
2. semantic_scholar_get_paper
Get detailed information about a specific paper.
Parameters:
Example:
JSON Example:
Citation and reference pages are independent. In JSON mode, requested directions
retain the existing citations / references arrays and additionally return
citations_page / references_page metadata with offset and next.
When next is non-null, use it as that direction's *_offset on the next
call with the same paper ID and limit. A null next means no continuation was
advertised by Semantic Scholar. Markdown mode prints a continuation hint when
one is available. Never treat a first page as a complete citation graph.
3. semantic_scholar_search_authors
Search for academic authors by name.
Parameters:
Example:
JSON Example:
4. semantic_scholar_get_author
Get author profile with publications.
Parameters:
Example:
JSON Example:
5. semantic_scholar_recommendations
Get AI-powered paper recommendations based on a seed paper.
Parameters:
Example:
JSON Example:
6. semantic_scholar_bulk_papers
Retrieve multiple papers in a single request (max 500).
Parameters:
Example:
JSON Example:
7. semantic_scholar_bulk_search
Search papers with sorting and cursor-based pagination for large result sets.
Unlike search_papers, supports a sort order and returns a token for
paging through all results.
Parameters:
JSON Example:
Returns: total result count, the page of papers, and a token for the
next page (when more results exist).
8. semantic_scholar_export_citation
Export a citation for a paper in BibTeX format.
Parameters:
JSON Example:
Returns: the BibTeX string for the requested paper.
9. semantic_scholar_match_paper
Find the single best paper matching a title string. Returns a numeric
matchScore alongside the matched paper.
Parameters:
JSON Example:
Returns: the best-matching paper plus its matchScore, or "No matching
paper found." if no match.
10. semantic_scholar_paper_authors
Get full author profiles for a paper's authors (richer than the abbreviated
author list returned by get_paper).
Parameters:
JSON Example:
Returns: the list of full author records for the paper.
11. semantic_scholar_author_batch
Retrieve multiple authors in a single request (max 1000).
Parameters:
JSON Example:
Returns: counts of requested / retrieved, the retrieved author
records, and a not_found list of IDs the API did not return.
12. semantic_scholar_multi_recommend
Get recommendations using multiple positive (and optional negative) example
papers.
Parameters:
JSON Example:
Returns: the recommended papers plus an echo of the positive/negative
seeds used.
13. semantic_scholar_snippet_search
Search within paper full text and return text snippets with surrounding
context. Heavily rate-limited without an API key.
Parameters:
JSON Example:
Returns: matching snippets, each with the source paper title, section,
and a short text excerpt.
14. semantic_scholar_status
Check server health and API connectivity status.
Parameters: None
Example:
Response:
Rate Limits
Semantic Scholar's current API guidance says introductory API keys receive
1 request/second across all endpoints, while some keys may receive a higher
rate after review. Unauthenticated requests share upstream capacity and may be
throttled during heavy use.
The server therefore uses these conservative client-side defaults:
If Semantic Scholar has explicitly assigned your key a different quota, set
SEMANTIC_SCHOLAR_MIN_SECONDS_BETWEEN_REQUESTS to an interval that stays
below that ceiling. For example, a reviewed 10 RPS quota should use an interval
slightly greater than 0.1 seconds rather than assuming every API key has that
rate. The setting is process-wide, so remote deployments accepting multiple
user-provided keys should configure it for the slowest accepted quota.
The server automatically handles rate limiting with:
- Request serialization to enforce minimum intervals
- Exponential backoff retry for 429 (rate limit), 502 (bad gateway), and 503 (service unavailable) errors
- Maximum 3 retries with jitter
Development
Security
API keys are never persisted to disk by the server. When the server makes
authenticated requests, the key is sent only to api.semanticscholar.org
over HTTPS as the x-api-key header. No telemetry is sent to any third
party. Under the default stdio transport the server runs locally on your
machine; if you connect to a remotely hosted instance over
Streamable HTTP, your per-request key also
transits that endpoint's operator before being forwarded to Semantic Scholar
— only send keys to remote endpoints you trust, and only over HTTPS.
Prefer the SEMANTIC_SCHOLAR_API_KEY environment variable over the
per-request api_key tool parameter. The per-request parameter is
deprecated (removal planned for v2.0.0) because tool-call arguments may
be visible in MCP transcripts and client logs. See SECURITY.md
for vulnerability reporting and the known-limitations list.
Related MCP servers by the same author
alphafold-sovereign-mcp — Model Context Protocol server for AlphaFold DB and other public biomedical data sources, with a local SQLite knowledge graph (pip install alphafold-sovereign-mcp).
uniprot-mcp — Model Context Protocol server for UniProt Swiss-Prot and TrEMBL (pip install uniprot-mcp-server).
License
MIT License - see LICENSE file.
Author
Santiago Maniches
Contributing
Contributions welcome! Please read our Contributing Guidelines.
Support
Built by TOPOLOGICA LLC