@djmima/pubmed-mcp 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +827 -793
- package/dist/cli/commands.js +114 -114
- package/dist/cli/run.js +31 -31
- package/dist/pubmed/client.d.ts.map +1 -1
- package/dist/pubmed/client.js +8 -4
- package/dist/pubmed/client.js.map +1 -1
- package/dist/utils/xml.d.ts.map +1 -1
- package/dist/utils/xml.js +2 -1
- package/dist/utils/xml.js.map +1 -1
- package/package.json +3 -2
- package/skills/pubmed-cli/SKILL.md +79 -79
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pubmed-cli
|
|
3
|
-
description: Search PubMed and PubMed Central from the shell with the `pubmed` CLI, saving results as JSON files and extracting only the fields you need with jq. Use for literature searches, article metadata and abstracts, full text, citing or similar articles, PMID/PMCID/DOI conversion, citation lookup, and open-access checks when a shell is available and the `pubmed` command is installed. Prefer it over the PubMed MCP tools when results are large (metadata for more than a few articles, any full text) or will be reused.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# PubMed CLI
|
|
7
|
-
|
|
8
|
-
`pubmed` runs the same code as the PubMed MCP tools and prints the same JSON, to stdout or to a file. Save results to files and read them with `jq` so that large records never enter the context: metadata is about 5 KB per article, and one full text is 50–100 KB.
|
|
9
|
-
|
|
10
|
-
If `pubmed --help` fails, the CLI is not installed; use the PubMed MCP tools instead.
|
|
11
|
-
|
|
12
|
-
## Rules
|
|
13
|
-
|
|
14
|
-
1. Save anything larger than a PMID list with `-o <file>`, then read it with `jq`. Do not `cat` metadata or full-text files. With `-o`, the CLI prints a summary and the file size to stderr.
|
|
15
|
-
2. Pass all IDs to one invocation, as arguments or one per line on stdin with `-`. The CLI splits long lists into batches and paces requests under NCBI's rate limit. Do not run several `pubmed` processes in parallel; together they can exceed the limit.
|
|
16
|
-
3. Before concluding that a low or zero `total_count` means no literature exists, check `query_translation`, `warnings`, and `errors` in the search output.
|
|
17
|
-
4. Exit status is 0 on success, 1 when NCBI or a file operation fails, and 2 for invalid usage; the reason is on stderr. Use `set -o pipefail` in pipelines.
|
|
18
|
-
5. On Windows, run pipelines in Git Bash or PowerShell 7. In Windows PowerShell 5.1, write files with `-o` rather than `>`, which would save them as UTF-16.
|
|
19
|
-
|
|
20
|
-
## Commands
|
|
21
|
-
|
|
22
|
-
| Command | MCP tool | Input | IDs per request |
|
|
23
|
-
|---|---|---|---|
|
|
24
|
-
| `pubmed search <query>` | `search_articles` | query, or `-` for stdin | — |
|
|
25
|
-
| `pubmed metadata <pmid>...` | `get_article_metadata` | PMIDs | 200 |
|
|
26
|
-
| `pubmed related <pmid>...` | `find_related_articles` | PMIDs | 200 |
|
|
27
|
-
| `pubmed citation --journal J --year Y ...` | `lookup_article_by_citation` | options, or `--input <file\|->` with a JSON array or JSON Lines | 100 |
|
|
28
|
-
| `pubmed convert <id>... [--id-type pmid\|pmcid\|doi]` | `convert_article_ids` | IDs of one type | 200 |
|
|
29
|
-
| `pubmed fulltext <pmcid>...` | `get_full_text_article` | PMCIDs | 20 |
|
|
30
|
-
| `pubmed copyright <pmid>...` | `get_copyright_status` | PMIDs | 50 |
|
|
31
|
-
|
|
32
|
-
Options are the MCP parameters in kebab-case: `--max-results`, `--retstart`, `--sort`, `--field`, `--date-from`, `--date-to`, `--datetype`, `--link-type`, `--id-type`, `--authors`, `--affiliations`. Run `pubmed <command> --help` for details.
|
|
33
|
-
|
|
34
|
-
## Output fields
|
|
35
|
-
|
|
36
|
-
- search: `.pmids[]`, `.total_count`, `.has_more`, `.query_translation`, `.warnings`, `.errors`
|
|
37
|
-
- metadata: `.articles[]` with `.identifiers.pmid`, `.identifiers.doi`, `.identifiers.pmcid`, `.title`, `.abstract`, `.authors[]` (`.last_name`, `.fore_name`, `.initials`, `.collective_name` for group authors, `.affiliations[]` only with `--affiliations true`), `.author_count`, `.journal.title`, `.journal.iso_abbreviation`, `.publication_date.year`, `.mesh_terms[]`, `.keywords[]`, `.article_types[]`, `.citation` (`.volume`, `.issue`, `.pages`)
|
|
38
|
-
- related: `.linksets[].linksetdbs[].links[]`; `citing_pmc_articles` gives PMC IDs without the `PMC` prefix
|
|
39
|
-
- citation: `.citations[]` with `.key` and `.pmid` (`""` when not found)
|
|
40
|
-
- convert: `.records[]` with `.pmid`, `.pmcid`, `.doi`, `."requested-id"`, `.errmsg`
|
|
41
|
-
- fulltext: `.articles[]` with `.identifiers.pmcid`, `.title`, `.full_text`; unavailable IDs in `.errors[]`
|
|
42
|
-
- copyright: `.statuses[]` with `.pmid`, `.pmcid`, `.has_full_text`, `.license`, `.is_open_access`
|
|
43
|
-
|
|
44
|
-
## Recipes
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Search, then check how PubMed interpreted the query
|
|
48
|
-
pubmed search 'TP53[tiab] AND myelodysplastic syndromes[mh]' --max-results 200 -o search.json
|
|
49
|
-
jq '{total_count, query_translation, warnings, errors}' search.json
|
|
50
|
-
|
|
51
|
-
# Metadata for every hit, listed one line per article
|
|
52
|
-
jq -r '.pmids[]' search.json | pubmed metadata - -o meta.json
|
|
53
|
-
jq -r '.articles[] | [.identifiers.pmid, .publication_date.year, .journal.iso_abbreviation, .title] | @tsv' meta.json
|
|
54
|
-
|
|
55
|
-
# Smaller records: first and last author only (affiliations are left out unless --affiliations true)
|
|
56
|
-
# (`pubmed metadata --help` lists --authors all|first_last|first|none; .author_count is always the full count)
|
|
57
|
-
jq -r '.pmids[]' search.json | pubmed metadata - --authors first_last -o meta.json
|
|
58
|
-
|
|
59
|
-
# One abstract
|
|
60
|
-
jq -r --arg p 34265844 '.articles[] | select(.identifiers.pmid == $p) | .abstract' meta.json
|
|
61
|
-
|
|
62
|
-
# Filter by a term in the title or abstract, or by article type
|
|
63
|
-
jq -c '.articles[] | select((.title + " " + .abstract) | test("venetoclax"; "i")) | {pmid: .identifiers.pmid, title}' meta.json
|
|
64
|
-
jq -r '.articles[] | select(.article_types | index("Review")) | .identifiers.pmid' meta.json
|
|
65
|
-
|
|
66
|
-
# Full text only where it is available; search it instead of reading it whole
|
|
67
|
-
jq -r '.pmids[]' search.json | pubmed copyright - -o rights.json
|
|
68
|
-
jq -r '.statuses[] | select(.has_full_text) | .pmcid' rights.json | pubmed fulltext - -o full.json
|
|
69
|
-
jq -r '.articles[] | select(.identifiers.pmcid == "PMC8371605") | .full_text' full.json | grep -n -i -C1 'resistance'
|
|
70
|
-
|
|
71
|
-
# Articles citing a paper, as metadata
|
|
72
|
-
pubmed related 34265844 --link-type citing_pmc_articles -o citing.json
|
|
73
|
-
jq -r '.linksets[].linksetdbs[].links[]' citing.json | pubmed convert - --id-type pmcid -o citing_ids.json
|
|
74
|
-
jq -r '.records[].pmid // empty' citing_ids.json | pubmed metadata - -o citing_meta.json
|
|
75
|
-
|
|
76
|
-
# Resolve references from a JSON Lines file of {journal, year, volume, first_page, author}
|
|
77
|
-
pubmed citation --input refs.jsonl -o matched.json
|
|
78
|
-
jq -r '.citations[] | [.key, .pmid] | @tsv' matched.json
|
|
79
|
-
```
|
|
1
|
+
---
|
|
2
|
+
name: pubmed-cli
|
|
3
|
+
description: Search PubMed and PubMed Central from the shell with the `pubmed` CLI, saving results as JSON files and extracting only the fields you need with jq. Use for literature searches, article metadata and abstracts, full text, citing or similar articles, PMID/PMCID/DOI conversion, citation lookup, and open-access checks when a shell is available and the `pubmed` command is installed. Prefer it over the PubMed MCP tools when results are large (metadata for more than a few articles, any full text) or will be reused.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PubMed CLI
|
|
7
|
+
|
|
8
|
+
`pubmed` runs the same code as the PubMed MCP tools and prints the same JSON, to stdout or to a file. Save results to files and read them with `jq` so that large records never enter the context: metadata is about 5 KB per article, and one full text is 50–100 KB.
|
|
9
|
+
|
|
10
|
+
If `pubmed --help` fails, the CLI is not installed; use the PubMed MCP tools instead.
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
1. Save anything larger than a PMID list with `-o <file>`, then read it with `jq`. Do not `cat` metadata or full-text files. With `-o`, the CLI prints a summary and the file size to stderr.
|
|
15
|
+
2. Pass all IDs to one invocation, as arguments or one per line on stdin with `-`. The CLI splits long lists into batches and paces requests under NCBI's rate limit. Do not run several `pubmed` processes in parallel; together they can exceed the limit.
|
|
16
|
+
3. Before concluding that a low or zero `total_count` means no literature exists, check `query_translation`, `warnings`, and `errors` in the search output.
|
|
17
|
+
4. Exit status is 0 on success, 1 when NCBI or a file operation fails, and 2 for invalid usage; the reason is on stderr. Use `set -o pipefail` in pipelines.
|
|
18
|
+
5. On Windows, run pipelines in Git Bash or PowerShell 7. In Windows PowerShell 5.1, write files with `-o` rather than `>`, which would save them as UTF-16.
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
| Command | MCP tool | Input | IDs per request |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| `pubmed search <query>` | `search_articles` | query, or `-` for stdin | — |
|
|
25
|
+
| `pubmed metadata <pmid>...` | `get_article_metadata` | PMIDs | 200 |
|
|
26
|
+
| `pubmed related <pmid>...` | `find_related_articles` | PMIDs | 200 |
|
|
27
|
+
| `pubmed citation --journal J --year Y ...` | `lookup_article_by_citation` | options, or `--input <file\|->` with a JSON array or JSON Lines | 100 |
|
|
28
|
+
| `pubmed convert <id>... [--id-type pmid\|pmcid\|doi]` | `convert_article_ids` | IDs of one type | 200 |
|
|
29
|
+
| `pubmed fulltext <pmcid>...` | `get_full_text_article` | PMCIDs | 20 |
|
|
30
|
+
| `pubmed copyright <pmid>...` | `get_copyright_status` | PMIDs | 50 |
|
|
31
|
+
|
|
32
|
+
Options are the MCP parameters in kebab-case: `--max-results`, `--retstart`, `--sort`, `--field`, `--date-from`, `--date-to`, `--datetype`, `--link-type`, `--id-type`, `--authors`, `--affiliations`. Run `pubmed <command> --help` for details.
|
|
33
|
+
|
|
34
|
+
## Output fields
|
|
35
|
+
|
|
36
|
+
- search: `.pmids[]`, `.total_count`, `.has_more`, `.query_translation`, `.warnings`, `.errors`
|
|
37
|
+
- metadata: `.articles[]` with `.identifiers.pmid`, `.identifiers.doi`, `.identifiers.pmcid`, `.title`, `.abstract`, `.authors[]` (`.last_name`, `.fore_name`, `.initials`, `.collective_name` for group authors, `.affiliations[]` only with `--affiliations true`), `.author_count`, `.journal.title`, `.journal.iso_abbreviation`, `.publication_date.year`, `.mesh_terms[]`, `.keywords[]`, `.article_types[]`, `.citation` (`.volume`, `.issue`, `.pages`)
|
|
38
|
+
- related: `.linksets[].linksetdbs[].links[]`; `citing_pmc_articles` gives PMC IDs without the `PMC` prefix
|
|
39
|
+
- citation: `.citations[]` with `.key` and `.pmid` (`""` when not found)
|
|
40
|
+
- convert: `.records[]` with `.pmid`, `.pmcid`, `.doi`, `."requested-id"`, `.errmsg`
|
|
41
|
+
- fulltext: `.articles[]` with `.identifiers.pmcid`, `.title`, `.full_text`; unavailable IDs in `.errors[]`
|
|
42
|
+
- copyright: `.statuses[]` with `.pmid`, `.pmcid`, `.has_full_text`, `.license`, `.is_open_access`
|
|
43
|
+
|
|
44
|
+
## Recipes
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Search, then check how PubMed interpreted the query
|
|
48
|
+
pubmed search 'TP53[tiab] AND myelodysplastic syndromes[mh]' --max-results 200 -o search.json
|
|
49
|
+
jq '{total_count, query_translation, warnings, errors}' search.json
|
|
50
|
+
|
|
51
|
+
# Metadata for every hit, listed one line per article
|
|
52
|
+
jq -r '.pmids[]' search.json | pubmed metadata - -o meta.json
|
|
53
|
+
jq -r '.articles[] | [.identifiers.pmid, .publication_date.year, .journal.iso_abbreviation, .title] | @tsv' meta.json
|
|
54
|
+
|
|
55
|
+
# Smaller records: first and last author only (affiliations are left out unless --affiliations true)
|
|
56
|
+
# (`pubmed metadata --help` lists --authors all|first_last|first|none; .author_count is always the full count)
|
|
57
|
+
jq -r '.pmids[]' search.json | pubmed metadata - --authors first_last -o meta.json
|
|
58
|
+
|
|
59
|
+
# One abstract
|
|
60
|
+
jq -r --arg p 34265844 '.articles[] | select(.identifiers.pmid == $p) | .abstract' meta.json
|
|
61
|
+
|
|
62
|
+
# Filter by a term in the title or abstract, or by article type
|
|
63
|
+
jq -c '.articles[] | select((.title + " " + .abstract) | test("venetoclax"; "i")) | {pmid: .identifiers.pmid, title}' meta.json
|
|
64
|
+
jq -r '.articles[] | select(.article_types | index("Review")) | .identifiers.pmid' meta.json
|
|
65
|
+
|
|
66
|
+
# Full text only where it is available; search it instead of reading it whole
|
|
67
|
+
jq -r '.pmids[]' search.json | pubmed copyright - -o rights.json
|
|
68
|
+
jq -r '.statuses[] | select(.has_full_text) | .pmcid' rights.json | pubmed fulltext - -o full.json
|
|
69
|
+
jq -r '.articles[] | select(.identifiers.pmcid == "PMC8371605") | .full_text' full.json | grep -n -i -C1 'resistance'
|
|
70
|
+
|
|
71
|
+
# Articles citing a paper, as metadata
|
|
72
|
+
pubmed related 34265844 --link-type citing_pmc_articles -o citing.json
|
|
73
|
+
jq -r '.linksets[].linksetdbs[].links[]' citing.json | pubmed convert - --id-type pmcid -o citing_ids.json
|
|
74
|
+
jq -r '.records[].pmid // empty' citing_ids.json | pubmed metadata - -o citing_meta.json
|
|
75
|
+
|
|
76
|
+
# Resolve references from a JSON Lines file of {journal, year, volume, first_page, author}
|
|
77
|
+
pubmed citation --input refs.jsonl -o matched.json
|
|
78
|
+
jq -r '.citations[] | [.key, .pmid] | @tsv' matched.json
|
|
79
|
+
```
|