@cyanheads/pubmed-mcp-server 2.9.9 → 2.10.0
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/AGENTS.md +2 -2
- package/CLAUDE.md +2 -2
- package/README.md +19 -4
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/_text.d.ts +22 -0
- package/dist/mcp-server/tools/definitions/_text.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/_text.js +32 -0
- package/dist/mcp-server/tools/definitions/_text.js.map +1 -0
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts +35 -0
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js +634 -123
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.d.ts +87 -0
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js +195 -0
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js +29 -8
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js.map +1 -1
- package/dist/services/europe-pmc/api-client.d.ts +14 -1
- package/dist/services/europe-pmc/api-client.d.ts.map +1 -1
- package/dist/services/europe-pmc/api-client.js +21 -25
- package/dist/services/europe-pmc/api-client.js.map +1 -1
- package/dist/services/europe-pmc/europe-pmc-service.d.ts +21 -7
- package/dist/services/europe-pmc/europe-pmc-service.d.ts.map +1 -1
- package/dist/services/europe-pmc/europe-pmc-service.js +39 -6
- package/dist/services/europe-pmc/europe-pmc-service.js.map +1 -1
- package/dist/services/europe-pmc/types.d.ts +9 -0
- package/dist/services/europe-pmc/types.d.ts.map +1 -1
- package/dist/services/openalex/api-client.d.ts +15 -1
- package/dist/services/openalex/api-client.d.ts.map +1 -1
- package/dist/services/openalex/api-client.js +21 -24
- package/dist/services/openalex/api-client.js.map +1 -1
- package/package.json +1 -1
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/pubmed-mcp-server
|
|
4
|
-
**Version:** 2.
|
|
4
|
+
**Version:** 2.10.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.11.0`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
7
|
|
|
@@ -246,7 +246,7 @@ src/
|
|
|
246
246
|
parsing/ # XML parsers (article, esummary, PMC)
|
|
247
247
|
formatting/ # Citation formatter (APA, MLA, BibTeX, RIS)
|
|
248
248
|
mcp-server/
|
|
249
|
-
tools/definitions/ #
|
|
249
|
+
tools/definitions/ # 11 tool definitions (*.tool.ts)
|
|
250
250
|
resources/definitions/ # database-info.resource.ts
|
|
251
251
|
prompts/definitions/ # research-plan.prompt.ts
|
|
252
252
|
```
|
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/pubmed-mcp-server
|
|
4
|
-
**Version:** 2.
|
|
4
|
+
**Version:** 2.10.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.11.0`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
7
|
|
|
@@ -246,7 +246,7 @@ src/
|
|
|
246
246
|
parsing/ # XML parsers (article, esummary, PMC)
|
|
247
247
|
formatting/ # Citation formatter (APA, MLA, BibTeX, RIS)
|
|
248
248
|
mcp-server/
|
|
249
|
-
tools/definitions/ #
|
|
249
|
+
tools/definitions/ # 11 tool definitions (*.tool.ts)
|
|
250
250
|
resources/definitions/ # database-info.resource.ts
|
|
251
251
|
prompts/definitions/ # research-plan.prompt.ts
|
|
252
252
|
```
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@cyanheads/pubmed-mcp-server</h1>
|
|
3
3
|
<p><b>Search PubMed/Europe PMC, fetch articles and full text (PMC/EPMC/Unpaywall), citations, MeSH terms via MCP. STDIO or Streamable HTTP.</b>
|
|
4
|
-
<div>
|
|
4
|
+
<div>11 Tools • 1 Resource • 1 Prompt</div>
|
|
5
5
|
</p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/pubmed-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/pubmed-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -31,12 +31,13 @@
|
|
|
31
31
|
|
|
32
32
|
## Tools
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
11 tools for working with PubMed, PubMed Central, and Europe PMC data:
|
|
35
35
|
|
|
36
36
|
| Tool | Description |
|
|
37
37
|
|:---|:---|
|
|
38
38
|
| `pubmed_search_articles` | Search PubMed with full query syntax, field-specific filters, date ranges, pagination, and optional brief summaries |
|
|
39
39
|
| `pubmed_europepmc_search` | Search Europe PMC for preprints, patents, Agricola, and EPMC-only OA records that don't surface in PubMed. Cursor-based pagination. |
|
|
40
|
+
| `pubmed_europepmc_fetch` | Fetch complete Europe PMC records — including the untruncated abstract — by `source` + `epmcId`, the only identifier many preprint, patent, and Agricola records carry |
|
|
40
41
|
| `pubmed_fetch_articles` | Fetch full article metadata by PMIDs — abstract, authors, journal, MeSH terms, grants |
|
|
41
42
|
| `pubmed_fetch_fulltext` | Fetch full-text articles via a chain: NCBI PMC EFetch → Europe PMC `fullTextXML` → Unpaywall. Accepts PMIDs, PMCIDs, or DOIs. |
|
|
42
43
|
| `pubmed_format_citations` | Generate formatted citations in APA 7th, MLA 9th, BibTeX, RIS, or Vancouver (ICMJE/NLM) |
|
|
@@ -86,6 +87,7 @@ Fetch full-text articles via a three-stage chain: NCBI PMC EFetch → Europe PMC
|
|
|
86
87
|
- Structured unavailable reasons (`not-found`, `no-pmc-fallback-disabled`, `no-epmc-fulltext`, `no-doi`, `no-oa`, `fetch-failed`, `parse-failed`, `service-error`) so callers can retry or explain to users without parsing text
|
|
87
88
|
- Each `unavailable` entry carries `idType` (`pmid` / `pmcid` / `doi`) and `triedTiers` — per-tier outcomes (`not-attempted`, `miss`, `no-fulltext`, `service-error`, …) in execution order, so callers can see which stage failed and why
|
|
88
89
|
- Section filtering by title (case-insensitive match, e.g. `["methods", "results"]`) and configurable max sections apply to PMC output
|
|
90
|
+
- Character budgets keep context size predictable: `maxCharacters` caps body text per article (PMC sections and subsections, or the Unpaywall body), `maxCharactersPerSection` caps a single PMC section, and `overflowMode` picks between `truncate` (fill sections in document order) and `outline` (split the budget evenly so every heading survives with an excerpt). Budgets run after the semantic filters, and a `truncation` object reports per-article and per-section character counts whenever anything was shortened
|
|
89
91
|
- Up to 10 articles per request
|
|
90
92
|
|
|
91
93
|
---
|
|
@@ -98,6 +100,19 @@ Search Europe PMC (EBI/EMBL-EBI), a broader open-access biomedical corpus than P
|
|
|
98
100
|
- Default sources `["MED", "PMC", "PPR"]`; pass `sources` to include `PAT` / `AGR`
|
|
99
101
|
- Cursor-based pagination via `cursorMark` (unlike `pubmed_search_articles`, which uses offset) — `*` for the first page, return `nextCursorMark` for the next
|
|
100
102
|
- Output discriminator on `source` plus optional `pmid` / `pmcId` / `doi` cross-walking
|
|
103
|
+
- `abstractSnippet` is capped at 400 characters to keep a page bounded; `abstractTruncated` says whether it was cut, and `pubmed_europepmc_fetch` returns the whole abstract for the records worth reading in full
|
|
104
|
+
- Disabled when `EUROPEPMC_ENABLED=false`; tool is not registered in that case
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### `pubmed_europepmc_fetch`
|
|
109
|
+
|
|
110
|
+
Fetch complete Europe PMC records by `source` + `epmcId`, the detail counterpart to `pubmed_europepmc_search`.
|
|
111
|
+
|
|
112
|
+
- Returns the full, untruncated abstract as display-ready plain text — markup stripped, HTML entities decoded
|
|
113
|
+
- Addressed by the `source` and `epmcId` of a search hit, the only identifier preprint (`PPR`), patent (`PAT`), and Agricola (`AGR`) records reliably carry — `pubmed_fetch_articles` needs a PMID and `pubmed_fetch_fulltext` needs a PMCID, PMID, or DOI
|
|
114
|
+
- Up to 25 records per call, resolved in a single Europe PMC request
|
|
115
|
+
- Pairs unresolved requests back to the caller in `notFound` instead of failing the batch
|
|
101
116
|
- Disabled when `EUROPEPMC_ENABLED=false`; tool is not registered in that case
|
|
102
117
|
|
|
103
118
|
---
|
|
@@ -355,7 +370,7 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
|
|
|
355
370
|
|
|
356
371
|
| Directory | Purpose |
|
|
357
372
|
|:---|:---|
|
|
358
|
-
| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`).
|
|
373
|
+
| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). Eleven tools across PubMed, PMC, and Europe PMC. |
|
|
359
374
|
| `src/mcp-server/resources` | Resource definitions. Database info resource. |
|
|
360
375
|
| `src/mcp-server/prompts` | Prompt definitions. Research plan prompt. |
|
|
361
376
|
| `src/services/ncbi` | NCBI E-utilities service layer — API client, queue, parser, formatter. |
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { findRelatedTool } from './mcp-server/tools/definitions/find-related.too
|
|
|
14
14
|
import { formatCitationsTool } from './mcp-server/tools/definitions/format-citations.tool.js';
|
|
15
15
|
import { lookupCitationTool } from './mcp-server/tools/definitions/lookup-citation.tool.js';
|
|
16
16
|
import { lookupMeshTool } from './mcp-server/tools/definitions/lookup-mesh.tool.js';
|
|
17
|
+
import { pubmedEuropepmcFetchTool } from './mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js';
|
|
17
18
|
import { pubmedEuropepmcSearchTool } from './mcp-server/tools/definitions/pubmed-europepmc-search.tool.js';
|
|
18
19
|
import { searchArticlesTool } from './mcp-server/tools/definitions/search-articles.tool.js';
|
|
19
20
|
import { spellCheckTool } from './mcp-server/tools/definitions/spell-check.tool.js';
|
|
@@ -32,7 +33,7 @@ const tools = [
|
|
|
32
33
|
lookupMeshTool,
|
|
33
34
|
lookupCitationTool,
|
|
34
35
|
convertIdsTool,
|
|
35
|
-
...(config.europepmcEnabled ? [pubmedEuropepmcSearchTool] : []),
|
|
36
|
+
...(config.europepmcEnabled ? [pubmedEuropepmcSearchTool, pubmedEuropepmcFetchTool] : []),
|
|
36
37
|
];
|
|
37
38
|
await createApp({
|
|
38
39
|
name: 'pubmed-mcp-server',
|
|
@@ -40,7 +41,7 @@ await createApp({
|
|
|
40
41
|
tools,
|
|
41
42
|
resources: [databaseInfoResource],
|
|
42
43
|
prompts: [researchPlanPrompt],
|
|
43
|
-
instructions: "Use the pubmed_* tools to search PubMed and PubMed Central, fetch article metadata and full text, format citations, and find related articles via NCBI's E-utilities. Articles are keyed by PMID (integer); PMC full text by PMCID (`PMC` prefix); most also carry a DOI. Typical flow: `pubmed_search_articles` → `pubmed_fetch_articles` → `pubmed_fetch_fulltext`. When PubMed itself comes up empty (preprints, EPMC-only OA), broaden via `pubmed_europepmc_search
|
|
44
|
+
instructions: "Use the pubmed_* tools to search PubMed and PubMed Central, fetch article metadata and full text, format citations, and find related articles via NCBI's E-utilities. Articles are keyed by PMID (integer); PMC full text by PMCID (`PMC` prefix); most also carry a DOI. Typical flow: `pubmed_search_articles` → `pubmed_fetch_articles` → `pubmed_fetch_fulltext`. When PubMed itself comes up empty (preprints, EPMC-only OA), broaden via `pubmed_europepmc_search`, then `pubmed_europepmc_fetch` with a hit's `source` + `epmcId` for its complete abstract. Prefer deterministic resolvers when inputs are structured: `pubmed_lookup_citation` for partial references, `pubmed_convert_ids` to crosswalk IDs. Refine queries with `pubmed_lookup_mesh` and `pubmed_spell_check`.",
|
|
44
45
|
landing: {
|
|
45
46
|
requireAuth: false,
|
|
46
47
|
tagline: 'Search PubMed, fetch articles, generate citations, explore MeSH terms, and discover related research.',
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAC;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,8DAA8D,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,gEAAgE,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;AACjC,MAAM,KAAK,GAAG;IACZ,kBAAkB;IAClB,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,cAAc;IACd,kBAAkB;IAClB,cAAc;IACd,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAC;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,8DAA8D,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,+DAA+D,CAAC;AACzG,OAAO,EAAE,yBAAyB,EAAE,MAAM,gEAAgE,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;AACjC,MAAM,KAAK,GAAG;IACZ,kBAAkB;IAClB,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,cAAc;IACd,kBAAkB;IAClB,cAAc;IACd,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,yBAAyB,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;CAC1F,CAAC;AAEF,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,mBAAmB;IAC1B,KAAK;IACL,SAAS,EAAE,CAAC,oBAAoB,CAAC;IACjC,OAAO,EAAE,CAAC,kBAAkB,CAAC;IAC7B,YAAY,EACV,2vBAA2vB;IAC7vB,OAAO,EAAE;QACP,WAAW,EAAE,KAAK;QAClB,OAAO,EACL,uGAAuG;QACzG,QAAQ,EAAE,gDAAgD;QAC1D,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC7E;gBACE,KAAK,EAAE,kBAAkB;gBACzB,IAAI,EAAE,8CAA8C;gBACpD,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,KAAK,EAAE,qBAAqB;gBAC5B,IAAI,EAAE,gDAAgD;gBACtD,QAAQ,EAAE,IAAI;aACf;YACD,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,4BAA4B,EAAE,QAAQ,EAAE,IAAI,EAAE;SAC9E;QACD,UAAU,EAAE;YACV,YAAY,EAAE,mBAAmB;YACjC,gBAAgB,EAAE,iBAAiB;YACnC,eAAe,EAAE,iBAAiB;SACnC;KACF;IACD,KAAK;QACH,eAAe,EAAE,CAAC;QAClB,oBAAoB,EAAE,CAAC;QACvB,oBAAoB,EAAE,CAAC;QACvB,mBAAmB,EAAE,CAAC;IACxB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Text-cutting helper shared by the tool definitions that bound
|
|
3
|
+
* returned text to a character budget.
|
|
4
|
+
* @module src/mcp-server/tools/definitions/_text
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Take at most `limit` UTF-16 code units from `text` without splitting a
|
|
8
|
+
* surrogate pair.
|
|
9
|
+
*
|
|
10
|
+
* `String.prototype.slice` cuts on a code-unit boundary, so a cut landing
|
|
11
|
+
* between the high and low half of an astral character — emoji, mathematical
|
|
12
|
+
* alphanumerics, CJK extensions — leaves a lone surrogate. It survives
|
|
13
|
+
* `JSON.stringify` as `\ud83e` and transports fine, then renders as U+FFFD once
|
|
14
|
+
* a client decodes it, and the string fails `String.prototype.isWellFormed()`.
|
|
15
|
+
*
|
|
16
|
+
* `limit` stays a ceiling: when the boundary would land mid-pair it backs off by
|
|
17
|
+
* one code unit, so the result can come back one unit short of the allowance.
|
|
18
|
+
* Callers that report character counts must measure the returned string rather
|
|
19
|
+
* than assume the allowance was spent exactly. (#93)
|
|
20
|
+
*/
|
|
21
|
+
export declare function sliceCodeUnits(text: string, limit: number): string;
|
|
22
|
+
//# sourceMappingURL=_text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_text.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Text-cutting helper shared by the tool definitions that bound
|
|
3
|
+
* returned text to a character budget.
|
|
4
|
+
* @module src/mcp-server/tools/definitions/_text
|
|
5
|
+
*/
|
|
6
|
+
const HIGH_SURROGATE_FIRST = 0xd800;
|
|
7
|
+
const HIGH_SURROGATE_LAST = 0xdbff;
|
|
8
|
+
/**
|
|
9
|
+
* Take at most `limit` UTF-16 code units from `text` without splitting a
|
|
10
|
+
* surrogate pair.
|
|
11
|
+
*
|
|
12
|
+
* `String.prototype.slice` cuts on a code-unit boundary, so a cut landing
|
|
13
|
+
* between the high and low half of an astral character — emoji, mathematical
|
|
14
|
+
* alphanumerics, CJK extensions — leaves a lone surrogate. It survives
|
|
15
|
+
* `JSON.stringify` as `\ud83e` and transports fine, then renders as U+FFFD once
|
|
16
|
+
* a client decodes it, and the string fails `String.prototype.isWellFormed()`.
|
|
17
|
+
*
|
|
18
|
+
* `limit` stays a ceiling: when the boundary would land mid-pair it backs off by
|
|
19
|
+
* one code unit, so the result can come back one unit short of the allowance.
|
|
20
|
+
* Callers that report character counts must measure the returned string rather
|
|
21
|
+
* than assume the allowance was spent exactly. (#93)
|
|
22
|
+
*/
|
|
23
|
+
export function sliceCodeUnits(text, limit) {
|
|
24
|
+
if (limit <= 0)
|
|
25
|
+
return '';
|
|
26
|
+
if (limit >= text.length)
|
|
27
|
+
return text;
|
|
28
|
+
const last = text.charCodeAt(limit - 1);
|
|
29
|
+
const splitsPair = last >= HIGH_SURROGATE_FIRST && last <= HIGH_SURROGATE_LAST;
|
|
30
|
+
return text.slice(0, splitsPair ? limit - 1 : limit);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=_text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_text.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa;IACxD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1B,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI,IAAI,oBAAoB,IAAI,IAAI,IAAI,mBAAmB,CAAC;IAC/E,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -36,6 +36,12 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
36
36
|
includeReferences: z.ZodDefault<z.ZodBoolean>;
|
|
37
37
|
maxSections: z.ZodOptional<z.ZodNumber>;
|
|
38
38
|
sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
39
|
+
maxCharacters: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
maxCharactersPerSection: z.ZodOptional<z.ZodNumber>;
|
|
41
|
+
overflowMode: z.ZodDefault<z.ZodEnum<{
|
|
42
|
+
outline: "outline";
|
|
43
|
+
truncate: "truncate";
|
|
44
|
+
}>>;
|
|
39
45
|
}, z.core.$strip>, z.ZodObject<{
|
|
40
46
|
articles: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
41
47
|
source: z.ZodLiteral<"pmc">;
|
|
@@ -94,6 +100,7 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
94
100
|
"html-markdown": "html-markdown";
|
|
95
101
|
"pdf-text": "pdf-text";
|
|
96
102
|
}>;
|
|
103
|
+
pmcId: z.ZodOptional<z.ZodString>;
|
|
97
104
|
pmid: z.ZodOptional<z.ZodString>;
|
|
98
105
|
pubmedUrl: z.ZodOptional<z.ZodString>;
|
|
99
106
|
doi: z.ZodString;
|
|
@@ -116,6 +123,7 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
116
123
|
}>;
|
|
117
124
|
reason: z.ZodEnum<{
|
|
118
125
|
"fetch-failed": "fetch-failed";
|
|
126
|
+
"no-body": "no-body";
|
|
119
127
|
"no-doi": "no-doi";
|
|
120
128
|
"no-epmc-fulltext": "no-epmc-fulltext";
|
|
121
129
|
"no-oa": "no-oa";
|
|
@@ -133,6 +141,7 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
133
141
|
outcome: z.ZodEnum<{
|
|
134
142
|
"fetch-failed": "fetch-failed";
|
|
135
143
|
miss: "miss";
|
|
144
|
+
"no-body": "no-body";
|
|
136
145
|
"no-doi": "no-doi";
|
|
137
146
|
"no-fulltext": "no-fulltext";
|
|
138
147
|
"no-oa": "no-oa";
|
|
@@ -143,6 +152,32 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
143
152
|
detail: z.ZodOptional<z.ZodString>;
|
|
144
153
|
}, z.core.$strip>>;
|
|
145
154
|
}, z.core.$strip>>>;
|
|
155
|
+
truncation: z.ZodOptional<z.ZodObject<{
|
|
156
|
+
mode: z.ZodEnum<{
|
|
157
|
+
outline: "outline";
|
|
158
|
+
truncate: "truncate";
|
|
159
|
+
}>;
|
|
160
|
+
maxCharacters: z.ZodOptional<z.ZodNumber>;
|
|
161
|
+
maxCharactersPerSection: z.ZodOptional<z.ZodNumber>;
|
|
162
|
+
originalCharacters: z.ZodNumber;
|
|
163
|
+
returnedCharacters: z.ZodNumber;
|
|
164
|
+
omittedSections: z.ZodNumber;
|
|
165
|
+
articles: z.ZodArray<z.ZodObject<{
|
|
166
|
+
id: z.ZodString;
|
|
167
|
+
source: z.ZodEnum<{
|
|
168
|
+
pmc: "pmc";
|
|
169
|
+
unpaywall: "unpaywall";
|
|
170
|
+
}>;
|
|
171
|
+
originalCharacters: z.ZodNumber;
|
|
172
|
+
returnedCharacters: z.ZodNumber;
|
|
173
|
+
sections: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
174
|
+
title: z.ZodOptional<z.ZodString>;
|
|
175
|
+
originalCharacters: z.ZodNumber;
|
|
176
|
+
returnedCharacters: z.ZodNumber;
|
|
177
|
+
truncated: z.ZodBoolean;
|
|
178
|
+
}, z.core.$strip>>>;
|
|
179
|
+
}, z.core.$strip>>;
|
|
180
|
+
}, z.core.$strip>>;
|
|
146
181
|
}, z.core.$strip>, readonly [{
|
|
147
182
|
readonly reason: 'queue_full';
|
|
148
183
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.RateLimited;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-fulltext.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-fulltext.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-fulltext.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-fulltext.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAmoB/D;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,MAAM,CA+BT;AAID,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2rB5B,CAAC"}
|