skills/fetch-pubmed-recent/SKILL.md
Fetches PubMed articles posted in a given date window matching a keyword set, returning normalized records (PMID, title, authors, abstract, journal, date, DOI, URL). Uses NCBI E-utilities (`esearch` + `esummary` + `efetch`) via WebFetch for portability, but prefers a PubMed MCP server's `search_articles` + `get_article_metadata` tools when one is connected (faster, paginated, parsed). Builds date-bounded queries with optional MeSH expansion. Domain-neutral - usable for any PubMed scan, not just one project. Use when user mentions PubMed, NCBI, last-N-days PubMed, weekly PubMed scan, MeSH search, or when a literature-scan agent needs structured PubMed records.
npx skillsauth add lyndonkl/claude fetch-pubmed-recentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch PubMed records for a date window + keyword set. Normalize the output to the same shape as fetch-preprint-recent so a calling agent can dedupe across sources.
- [ ] Step 1: Detect transport — prefer PubMed MCP if available, else E-utilities via WebFetch
- [ ] Step 2: Build the keyword query with explicit date bounds
- [ ] Step 3: Execute search → list of PMIDs (page if > 100)
- [ ] Step 4: Fetch metadata + abstracts for each PMID batch
- [ ] Step 5: Normalize records to canonical shape
- [ ] Step 6: Return matched records + summary
Step 1 — Detect transport
At session start the runtime exposes any connected MCP servers. Check whether tools matching mcp__*PubMed*__search_articles and mcp__*PubMed*__get_article_metadata are available.
https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term={query}&retmode=json&retmax=200https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id={pmids_csv}&retmode=jsonhttps://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id={pmids_csv}&rettype=abstract&retmode=xmlBoth transports return the same downstream shape. The skill caller should not need to care which was used (record transport_used in the return summary so debugging is possible).
Step 2 — Build the date-bounded query
PubMed accepts boolean keyword expressions plus a date filter. The canonical date filter for "papers indexed in PubMed during this window" is:
("YYYY/MM/DD"[PDAT] : "YYYY/MM/DD"[PDAT])
PDAT is the publication date — the most stable choice for a weekly digest. (EDAT is the entry-into-PubMed date, useful if you want "newly indexed even if old"; MHDA is the MeSH-indexed date. Default PDAT.)
For each watchlist keyword, expand into a sub-query:
"protein language model"[Title/Abstract]("Alzheimer Disease"[MeSH] OR "alzheimer's disease"[Title/Abstract]) — only when the keyword has a clean MeSH match the caller has confirmed; do not auto-MeSH-expand or you'll widen the net unpredictably.Combine sub-queries with OR, then AND the date filter:
(("term1"[Title/Abstract]) OR ("term2"[Title/Abstract]) OR ...) AND ("2026/05/04"[PDAT] : "2026/05/10"[PDAT])
Watch out for special characters — escape () inside terms by quoting the term.
Step 3 — Execute search
Call the search tool. Expected output is a list of PMIDs and a count.
If count > 200, page: rerun the search with retstart=200, retstart=400, etc. Cap at 1,000 PMIDs (5 pages). If a 7-day window matches more than 1,000 records, the keyword set is too broad — surface this and ask the calling agent to tighten.
Step 4 — Fetch metadata + abstracts
Batch the PMIDs (200 per esummary call). Pull:
et al. truncation is the digest's job, not this skill's)fulljournalname)pubdate, sortpubdate)articleids[].idtype == 'doi')efetch call with rettype=abstract since esummary doesn't return abstracts)Abstract fetch is the slow part. Batch 100 PMIDs at a time. If abstract fetch fails for a record, keep it but with abstract: null and a warnings flag.
Step 5 — Normalize
Same canonical shape as fetch-preprint-recent:
{
"id": "PMID:39123456", // PMID-prefixed for source clarity
"title": "...",
"authors": ["Smith J", "Doe A", ...],
"abstract": "...",
"date": "2026-05-07", // YYYY-MM-DD parsed from pubdate
"server": "pubmed",
"journal": "Nature Biotechnology",
"doi": "10.1038/s41587-026-12345-6", // if present
"url": "https://pubmed.ncbi.nlm.nih.gov/39123456/",
"matched_keywords": ["protein language model"]
}
URL pattern: https://pubmed.ncbi.nlm.nih.gov/{pmid}/ — the canonical PubMed link. Optional secondary URL via DOI: https://doi.org/{doi} for the publisher's page.
Step 6 — Return
{
"server": "pubmed",
"transport_used": "mcp" | "eutils",
"window": "2026-05-04/2026-05-10",
"query": "(...full query string...)",
"fetched_total": 47,
"matched_total": 47, // PubMed filter is server-side, so fetched == matched
"fetch_errors": [],
"records": [ ... ]
}
Cache the raw search + metadata responses to .cache/{YYYY-WW}-pubmed.json.
Pattern A — Standard weekly scan: PDAT-bounded query with all watchlist keywords OR'd together. The default.
Pattern B — Newly-indexed reach-back: when the user wants "papers PubMed indexed this week, even if published earlier" (useful for older preprints just appearing in PubMed), swap PDAT for EDAT. Document the choice in the digest.
Pattern C — High-precision MeSH-only search: when keyword matching is producing too much noise, ask the user for the exact MeSH headings they care about and search term[MeSH] only. Higher precision, lower recall.
Pattern D — Author-specific watch: outside this skill's default scope but easy — add (Smith J[Author] OR Doe A[Author]) as an additional OR clause to the keyword group.
PDAT is the bug that turns a 7-paper digest into a 70,000-paper data dump.[Title/Abstract] to disable expansion unless MeSH expansion is explicitly requested.efetch with rettype=abstract occasionally times out for batches > 100. On failure, halve the batch and retry; only after two full halvings do you give up on a record.PMID: prefix from id. It distinguishes PubMed records from preprint DOIs at a glance — important during cross-source dedupe in the caller.NCBI_API_KEY), include it as &api_key=....Publisher (in-process, not yet fully indexed). Fine to include but note status if available.| Field | E-utilities (fallback) | MCP (preferred) |
| -------------- | ------------------------------------------------------------------------ | ------------------------------------- |
| Search | esearch.fcgi?db=pubmed&term={q}&retmode=json | search_articles(query=...) |
| Metadata | esummary.fcgi?db=pubmed&id={pmids}&retmode=json | get_article_metadata(pmids=...) |
| Abstract | efetch.fcgi?db=pubmed&id={pmids}&rettype=abstract&retmode=xml | included in metadata when MCP returns it |
| Date filter | ("YYYY/MM/DD"[PDAT] : "YYYY/MM/DD"[PDAT]) | same — pass inside query string |
| Page size | 200 (search), 100-200 (summary), 100 (abstract) | MCP server's choice |
| Auth | optional api_key query param (3 → 10 rps) | per MCP server config |
| Canonical URL | https://pubmed.ncbi.nlm.nih.gov/{pmid}/ | |
testing
--- name: advisory-edit description: A strict advisory-only editing discipline for a writer who dictates ("speaks out") essays and wants help WITHOUT having their voice changed. The editor directs structure, flags grammar, and suggests strategic language — but never modifies the writer's text unless the writer explicitly says "apply" / "make that change" / "rewrite this." Produces a line-referenced, suggestion-only critique where every item is marked the writer's call. Four passes: structural, l
testing
Provides the house style for analyst-grade strategist writing — third-person register with sparing first-person, no em dashes, no "not X, not Y, not Z" negation cascades, numbered footnote citations rather than inline source parentheticals, specific opinion-signaling phrases, and topic-forward paragraph structure modeled on voice patterns observed in Damodaran's Musings on Markets and Thompson's Stratechery. Use when consolidating working notes into a finished long-form strategist or analyst report that must read as written by a senior human analyst rather than an AI assistant.
testing
Renders a markdown report to a PDF using pandoc with xelatex (11pt serif body, 1-inch margins, numbered footnotes, formal heading hierarchy). Requires a one-time install of pandoc and a LaTeX engine on the user's machine — basictex on macOS or texlive-xetex on Linux. Does not attempt automatic install. Fails loudly with the exact install commands if pandoc or xelatex is missing on the user's PATH. Use when producing a finished strategist or analyst report PDF from a polished markdown source.
testing
Produces step-by-step computational walkthroughs of vector and matrix operations as a sequence of numbered "frames", showing the explicit state at each step. The text-equivalent of a 3Blue1Brown animation — each frame shows what changed and why, so the learner can re-trace the operation by hand. Use when the learner needs to *see* a computation unfold (eigenvalue computation, attention with 3 tokens, gradient descent step, SVD on a 2×2, layer norm on a 3-vector, softmax of a small input), when an explanation has been given but the learner needs to ground it in a worked example, or when introducing an operation that's intimidating in symbol form but trivial in pencil-and-paper form.