pubmed-stream: PubMed search and PubMed Central full-text download, for researchers and their AI assistants
[PyPI version]
[Python 3.9+]
[License: MIT]
[Documentation]
pubmed-stream is an open-source Python library and command-line tool that takes a PubMed search to a knowledge graph of the literature. It is built on NCBI's official E-utilities API, works from the command line or Python, and needs nothing beyond requests. AI assistants use it too: it is a plugin for Claude Code and Codex, and a PubMed MCP server for them and Gemini CLI, so you can ask a research question in plain English and get an answer that cites only papers the assistant downloaded and read.
With it you can:
- Search PubMed and PubMed Central (PMC) with field tags and MeSH (Medical Subject Headings), and see how many papers a search finds before downloading anything (section 2)
- Bulk-download full-text articles from PubMed Central as JSON, with metadata, references and text or JATS XML, and the PubMed abstracts of articles without free full text (section 1)
- Export citations as BibTeX or RIS for Zotero, EndNote and Mendeley (section 1)
- Find the papers that cite a paper, the papers it cites and the papers PubMed rates as similar, with retracted papers, reviews and NIH funding flagged (section 3)
- Build a knowledge graph of a study's literature in Obsidian, one Markdown note per paper and MeSH concept, linked by citations, similarity and topics (section 4)
- Give AI assistants PubMed tools through the MCP server or the plugin, and summarize abstracts with a local LLM through Ollama, so nothing leaves your computer (section 5)
- Measure the impact of a retracted paper through the papers citing it and the papers citing those (tutorial 8)
Documentation: melhzy.github.io/pubmed-stream, the tutorials, guides and reference in one searchable website, with every notebook shown with its results.
A study made with it: the Aβ*56 retraction impact page, how a retracted Alzheimer's paper spread through the literature and how much of it language models learned, as an interactive page where every number comes from the study's files; see Studies.
New to programming? Start with tutorial 0, which takes a research question to a map of its literature in an afternoon. Click Open in Colab to run it in your web browser, with nothing to install; you only type your question into one settings cell.
Contents
Quick start
For automatic first-time Obsidian setup with --register, see Open the graph in Obsidian. That section also explains how to use the updated source if your installed command does not yet support the option.
With an AI assistant: Claude Code, Codex or Gemini CLI
An AI assistant can do all of the above for you. Install one: Claude Code needs a paid Claude plan, Codex a paid ChatGPT plan, and Gemini CLI only a Google account. These commands need Node.js 22 or later; tutorial 7 shows the other installers and walks through a session.
Then give your assistant pubmed-stream's tools, in one of two ways:
Start your assistant in your research folder with claude, codex or gemini. The first time, it asks you to sign in. With init, Claude Code also asks to approve the pubmed-stream server, and Gemini CLI asks whether you trust the folder: say yes to both, or the assistant will not have pubmed-stream's tools. /mcp lists them. Then ask in plain language:
Is the gut microbiota linked to frailty? Size the search first, download the clinical studies, and summarize the evidence with PMIDs.
Section 5 compares the plugin and init.
In Python
The first steps of the quick start, in Python:
Tutorials
The notebooks in tutorials/ are written for researchers, not programmers. Each follows a real research question. The notebooks have a single Your settings cell for your own question, run in Google Colab with nothing to install, and are saved with their results so you can read them first, on GitHub or on the documentation site; tutorial 7 happens in a terminal, with an AI assistant.
Five short guides support them:
The tutorials README lists everything, including how programmers can run the notebooks locally.
Studies
Research done with pubmed-stream lives in studies/, one folder per study with its frozen data, scripts and write-up, and a web page where the study has one, published with the documentation site.
The studies README explains the layout of a study and how to start one.
Installation and configuration
The AI-assistant, local-model and Obsidian features of section 5 need version 0.3.0 or later, PubMed abstracts and citation export 0.4.0, reviews by Claude Code, Codex or Gemini CLI (review --model claude) 0.4.1, and the Claude Code and Codex plugin, pubmed_stream.impact, which tutorial 8 imports, and saving your NCBI API key with init 0.4.2, and the MCP server's progress reports and its hidden console window on Windows 0.4.3: pubmed-stream --version shows yours, and pip install --upgrade pubmed-stream updates it. From a clone, pip install -e ".[dev]" installs it in editable mode with pytest and ruff. pubmed-stream needs Python 3.9 or later; its only runtime dependency is requests.
Set an NCBI API key. NCBI allows 3 requests per second without a key and 10 with one, so a key makes everything about three times faster. Keys are free: create one under API Key Management in the settings of an NCBI account. Save it once, for every folder:
init checks the key with NCBI before saving it, and if NCBI ever rejects a saved key, pubmed-stream says so and continues without it rather than failing every request. Without a key, a download that a key would have shortened by ten seconds or more ends by saying how much time it would have saved.
Claude Code asks for it when the pubmed-stream plugin is installed. For scripts and servers, the environment works too, with an optional contact email, and takes precedence:
Every command also accepts --api-key and --email. pubmed-stream sets its request rate from the key automatically, retries failed requests three times with back-off, and never writes the key to its logs. --rate-limit SECONDS slows it down further if needed.
1. Download full-text articles from PubMed Central
pubmed-stream download searches PubMed Central directly, so every result is an article with a PMC record, then fetches each one's full-text XML in parallel and saves it as one JSON file. Some publishers do not allow their articles to be downloaded as XML; those are reported as unavailable and skipped, rather than saved half-empty.
Each search gets its own folder, named after the query; a name longer than 100 characters is shortened and ends with a short hash of the query. Running a search again skips the files that already exist, so an interrupted download resumes and a repeated search only fetches what is new.
To see what you downloaded without opening every file, list prints one line per article, newest first, and each article once however many searches found it:
Articles without free full text. PMC holds the free full text of only part of the literature: search counts both, and for the frailty search of the quick start PubMed has 95 articles where PMC has 66. abstracts saves the PubMed record of each match, with its abstract, MeSH terms and publication types, in the same folder as the full texts. list, review and the knowledge graph read both; list marks the abstracts [abstract only], and an article saved both ways is shown with its full text.
Citations. export writes the articles, full texts and abstracts alike, as BibTeX or RIS, which Zotero (File > Import), EndNote, Mendeley and LaTeX read. Entries have the title, authors, journal, year, DOI, PubMed and PMC IDs, a link and the abstract. The first word of each author name is taken as the surname, so check multi-word surnames such as "van der Berg" after importing.
Every article file has the same shape. metadata.references lists the cited works that have a PubMed ID or DOI; those become citation links in a knowledge graph.
The format decides what is kept beside the metadata:
download exits with 0 when articles were saved or already present, 1 when the search found nothing, and 2 when every download failed.
2. Write PubMed searches that find the right papers
PMC searches the full text of every article, including its reference list, so a plain search such as gut microbiome frailty matches thousands of articles that only mention the words in passing. Field tags fix this. In tutorial 2, five versions of one question range from 7,587 matches with almost no relevant recent results to 66 matches where most are on topic.
PMC returns the newest matches first, so --max-results takes the most recent articles. Check a search before downloading: pubmed-stream search QUERY prints its size and newest titles without downloading anything, and --show 0 prints the count only.
3. Map the evidence around a paper: citing, cited and similar articles
A search finds papers by their words. An evidence neighborhood starts from one key paper and follows PubMed's links instead: the papers PubMed rates as similar, the papers citing it, and the papers it cites. Each is flagged as a review, retracted or NIH-funded. NLM's Linked Discoveries web tool shows the same kind of neighborhood but has no API; pubmed-stream builds one from documented E-utilities.
100 of 489 means 489 PubMed articles cite the seed and the newest 100 were fetched in detail; --max-per-relation changes that cap. The counts in brackets always cover all 489, counted with PubMed searches rather than by downloading every record. [RETRACTED] lists every retracted article among those fetched, so check them before citing or building on them.
The neighborhood is saved as publications/neighborhood_<PMID>/neighborhood.json. --download also saves the PMC full text of the seed and every neighbor that has one, beside it. In Python:
Each neighbor is a RelatedArticle with pmid, title, journal, year, authors, pub_types, is_review, is_retracted, nih_funded, pmcid, doi, mesh_terms, and, for similar articles, a similarity score. A neighborhood costs two requests for up to 200 articles, plus five for each relation cut short by the cap.
Compared with Linked Discoveries: similarity comes from PubMed's Similar Articles algorithm rather than a BiomedBERT model, so the neighbors can differ; there are no condition, gene or chemical filters; and citation links exist only where reference lists were deposited, mostly for PMC articles. Like the web tool, the flags describe connections; they do not judge whether a study is sound. Tutorial 4 charts a neighborhood and walks through retraction screening.
neighborhood exits with 0 on success, 1 when the PMID is invalid or not in PubMed, and 2 when NCBI could not be reached. It takes a PubMed ID, the number in a pubmed.ncbi.nlm.nih.gov/<PMID>/ link or a downloaded article's metadata.pmid, not a PMC ID.
4. Build the knowledge graph of a study in Obsidian
Downloads and neighborhoods come together in a knowledge graph. A study has a topic, the searches that collect its literature, and optionally key papers whose neighborhoods belong in it. pubmed-stream kg runs them all and links the results in an Obsidian vault named kg_<topic>: a folder of Markdown notes, one per paper, MeSH concept and collection. Open the graph in Obsidian to see which papers cite each other and which topics they share.
[A knowledge graph of PubMed papers built by pubmed-stream, in Obsidian's graph view: large dots for papers and MeSH concepts, each downloaded paper surrounded by a burst of small dots for the works it cites]
That study gives a graph of 127 papers, 42 with full text and 85 from the seed's neighborhood, linked to 309 MeSH concepts: 440 notes in all. The study is remembered, so it keeps growing and stays current with only its topic:
download and neighborhood can join a study too: with --topic "gut microbiome frailty", their search or seed is recorded like one made with kg. A bare --vault names the graph after the query or the neighborhood instead, and --vault DIR or --kg-dir DIR picks any folder. Obsidian links notes only inside one vault, so give every search of a study the same topic.
Open the graph in Obsidian
Install Obsidian and start it at least once. For automatic first-time registration, quit Obsidian completely (on macOS, use Obsidian → Quit Obsidian, or Cmd+Q), then run this from your research folder:
Replace the example folder name with your graph's folder. The command adds it to Obsidian's vault registry and opens PubMed Stream.md. It preserves existing vaults and settings and prints the path to an exact registry backup. Registration uses Obsidian's private registry format; the command refuses to write if Obsidian is running, its process status cannot be checked, or the registry has an unfamiliar format. Running it again reuses the existing registration.
Check that your command supports registration: run pubmed-stream open --help and look for --register. Your installed command may still use a different copy of pubmed-stream. If the option is missing, run the updated source directly from the pubmed-stream repository folder, using the full path to your graph:
Alternatively, run python -m pip install -e . from that repository folder to use the checkout as your installed package, then return to your research folder and use pubmed-stream open normally.
Manual setup: in Obsidian, choose Open folder as vault and select the kg_<topic> folder itself—the folder containing PubMed Stream.md and papers/. This also works if automatic registration is unavailable.
After either setup, open the graph at any time with:
Obsidian can stay running for later opens. If there is exactly one kg_* folder in the current directory, pubmed-stream open finds it without a folder argument. Once registered, pubmed-stream kg ... --open also opens the graph after a build. See the Obsidian guide for browsing papers, using the graph view and adding your notes.
What the graph contains
Here is a slice of the example study's graph. Every link in it is real: two 2026 studies from different searches cite the same 2021 study, which PubMed also rates as similar to the seed review. Connections like this are what a list of search results hides.
Where the links come from:
- Citations come from the reference lists of downloaded articles, for references with a PMID, and from neighborhood citing and cited papers. References with only a DOI are listed under Other references.
- Similarity comes from neighborhood similar articles, with PubMed's score.
- Concepts are MeSH headings fetched from PubMed, once per 200 papers, and cached in the graph. Check tags such as Humans or Aged stay in the paper's properties but get no note, because they would link almost every paper.
- Stubs are neighborhood papers that were not downloaded. Their notes carry PubMed details and links, and are tagged
pubmed/stub.
A paper note holds Obsidian properties, then a generated block, then space for your own notes:
Rebuilding is safe. A rebuild replaces only the generated block and the properties the tool owns. Text outside the block, and properties, tags and aliases you add in Obsidian, are kept; unchanged notes are not rewritten. Do not rename or move generated notes, or a rebuild will recreate them. Properties work in Obsidian search, Bases and the Dataview plugin, and on the first build the graph view gets colours for retracted papers, reviews, stubs, concepts and collections.
Tutorial 5 builds this study and explains the graph with charts: where the papers came from, which concepts travel together, which papers the study relies on most, and which ones bridge its parts.
kg exits with 0 when everything worked, 1 when there is nothing to build or an option is invalid, and 2 when a search or neighborhood failed; the graph is still built from everything else.
Limitations to know about:
- Some papers lack MeSH terms. Indexing takes months, and papers in journals outside MEDLINE are never indexed, so such papers have no concept links. Rebuild later to pick up newly indexed papers; the others stay unlinked to concepts but keep their citation links.
- Downloads from pubmed-stream 0.1.1 or earlier have no reference lists, unless saved with
--format xml or both. Download them again to add citation links.
- Many references have no PMID. Conference papers, preprints and books appear under Other references, not in the graph.
- Notes are never deleted. Removing a source leaves its notes in the graph.
5. Use it with AI assistants (MCP server and plugin), local models and Obsidian
pubmed-stream connects to the tools researchers now work with: AI assistants that run in a terminal, local models that keep everything on your computer, and Obsidian, where the knowledge graph lives.
A PubMed MCP server for Claude Code, Codex and Gemini CLI
How it works. The MCP server is part of the Python library: the command pubmed-stream mcp starts it. There is nothing else to install. An AI assistant starts that command in the background, and from then on it can call pubmed-stream's tools itself, the way you would type its commands. The setup only tells the assistant how to start the server. There are three ways to do that, and they differ only in where the library comes from and which folders have the tools:
1. The plugin, for Claude Code or Codex in every folder. The plugin, in plugins/pubmed-stream, holds no code. It is a few settings files that tell the assistant to start the server with uvx --from pubmed-stream==<version> pubmed-stream mcp. uv downloads that release of the library from PyPI and runs it, so you do not need pip install; the plugin's version always names the library release it runs. It also brings the instructions, as the skill literature-search. Install uv, then:
The first start takes longer, while uv downloads pubmed-stream; if the assistant reports that the server did not start, start the assistant again. If Claude Code did not ask for your NCBI API key, type /plugin configure pubmed-stream@pubmed-stream inside it.
2. pubmed-stream init, for any of the three assistants in one research folder. After pip install pubmed-stream, run it in the folder. It writes settings files that start the server with the Python that has the library, python -m pubmed_stream mcp: .mcp.json for Claude Code, .codex/config.toml for Codex and .gemini/settings.json for Gemini CLI. It also writes the instructions as AGENTS.md, which CLAUDE.md and GEMINI.md import, and asks once for your NCBI API key. init --claude-model opus and init --review-model <ollama model> choose the folder's models.
3. By hand, for every folder, without the plugin. After pip install pubmed-stream, register the command once; --scope user makes Claude Code load it in every folder, not only in the one where you ran the command. The assistant gets the tools but not the instructions file, so prefer one of the first two.
Then use it. Start the assistant in your research folder, claude, codex or gemini; files it downloads are saved there. Type /mcp to check that pubmed-stream is listed with its tools, and ask a research question in plain language:
Does fecal microbiota transplantation help people with Parkinson's disease? Find the clinical evidence and summarize it, with PMIDs.
The assistant picks among the nine tools by itself. Each returns compact text, so it can scan 64 papers in about 3,000 tokens instead of reading 4.3 MB of full text. The instructions make it size searches before downloading, cite only papers it downloaded and read in the session, say what kind of evidence each is, report its searches with their counts, and name what it could not read. A download of hundreds of articles or a knowledge graph takes minutes; the server reports its progress while it runs, and Claude Code shows it.
To call pubmed-stream on purpose rather than let the assistant choose it:
The ways do not conflict: where the plugin is installed, init leaves its server out of the folder, so the tools are not listed twice, and running it again in a folder set up earlier removes the extra one.
Local LLMs through Ollama, and Obsidian
Local models. For questions you would rather not send to a company, pubmed-stream review has a model running in Ollama on your own computer summarize the abstracts you chose; only the PubMed searches leave your computer. The model reads one abstract at a time, at temperature 0, and never sees your question, so it cannot present the question as a finding. pubmed-stream attaches each PubMed ID itself and flags numbers and citations the abstracts do not support.
1. Install Ollama from ollama.com/download, or on Windows with winget install Ollama.Ollama. It runs in the background; ollama list checks that it works.
2. Choose a model your computer can run. Any model in Ollama's library works, open-weight models such as Qwen, Gemma or Llama included; pubmed-stream turns off the "thinking" step of models that have one, so it does not use up the summary's length. Larger models make fewer mistakes but need more memory: the model's download size should be at most about two-thirds of your computer's memory, and a model that fits in a graphics card's memory runs much faster.
Without --model, review uses Llama 3.2 1B (807 MB), which runs on almost any computer but makes more mistakes: on seven Parkinson's papers it called a review of eleven studies a randomized controlled trial, which Qwen3.5 2B did not.
3. Download the model and ask:
--vault also saves the summaries as a note in the knowledge graph's reviews folder, named after the question, the date and the model, so reviews by several models sit side by side. pubmed-stream init --review-model qwen3.5:9b makes the model the folder's default, so --model can be left out. --answer adds one answer drawn from all the summaries; check it against them, as smaller models credit findings to the wrong paper. If Ollama runs on another computer, such as a lab server, point to it with --ollama-host http://<server>:11434.
Or an AI assistant's model. --model claude, --model codex or --model gemini has Claude Code, Codex or Gemini CLI summarize instead, if it is installed and signed in on your computer (see the quick start). Their models are much larger than a laptop can run, so they make fewer mistakes: on the seven Parkinson's papers above, Claude Code's summaries were all accurate, including the review of eleven studies that Llama 3.2 1B called a trial. In exchange, the abstracts go to Anthropic, OpenAI or Google, and each run uses some of your plan. pubmed-stream runs the assistant in an empty folder with its tools turned off, so it only answers; everything else works as with Ollama: one abstract at a time, without the question, the same checks, --answer and --vault. Add the assistant's own model after a colon, as in --model claude:opus.
Obsidian. Every knowledge graph has property types for Obsidian and Papers.base, a Bases table of all papers with views for full texts, reviews, retracted papers and your #to-read list. Register and open the graph once, then use pubmed-stream open kg_<topic> on later visits. With Obsidian's command line switched on, an assistant can query the vault: obsidian vault=kg_<topic> base:query path=Papers.base view="Reading list".
Tutorial 7 walks through real sessions: an assistant going from 4,863 search results to a cited report, Claude Code and Codex using the MCP tools, and what a 1-billion-parameter local model gets right and wrong. A model that small summarizes well but cannot run the searches itself.
Python API for PubMed and NCBI E-utilities
Everything the commands do is available from pubmed_stream:
Functions that call NCBI accept api_key, email, user_agent, rate_limit and a session to reuse, and fall back to the environment variables. The low-level functions take an explicit session and rate limiter:
How a paper spread through the literature is measured by a module of its own, from pubmed_stream import impact. impact.citers_of(pmids) asks PubMed for the articles citing each of many papers at once, impact.count_by_year(pmids, first, last) and impact.count_flags(pmids) count them by year, or as reviews, retracted or NIH-funded, without downloading their records, and impact.corrections(pmid) lists a paper's retraction notice, errata and comments. impact.citation_contexts(folder, pmid, doi) finds the sentence in which each downloaded full text cites the paper, impact.semantic_scholar_contexts(pmid) adds the sentences Semantic Scholar has for papers whose full text is not free, and impact.classify(sentences) sorts them: discussing the retraction or doubts about the paper, naming its finding, or citing it in general. impact.annotate(kg_dir, properties) writes the results into the notes of a knowledge graph. Tutorial 8 follows a retracted paper through two hops of citing papers with them.
Troubleshooting
Problems with installing Python, Jupyter, Colab or Obsidian are covered in the troubleshooting guide for beginners.
For details, add -v to any command, or enable debug logging for this package only, since the HTTP library's debug output would log request URLs with your API key:
How it works
pubmed-stream is a stack of five small modules. Each one uses only those below it, from the command line down to the HTTP client:
The architecture guide explains the whole repository with diagrams, tables and figures: every NCBI request, the request flows, how knowledge graphs are merged and safely rebuilt, the data model, and where to extend the code.
Contributing
Contributions are welcome. Fork the repository, create a feature branch, and open a pull request. Add tests for new behaviour, and make sure pytest and ruff check . pass; GitHub Actions runs both on every pull request. The tests run offline in a few seconds:
The documentation site is built from the README, tutorials/, docs/ and the changelog, and published by GitHub Actions on every push to main. Preview it at http://127.0.0.1:8000 with:
Ideas on the roadmap: a search query builder and progress bars.
Releasing to PyPI
Maintainers publish new versions by hand. Replace X.Y.Z with the new version.
-
Bump the version in pubmed_stream/__init__.py (__version__ = "X.Y.Z"), which pyproject.toml reads, and CITATION.cff (version and date-released). In the plugin, plugins/pubmed-stream, bump it in both plugin.json files (version), in the release its server runs (pubmed-stream==X.Y.Z, in .codex-plugin/mcp.json and in .claude-plugin/plugin.json) and in the skill's note, twice; and in server.json, twice (version, and the package's version). Turn the changelog's Unreleased heading into X.Y.Z - YYYY-MM-DD. The tests name any copy left behind.
-
Run the tests: pytest.
-
Build and check the distributions; dist/ is git-ignored:
-
Upload to PyPI with an API token from https://pypi.org/manage/account/token/, scoped to the pubmed-stream project. The username is literally __token__; a PyPI password will not work. A 403 Forbidden means the token is wrong, expired or not scoped to this project. PyPI never accepts the same version twice, so fix a broken release with a new patch version. InvalidDistribution: Metadata is missing required fields: Name, Version means twine is too old to read the package's metadata (version 2.4): use twine 6.1 or later. In a shared environment such as Anaconda's, upgrading twine also upgrades packages that other tools there depend on, so run it from a separate virtual environment.
Paste the token when twine asks for it; typed there, it stays out of your shell's history. Upload before you push the release: the plugin on GitHub runs the release its pubmed-stream==X.Y.Z names, so until PyPI has that release, the plugin's server cannot start.
-
Commit, tag and push the release:
If the tag already exists on the wrong commit, move it and force-push only that tag, never main: git tag -f X.Y.Z <commit>, then git push --force origin refs/tags/X.Y.Z.
-
Create the GitHub release. In the web interface, open https://github.com/melhzy/pubmed-stream/releases/new?tag=X.Y.Z, set the title to X.Y.Z, paste the version's section of CHANGELOG.md as the description, attach the two files from dist/, and publish. With the GitHub CLI, after a one-time gh auth login: gh release create X.Y.Z --title "X.Y.Z" --notes "<the changelog section>" dist/*.
-
Update the listing in the official MCP Registry, which other MCP directories copy. It holds only server.json, so run this after PyPI has the release: the registry checks that the version exists there and that the README PyPI shows contains the line mcp-name: io.github.melhzy/pubmed-stream, which the README carries as a hidden comment. With mcp-publisher installed, from the repository root:
-
Verify: pip install --upgrade pubmed-stream, then pubmed-stream --version.
FAQ
What is the difference between PubMed and PMC? PubMed indexes the citations and abstracts of over 35 million articles. PubMed Central (PMC) is NCBI's archive of full-text articles, a subset of them. pubmed-stream downloads full text from PMC, and uses PubMed for neighborhoods, MeSH terms and the abstracts of articles whose full text is not free.
How do I download full-text articles from PubMed Central with Python? Install it with pip install pubmed-stream, then call search_and_download("your search", max_results=50), or run pubmed-stream download "your search". It searches PMC, downloads each article's full-text XML through the E-utilities in parallel, and saves it as JSON with its metadata and references; see section 1.
Can it download PDFs? No. It downloads the full text as XML, which it turns into plain text, metadata and references, the form that text mining, search and AI assistants need. Articles whose publishers withhold the XML, or that PMC has only as PDFs, are reported as unavailable; abstracts still saves their PubMed abstracts.
Is there a PubMed MCP server for Claude Code, Codex or Gemini CLI? Yes: pubmed-stream mcp is one. Its tools search PubMed Central, download full texts and abstracts, read them back compactly, map a paper's citations and build a knowledge graph. Install it as a plugin in Claude Code or Codex, or set up a research folder for any of the three with pubmed-stream init; see section 5.
How do I find the papers that cite a PubMed article? pubmed-stream neighborhood <PMID> lists the papers citing it, the papers it cites and the papers PubMed rates as similar; for many papers at once, impact.citers_of(pmids) returns the citing PMIDs of each. PubMed has citation links only where reference lists were deposited, mostly for PMC articles, so its counts can be lower than Google Scholar's.
Can it tell me whether a paper has been retracted? Yes. Neighborhoods and knowledge graphs flag every retracted paper, from PubMed's Retracted Publication type and linked retraction notices, and impact.corrections(pmid) lists a paper's retraction notice, errata and comments. Tutorial 8 follows a retracted paper through the literature.
How do I export PubMed results to Zotero, EndNote or Mendeley? Download them, then run pubmed-stream export publications -o review.bib for BibTeX, or add --format ris for RIS, and import the file; in Zotero, with File > Import.
How is it different from Biopython's Entrez module? Bio.Entrez gives you the E-utilities requests themselves. pubmed-stream is built on the same E-utilities, without Biopython, and does the steps of a literature search for you: searching, downloading in parallel within NCBI's rate limits, resuming, parsing JATS XML into text, metadata and references, exporting citations, and building citation neighborhoods and knowledge graphs.
Does it comply with NCBI's terms? Yes. It uses the official E-utilities, keeps within NCBI's rate limits, identifies itself with a User-Agent, and sends your contact email when you set one.
Why one JSON file per article? One file keeps an article's metadata, references and text together, in every format, and makes corpora easy to filter, merge and resume.
Can I resume an interrupted download? Yes. Run the same command again; existing files are skipped.
Can I use it for a systematic review? For the first steps: scoping the field, testing and recording searches, and finding key papers. A systematic review also needs other databases, screening by two reviewers and risk-of-bias assessment; see what pubmed-stream can and cannot do.
Why are some important papers missing? Full text comes only from PMC, and searches return the newest matches first. abstracts saves the PubMed abstracts of the rest, and older and subscription-only papers also enter a knowledge graph through key papers' neighborhoods, as stubs, or as links from the papers that cite them.
Do I need Obsidian? Only to explore a knowledge graph visually. The notes are plain Markdown, and tutorial 5 analyses one in Python.
Can I use it commercially? Yes, under the MIT license, while respecting NCBI's usage policies.
Citation, acknowledgments and license
pubmed-stream was developed to support biomedical research at the University of Massachusetts by the Haran Lab, the Bucci Lab and the Microbiology & Microbiome Dynamics AI HUB. Thanks to NCBI for the E-utilities and open access to PubMed Central. If you use it in your research, please cite it. GitHub's Cite this repository button, on the repository's main page, gives the citation in APA and BibTeX from CITATION.cff:
pubmed-stream is free software under the MIT License. Changes in each version are listed in the changelog.
Questions and bug reports: open an issue. Package: pypi.org/project/pubmed-stream.