literature-search-mcp
A standalone MCP server that searches multiple scholarly metadata providers (PubMed, Europe PMC, bioRxiv, Crossref, OpenAlex, Semantic Scholar, arXiv), deduplicates results, and returns ranked literature with optional open-access full-text retrieval from Europe PMC.
README
literature-search-mcp
A standalone Node.js 22 TypeScript MCP server that searches seven scholarly metadata providers over stdio, normalizes records, deduplicates them, and applies deterministic reciprocal-rank fusion.
For ZIP packaging, recipient installation, Claude Code registration, permissions, updates, troubleshooting, and uninstallation, see the Chinese guide: INSTALL_ZH.md.
MCP tools
The server registers exactly three tools:
literature_search— search selected providers or all providers by default.literature_sources— list supported providers, limitations, and whether optional environment variables are configured.literature_get_fulltext— fetch open-access full text from Europe PMC (PMC Open Access subset) for a paper identified bypmcid,pmid, ordoi, returning title, abstract, structured sections, a joined plain-textfull_text, and metadata.
literature_search accepts:
| Input | Type | Default | Notes |
|---|---|---|---|
query |
string | required | Search expression. Rich syntax (fielded, wildcard, Boolean) is passed through to providers that support it natively (PubMed [Field], Europe PMC FIELD:, arXiv field:); Crossref, OpenAlex, Semantic Scholar, and bioRxiv receive a sanitized keyword form so wildcards/fields never break them. |
limit |
integer 1–50 | 10 |
Maximum fused results returned. |
sources |
source ID array | all seven | pubmed, europepmc, biorxiv, crossref, openalex, semantic-scholar, arxiv |
year_from |
integer | unset | Inclusive lower publication year. |
year_to |
integer | unset | Inclusive upper publication year. |
open_access |
boolean | unset | Require positive open-access or PDF evidence. |
abstract_max_chars |
integer 1–3000 | 3000 |
Maximum characters returned for each provider-supplied abstract or summary. |
Results include title, cleaned provider-supplied abstracts or summaries capped at abstract_max_chars, normalized identifiers, canonical/PDF URLs, year, authors and venue when available, reciprocal-rank score, source evidence, and per-source statuses. literature_search never downloads full text, fetches citation graphs, or retrieves references/citations. Open-access full text is available through the separate literature_get_fulltext tool (Europe PMC OA subset only; input pmcid/pmid/doi; output title, abstract, structured sections, and a joined plain-text full_text capped by max_chars).
literature_get_fulltext accepts:
| Input | Type | Default | Notes |
|---|---|---|---|
pmcid |
string | unset | PubMed Central identifier (e.g. PMC1234567); at least one of pmcid/pmid/doi is required. |
pmid |
string | unset | PubMed identifier; resolved to a PMCID via Europe PMC search. |
doi |
string | unset | DOI; resolved to a PMCID via Europe PMC search. |
max_chars |
integer 1000–1000000 | 100000 |
Maximum characters in the joined full_text string; sections and abstract are returned in full. |
Papers without open-access full text in Europe PMC return a structured status: "not_found" with empty content; transport or server failures return status: "error" with a sanitized error detail. Full text is never persisted to search history.
Requirements and commands
Node.js 22 or newer is required. Dependencies are pinned in package-lock.json.
npm run typecheck
npm test
npm run build
npm start
The build emits dist/server.js and dist/cli.js. npm start runs the stdio server; stdout is reserved for MCP protocol messages and operational logging goes to stderr.
An MCP client can launch the built server with a command equivalent to:
{
"command": "node",
"args": ["/absolute/path/to/literature-search-mcp/dist/server.js"]
}
This project does not modify or register MCP client configuration itself.
Optional provider configuration
The server starts and searches without credentials. Optional environment variables improve provider etiquette or rate limits:
OPENALEX_MAILTO
OPENALEX_API_KEY
SEMANTIC_SCHOLAR_API_KEY
CROSSREF_MAILTO
NCBI_TOOL
NCBI_EMAIL
NCBI_API_KEY
No Synthetic Sciences contact address is used as a fallback. PubMed always sends a tool name (literature-search-mcp unless NCBI_TOOL is set); email parameters are sent only when explicitly configured.
See PROVIDERS.md for API-specific behavior and limitations.
Ranking and deduplication
Providers are always processed in this fixed order:
- PubMed
- Europe PMC
- bioRxiv/medRxiv
- Crossref
- OpenAlex
- Semantic Scholar
- arXiv
Deduplication checks normalized DOI, PMID, versionless arXiv ID, then normalized title. Records with conflicting values for the same strong identifier type are never merged. Ranking uses reciprocal-rank fusion with a fixed constant (k = 60), followed by stable source/rank/title tie-breakers; provider-native scores do not affect ordering.
HTTP behavior
All provider traffic uses Node's native fetch with:
- 30-second per-attempt timeout;
- three retries after the initial attempt for HTTP 408, 429, 5xx, network failures, and internal timeouts;
- numeric and HTTP-date
Retry-Aftersupport; - exponential backoff;
- caller cancellation propagation;
- per-host request pacing and concurrency controls;
- a maximum five-minute, 256-entry in-memory GET cache;
- typed, sanitized errors that omit query strings and response bodies.
Search history
Each completed search appends one JSON object to:
${XDG_STATE_HOME:-~/.local/state}/literature-search-mcp/history.jsonl
History records query parameters, source statuses, result identifiers, ranks, evidence, and URLs. It does not store abstracts, authors, provider credentials, or secrets.
Clear history with the compiled CLI:
node dist/cli.js clear-history
# or
npm run history:clear
Tests
npm test is offline and uses node:test, fixtures, fake fetch implementations, and an in-memory MCP transport. It covers HTTP behavior, every provider parser, aggregation/deduplication, history, the search service, and exact MCP tool registration.
The live smoke test is opt-in:
npm run test:live
It performs a small Crossref query and is not part of the offline suite.
License and attribution
Apache License 2.0. See LICENSE and NOTICE. This project adapts concepts from OpenScience literature connectors but does not import the OpenScience runtime.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.