pubmed-proxy-mcp
MCP server for NCBI PubMed E-utilities with rate limiting, enabling article search, metadata retrieval, full-text access, BibTeX generation, and bibliography management.
README
pubmed-proxy-mcp
MCP server and CLI for NCBI PubMed E-utilities with built-in rate limiting.
Features
- PubMed search — Full query syntax with field tags, boolean operators, date ranges, pagination, and sorting
- Article metadata — Fetch title, authors, journal, year, DOI, and abstract for any PMID
- Batch lookup — Fetch metadata for up to 20 PMIDs at once
- Full-text retrieval — Get full article text from PubMed Central (when available)
- BibTeX citations — Generate BibTeX entries from PMID or DOI (with CrossRef fallback)
- Bibliography management — Add citations to .bib files, search, list, validate, and batch-initialize
- BibTeX correction — Correct .bib files against authoritative NCBI/CrossRef metadata with smart field comparison
- Rate limiting — Built-in token bucket (10 req/s NCBI, 1 req/s CrossRef)
Quick Start for LLM Agents
If you are an LLM agent that has been pointed to this tool for literature research, follow these steps:
1. Check that the NCBI API key is configured (recommended but optional):
echo $NCBI_API_KEY
If empty, commands will still work but at a lower rate limit (3 req/s instead of 10 req/s). To get the faster rate, set an API key:
export NCBI_API_KEY="your-api-key"
Or pass it per-command with --api-key <key>.
To obtain a key: create an account at https://www.ncbi.nlm.nih.gov/account/, then go to
Settings > API Key Management > Create an API Key.
2. If using MCP tools (e.g. via Claude Desktop), the MCP server must be configured in the client. The CLI commands below work standalone without the MCP server.
3. Typical research workflow:
# Search for relevant articles
pubmed-proxy search "your topic here" --summaries --max 10
# Get full metadata + abstract for interesting PMIDs
pubmed-proxy lookup 23381990
# Get full-text if available (PMC only)
pubmed-proxy lookup --full-text 23381990
# Generate BibTeX citations for references
pubmed-proxy citation 23381990 16855256 >> references.bib
Installation
pip install -e . # Core (MCP server + basic CLI)
pip install -e ".[bib]" # With bibliography management (bibtexparser)
Requires Python 3.10+. An NCBI API key is recommended for higher rate limits (see Quick Start above).
MCP Server
Run as an MCP server (stdio transport). Works without an API key (3 req/s) or with one (10 req/s):
python -m pubmed_proxy_mcp
MCP Tools
| Tool | Description |
|---|---|
search_articles |
Search PubMed with full query syntax, filters, pagination, optional summaries |
get_article_metadata |
Get metadata + abstract for a single PMID |
batch_get_metadata |
Batch fetch metadata for up to 20 PMIDs |
get_full_text |
Get full-text article content via PMC |
get_citation_bibtex |
Get BibTeX entry for a PMID |
get_citation_by_doi |
Get BibTeX entry for a DOI |
search_doi_to_pmid |
Convert DOI to PMID |
bib_add_citation |
Fetch BibTeX and add to a .bib file |
bib_search |
Search across all .bib files for a keyword |
bib_list |
List entries in .bib files |
bib_show |
Show full BibTeX for a citekey |
bib_validate |
Validate citekeys in markdown against .bib |
bib_init |
Scan markdown for PMIDs and create .bib files |
bib_stats |
Summary statistics for .bib files |
bib_correct |
Correct a .bib file against NCBI/CrossRef metadata |
CLI Reference
An NCBI API key is optional but recommended. Without one, the rate limit is 3 req/s instead of 10 req/s. If not set, a warning is printed to stderr but commands still work.
echo $NCBI_API_KEY # If empty, commands work at 3 req/s
To use a key, either export NCBI_API_KEY=<key> or pass --api-key <key> to any command.
pubmed-proxy server — Shared Rate-Limiting Proxy
Note: The proxy server is only needed when running multiple CLI commands in parallel (e.g. from multiple subagents). For single-command usage, the CLI works fine on its own with its built-in rate limiter — no server required.
When running parallel commands, each process has its own rate limiter. To share a single rate limiter across all processes, start the proxy server first:
# Terminal 1: start the shared proxy server
pubmed-proxy server # default port 8765
pubmed-proxy server --port 9000 # custom port
Then point CLI commands at it with --server:
# Terminal 2+: commands share the proxy's rate limiter
pubmed-proxy --server http://localhost:8765 search "CRISPR" --max 10
pubmed-proxy --server http://localhost:8765 lookup 23381990
The MCP server also auto-detects the proxy: if pubmed-proxy server is running on
port 8765 when the MCP server starts, it will use the shared rate limiter automatically.
Set PUBMED_PROXY_URL to override the proxy URL for the MCP server.
Arguments:
| Argument | Required | Description |
|---|---|---|
--port PORT |
No | Server port (default: 8765) |
Global --server flag:
| Argument | Required | Description |
|---|---|---|
--server URL |
No | Proxy server URL (e.g. http://localhost:8765). When set, all NCBI requests go through the proxy for shared rate limiting |
pubmed-proxy search — Search PubMed
Search PubMed using full NCBI query syntax. Supports field-specific tags, boolean
operators (AND, OR, NOT), and MeSH terms.
Arguments:
| Argument | Required | Description |
|---|---|---|
query |
Yes | PubMed search query string |
--max N |
No | Maximum results to return (default: 20, max: 10000) |
--page N |
No | Page number, 0-indexed (default: 0). Page 1 with --max 10 starts at result 11 |
--sort ORDER |
No | Sort order: relevance (default), pub_date, author, journal |
--date-type TYPE |
No | Date field to filter: pdat (publication date) or edat (Entrez date) |
--min-date DATE |
No | Start date filter, format YYYY/MM/DD or YYYY |
--max-date DATE |
No | End date filter, format YYYY/MM/DD or YYYY |
--summaries |
No | Include title, authors, journal, and year for each result |
Query syntax examples:
"E. coli iron regulation"— keyword search"Smith[Author] AND cancer[Title]"— field-specific search"CRISPR[Title] AND 2024[PDAT]"— with publication date tag"breast cancer AND review[PT]"— filter by publication type"Nature[Journal] AND gene editing"— journal-specific search
Output without --summaries:
Found 1543 results (showing 1-20):
38471234
38469012
...
Output with --summaries:
Found 1543 results (showing 1-5):
PMID: 38471234
Title: CRISPR-Cas9 gene editing in E. coli
Authors: Smith, JD; Doe, A; Lee, B (+4 more)
Journal: Nature Biotechnology (2024)
PMID: 38469012
Title: Another relevant paper
Authors: Jones, C; Wang, X
Journal: Science (2024)
Examples:
# Basic keyword search
pubmed-proxy search "antibiotic resistance"
# Field-specific with boolean operators
pubmed-proxy search "Smith[Author] AND cancer[Title]"
# Filter by date range (publication date)
pubmed-proxy search "CRISPR" --min-date 2023/01/01 --max-date 2024/12/31 --date-type pdat
# Sort by publication date, get 10 results
pubmed-proxy search "biofilm" --max 10 --sort pub_date
# Page 2 of results (results 11-20)
pubmed-proxy search "biofilm" --max 10 --page 1
# Include metadata summaries for quick scanning
pubmed-proxy search "antibiotic resistance" --summaries --max 5
pubmed-proxy lookup — Get Article Metadata
Fetch metadata and abstract for one or more PubMed articles by PMID.
Arguments:
| Argument | Required | Description |
|---|---|---|
pmids |
Yes | One or more PubMed IDs (space-separated) |
--full-text |
No | Fetch full article text from PMC instead of just metadata. Only works for the first PMID. Not all articles have free full text |
Output (metadata mode):
PMID: 23381990
Valid: Yes
Title: The Fur regulon of pathogenic Neisseria
Authors: Smith, JD, Doe, A, Lee, B, Wang, X, Jones, C
Journal: Journal of Bacteriology (2013)
DOI: 10.1128/JB.01411-12
Abstract: The ferric uptake regulator (Fur) is a transcription factor...
For multiple PMIDs, each article's metadata is separated by a blank line.
Invalid PMIDs return Valid: No with an error message.
Output (full-text mode):
PMID: 23381990 (Full Text)
PMCID: PMC3697534
## Introduction
The ferric uptake regulator (Fur) is a global...
## Results
We identified 47 genes...
If the article is not available in PMC, shows: Error: Full text not available in PMC
Examples:
# Single article metadata + abstract
pubmed-proxy lookup 23381990
# Batch lookup (up to 20 PMIDs)
pubmed-proxy lookup 23381990 16855256 25157846
# Full article text (PMC only, first PMID only)
pubmed-proxy lookup --full-text 23381990
pubmed-proxy citation — Fetch BibTeX Citations
Generate BibTeX @article entries for PubMed articles. Output goes to stdout and can
be piped or appended to .bib files. Citekeys use the format pmid_XXXXXXXX.
Arguments:
| Argument | Required | Description |
|---|---|---|
pmids |
No* | One or more PubMed IDs (space-separated) |
--doi DOI |
No* | Fetch BibTeX by DOI instead. Tries NCBI first for better metadata, falls back to CrossRef |
*Provide either pmids or --doi.
Output:
@article{pmid_23381990,
author = {Smith, JD and Doe, A},
title = {{The Fur regulon of pathogenic Neisseria}},
journal = {J Bacteriol},
year = {2013},
volume = {195},
number = {14},
pages = {3159-3170},
doi = {10.1128/JB.01411-12},
pmid = {23381990}
}
Multiple PMIDs produce multiple entries separated by blank lines.
DOI-only entries (not in PubMed) use citekey format doi_<sanitized_doi>.
Examples:
# Single PMID to stdout
pubmed-proxy citation 23381990
# Multiple PMIDs, append to a file
pubmed-proxy citation 23381990 16855256 25157846 >> references.bib
# By DOI (tries NCBI first, falls back to CrossRef)
pubmed-proxy citation --doi 10.1128/JB.01411-12
pubmed-proxy doi2pmid — Convert DOI to PMID
Look up the PubMed ID for a given DOI.
Arguments:
| Argument | Required | Description |
|---|---|---|
doi |
Yes | Digital Object Identifier |
Output:
DOI: 10.1038/s41467-019-13483-w
PMID: 31784527
If no PMID is found: PMID: not found
Example:
pubmed-proxy doi2pmid 10.1038/s41467-019-13483-w
pubmed-proxy correct — Correct BibTeX Files
Correct a .bib file by verifying each entry against authoritative NCBI/CrossRef metadata. For each entry, fetches correct metadata by DOI, existing PMID, or title search (with author-overlap validation to avoid wrong matches).
Requires pip install -e ".[bib]".
Smart comparison rules:
- Authors: never replaces full names with initials; expands "and others"; flags mismatches for review
- Pages: normalizes abbreviated ranges (e.g.
735-47to735-747); preserves LaTeX en-dashes - Journal: prefers longer (more complete) journal name
- Title: never touched (may contain LaTeX formatting)
- Year/volume/number/DOI: trusts authoritative source
Arguments:
| Argument | Required | Description |
|---|---|---|
-i, --input FILE |
Yes | Input .bib file path |
-o, --output FILE |
No | Output .bib file path. If omitted, corrects in-place and creates a .bib.bak backup |
Output:
entry1_key: OK via DOI
entry2_key: FIXED 2 field(s) via DOI
year: 2012 -> 2013
pages: 735-47 -> 735-747
entry3_key: FAIL could not fetch (no DOI/PMID)
Summary: 15 entries processed
Verified OK: 12
Corrected: 2
Failed: 1
Skipped: 0
Output: corrected.bib
Examples:
# Correct to a new output file
pubmed-proxy correct -i references.bib -o corrected.bib
# Correct in-place (creates references.bib.bak backup)
pubmed-proxy correct -i references.bib
pubmed-proxy bib — Bibliography Management
Manage .bib files: add citations, search, list, validate, and batch-initialize.
All bib subcommands accept --dir DIR to specify the directory containing .bib
files (default: current directory).
Requires pip install -e ".[bib]" (bibtexparser).
bib fetch — Add Citation to .bib File
Fetch a BibTeX citation by PMID or DOI and add it to a .bib file. Automatically deduplicates — skips entries whose citekey already exists.
| Argument | Required | Description |
|---|---|---|
identifiers |
No* | One or more PubMed IDs |
--doi DOI |
No* | Fetch by DOI instead |
--bib FILE |
Yes | Target .bib filename (e.g. Fur.bib) |
*Provide either identifiers or --doi.
pubmed-proxy bib fetch 23381990 --bib Fur.bib
pubmed-proxy bib fetch 23381990 16855256 --bib refs.bib
pubmed-proxy bib fetch --doi 10.1128/JB.01411-12 --bib Fur.bib
pubmed-proxy bib fetch 23381990 --bib refs.bib --dir ./citations
Output: Added: pmid_23381990 or Already exists: pmid_23381990
bib search — Search Across .bib Files
Search all .bib files in a directory for a keyword. Searches citekeys and all fields (title, author, journal, etc.). Case-insensitive.
| Argument | Required | Description |
|---|---|---|
keyword |
Yes | Search term |
pubmed-proxy bib search "Fur"
pubmed-proxy bib search "iron regulation" --dir ./citations
Output:
Found 3 entries matching 'Fur':
[Fur.bib] @pmid_23381990: The Fur regulon of pathogenic Neisseria
[Fur.bib] @pmid_16855256: Fur-mediated iron transport in E. coli
[iron.bib] @pmid_25157846: Iron homeostasis and Fur regulation
bib list — List Entries in .bib Files
List all entries in all .bib files, or in a specific file.
| Argument | Required | Description |
|---|---|---|
--bib FILE |
No | List only this .bib file (default: all files in directory) |
pubmed-proxy bib list --dir ./citations
pubmed-proxy bib list --bib Fur.bib --dir ./citations
Output:
Fur.bib (3 entries):
@pmid_23381990: The Fur regulon of pathogenic Neisseria (2013)
@pmid_16855256: Fur-mediated iron transport in E. coli (2006)
@pmid_25157846: Iron homeostasis and Fur regulation (2014)
bib show — Show Full BibTeX for a Citekey
Look up a citekey across all .bib files and print the complete BibTeX entry.
| Argument | Required | Description |
|---|---|---|
citekey |
Yes | Citation key (e.g. pmid_23381990) |
pubmed-proxy bib show pmid_23381990
pubmed-proxy bib show pmid_23381990 --dir ./citations
Output: the full @article{...} BibTeX block, preceded by # From <filename>.
bib validate — Validate Citekeys in Markdown
Check that all @citekey references and PMID:XXXXX patterns in a markdown file
exist in the specified .bib file.
| Argument | Required | Description |
|---|---|---|
file |
Yes | Markdown file to validate |
--bib FILE |
Yes | .bib file to validate against |
pubmed-proxy bib validate evidence.md --bib evidence.bib --dir ./citations
Output on success: OK: 5 citekeys validated, 2 raw PMIDs all in bib
Output on failure (exits with code 1):
MISSING citekeys (not in evidence.bib):
@pmid_99999999
UNCONVERTED PMIDs (still using PMID:XXXXX format):
PMID:12345678
bib validate-all — Validate All Evidence Files
Scan all markdown files in a directory and validate each one against its
corresponding .bib file (e.g. Fur.md against Fur.bib).
| Argument | Required | Description |
|---|---|---|
--scan-dir DIR |
No | Directory containing markdown files (default: current directory) |
pubmed-proxy bib validate-all --scan-dir ./evidence --dir ./citations
Output on success: All evidence files validated (12 bib files)
Output on failure (exits with code 1):
Fur.md: 2 missing citekey(s) — pmid_99999999, pmid_88888888
iron.md: 1 unconverted PMID(s)
Total: 3 issues across 2 files
bib init — Batch-Create .bib Files from Markdown
Scan markdown files for PMID:XXXXX references, fetch BibTeX from PubMed for each,
and create per-file .bib files (e.g. Fur.md produces Fur.bib).
| Argument | Required | Description |
|---|---|---|
--scan-dir DIR |
No | Directory containing markdown files (default: current directory) |
pubmed-proxy bib init --scan-dir ./evidence --dir ./citations
Output:
Found 47 unique PMIDs across 12 files
Fetching PMID: 23381990...
Fetching PMID: 16855256...
...
Fetched 45/47 PMIDs
Created/updated 12 .bib files in ./citations
bib stats — Citation Database Statistics
Print summary statistics for all .bib files in a directory.
pubmed-proxy bib stats --dir ./citations
Output:
Citation Database Statistics:
.bib files: 12
Total entries: 47
Unique citekeys: 45
Claude Desktop Configuration
Add to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"pubmed": {
"command": "python",
"args": ["-m", "pubmed_proxy_mcp"],
"env": {
"NCBI_API_KEY": "your-api-key"
}
}
}
}
The NCBI_API_KEY in the env block is optional but recommended for the higher 10 req/s
rate limit. Without it the server works at 3 req/s. Replace "your-api-key" with your
actual key from https://www.ncbi.nlm.nih.gov/account/settings/.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。