@cyanheads/pubmed-mcp-server 2.5.5 → 2.6.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.
Files changed (31) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +11 -8
  3. package/dist/config/server-config.d.ts +2 -0
  4. package/dist/config/server-config.d.ts.map +1 -1
  5. package/dist/config/server-config.js +11 -0
  6. package/dist/config/server-config.js.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts +45 -13
  10. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts.map +1 -1
  11. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js +434 -135
  12. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js.map +1 -1
  13. package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts +13 -1
  14. package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts.map +1 -1
  15. package/dist/mcp-server/tools/definitions/lookup-citation.tool.js +142 -12
  16. package/dist/mcp-server/tools/definitions/lookup-citation.tool.js.map +1 -1
  17. package/dist/services/ncbi/ncbi-service.d.ts.map +1 -1
  18. package/dist/services/ncbi/ncbi-service.js +8 -0
  19. package/dist/services/ncbi/ncbi-service.js.map +1 -1
  20. package/dist/services/ncbi/types.d.ts +5 -0
  21. package/dist/services/ncbi/types.d.ts.map +1 -1
  22. package/dist/services/unpaywall/types.d.ts +55 -0
  23. package/dist/services/unpaywall/types.d.ts.map +1 -0
  24. package/dist/services/unpaywall/types.js +7 -0
  25. package/dist/services/unpaywall/types.js.map +1 -0
  26. package/dist/services/unpaywall/unpaywall-service.d.ts +42 -0
  27. package/dist/services/unpaywall/unpaywall-service.d.ts.map +1 -0
  28. package/dist/services/unpaywall/unpaywall-service.js +165 -0
  29. package/dist/services/unpaywall/unpaywall-service.js.map +1 -0
  30. package/package.json +5 -2
  31. package/server.json +15 -3
package/CLAUDE.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Agent Protocol
2
2
 
3
3
  **Server:** @cyanheads/pubmed-mcp-server
4
- **Version:** 2.5.4
4
+ **Version:** 2.5.6
5
5
  **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
6
6
 
7
7
  > **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  <div align="center">
9
9
 
10
- [![npm](https://img.shields.io/npm/v/@cyanheads/pubmed-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/pubmed-mcp-server) [![Version](https://img.shields.io/badge/Version-2.5.5-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.27.1-green.svg?style=flat-square)](https://modelcontextprotocol.io/)
10
+ [![npm](https://img.shields.io/npm/v/@cyanheads/pubmed-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/pubmed-mcp-server) [![Version](https://img.shields.io/badge/Version-2.6.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.27.1-green.svg?style=flat-square)](https://modelcontextprotocol.io/)
11
11
 
12
12
  [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.2-blueviolet.svg?style=flat-square)](https://bun.sh/)
13
13
 
@@ -29,7 +29,7 @@ Nine tools for working with PubMed and NCBI data:
29
29
  |:---|:---|
30
30
  | `pubmed_search_articles` | Search PubMed with full query syntax, field-specific filters, date ranges, pagination, and optional brief summaries |
31
31
  | `pubmed_fetch_articles` | Fetch full article metadata by PMIDs — abstract, authors, journal, MeSH terms, grants |
32
- | `pubmed_fetch_fulltext` | Fetch full-text articles from PubMed Central body sections, references, and metadata for open-access articles |
32
+ | `pubmed_fetch_fulltext` | Fetch full-text articles from PubMed Central, with optional Unpaywall fallback for non-PMC DOIs (HTML → Markdown or PDF → text) |
33
33
  | `pubmed_format_citations` | Generate formatted citations in APA 7th, MLA 9th, BibTeX, or RIS |
34
34
  | `pubmed_find_related` | Find similar articles, citing articles, or references for a given PMID |
35
35
  | `pubmed_spell_check` | Spell-check biomedical queries using NCBI's ESpell service |
@@ -67,15 +67,15 @@ Fetch full article metadata by PubMed IDs.
67
67
 
68
68
  ### `pubmed_fetch_fulltext`
69
69
 
70
- Fetch full-text articles from PubMed Central (PMC).
70
+ Fetch full-text articles from PubMed Central (PMC), with an optional Unpaywall fallback for articles not in PMC.
71
71
 
72
72
  - Accepts PMC IDs directly or PubMed IDs (auto-resolved to PMCIDs via ELink)
73
- - Returns complete article body text organized by sections and subsections
74
- - Optional reference list from back matter
75
- - Section filtering by title (case-insensitive match, e.g. `["methods", "results"]`)
76
- - Configurable max sections to limit response size
73
+ - PMC path returns complete article body organized by sections and subsections, plus optional references from back matter
74
+ - Unpaywall fallback (enabled by setting `UNPAYWALL_EMAIL`) resolves DOIs to legal open-access copies hosted by publishers or institutional repositories; extracts HTML landing pages to Markdown via Defuddle or PDFs to text via unpdf
75
+ - Discriminated output contract `source: "pmc"` (structured sections) or `source: "unpaywall"` (single body + `contentFormat` metadata: `html-markdown` or `pdf-text`)
76
+ - Structured unavailable reasons (`no-pmc-fallback-disabled`, `no-doi`, `no-oa`, `fetch-failed`, `parse-failed`, `service-error`) so callers can retry or explain to users without parsing text
77
+ - Section filtering by title (case-insensitive match, e.g. `["methods", "results"]`) and configurable max sections apply to PMC output
77
78
  - Up to 10 articles per request
78
- - Only open-access articles available in PMC will return full text
79
79
 
80
80
  ---
81
81
 
@@ -289,6 +289,8 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
289
289
  | `NCBI_MAX_RETRIES` | Retry attempts for failed NCBI requests | 6 |
290
290
  | `NCBI_TIMEOUT_MS` | Per-request HTTP timeout in ms | `30000` |
291
291
  | `NCBI_TOTAL_DEADLINE_MS` | Total deadline across all retry attempts for one NCBI call, in ms | `60000` |
292
+ | `UNPAYWALL_EMAIL` | Contact email for Unpaywall. When set, `pubmed_fetch_fulltext` falls back to Unpaywall open-access copies for non-PMC DOIs | none |
293
+ | `UNPAYWALL_TIMEOUT_MS` | Per-request HTTP timeout for Unpaywall lookups and content fetches, in ms | `20000` |
292
294
  | `OTEL_ENABLED` | Enable OpenTelemetry | `false` |
293
295
 
294
296
  ## Running the server
@@ -321,6 +323,7 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
321
323
  | `src/mcp-server/resources` | Resource definitions. Database info resource. |
322
324
  | `src/mcp-server/prompts` | Prompt definitions. Research plan prompt. |
323
325
  | `src/services/ncbi` | NCBI E-utilities service layer — API client, queue, parser, formatter. |
326
+ | `src/services/unpaywall` | Unpaywall service — DOI → OA location resolution and content fetch (HTML/PDF). |
324
327
  | `src/config` | Server-specific environment variable parsing and validation with Zod. |
325
328
  | `tests/` | Unit and integration tests, mirroring the `src/` structure. |
326
329
 
@@ -13,6 +13,8 @@ declare const ServerConfigSchema: z.ZodObject<{
13
13
  maxRetries: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
14
14
  timeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
15
15
  totalDeadlineMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
16
+ unpaywallEmail: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodEmail>>;
17
+ unpaywallTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
16
18
  }, z.core.$strip>;
17
19
  export type ServerConfig = z.infer<typeof ServerConfigSchema>;
18
20
  export declare function getServerConfig(): ServerConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAU3C,QAAA,MAAM,kBAAkB;;;;;;;;iBAkBtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,wBAAgB,eAAe,IAAI,YAAY,CAsB9C"}
1
+ {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAU3C,QAAA,MAAM,kBAAkB;;;;;;;;;;iBA2BtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,wBAAgB,eAAe,IAAI,YAAY,CAwB9C"}
@@ -30,6 +30,15 @@ const ServerConfigSchema = z.object({
30
30
  .max(600000)
31
31
  .default(60000)
32
32
  .describe('Total deadline across all retry attempts for one NCBI call, in ms'),
33
+ unpaywallEmail: z
34
+ .preprocess(emptyAsUndefined, z.email().optional())
35
+ .describe('Email for Unpaywall API (enables non-PMC full-text fallback when set)'),
36
+ unpaywallTimeoutMs: z.coerce
37
+ .number()
38
+ .min(1000)
39
+ .max(120000)
40
+ .default(20000)
41
+ .describe('Per-request HTTP timeout for Unpaywall lookups and content fetches, in ms'),
33
42
  });
34
43
  let _config;
35
44
  export function getServerConfig() {
@@ -42,6 +51,8 @@ export function getServerConfig() {
42
51
  maxRetries: 'NCBI_MAX_RETRIES',
43
52
  timeoutMs: 'NCBI_TIMEOUT_MS',
44
53
  totalDeadlineMs: 'NCBI_TOTAL_DEADLINE_MS',
54
+ unpaywallEmail: 'UNPAYWALL_EMAIL',
55
+ unpaywallTimeoutMs: 'UNPAYWALL_TIMEOUT_MS',
45
56
  });
46
57
  /**
47
58
  * An API key raises NCBI's rate ceiling from ~3 req/s to ~10 req/s. If the
@@ -1 +1 @@
1
- {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;IACtF,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;IACxF,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAChG,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAChG,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACtF,SAAS,EAAE,CAAC,CAAC,MAAM;SAChB,MAAM,EAAE;SACR,GAAG,CAAC,IAAI,CAAC;SACT,GAAG,CAAC,MAAM,CAAC;SACX,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,gCAAgC,CAAC;IAC7C,eAAe,EAAE,CAAC,CAAC,MAAM;SACtB,MAAM,EAAE;SACR,GAAG,CAAC,IAAI,CAAC;SACT,GAAG,CAAC,MAAM,CAAC;SACX,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,mEAAmE,CAAC;CACjF,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,cAAc,CAAC,kBAAkB,EAAE;YAChD,MAAM,EAAE,cAAc;YACtB,cAAc,EAAE,sBAAsB;YACtC,UAAU,EAAE,kBAAkB;YAC9B,cAAc,EAAE,uBAAuB;YACvC,UAAU,EAAE,kBAAkB;YAC9B,SAAS,EAAE,iBAAiB;YAC5B,eAAe,EAAE,wBAAwB;SAC1C,CAAC,CAAC;QACH;;;;WAIG;QACH,OAAO;YACL,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,SAAS;gBAC9D,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE;gBACpC,CAAC,CAAC,MAAM,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ import { lookupMeshTool } from './mcp-server/tools/definitions/lookup-mesh.tool.
16
16
  import { searchArticlesTool } from './mcp-server/tools/definitions/search-articles.tool.js';
17
17
  import { spellCheckTool } from './mcp-server/tools/definitions/spell-check.tool.js';
18
18
  import { initNcbiService } from './services/ncbi/ncbi-service.js';
19
+ import { initUnpaywallService } from './services/unpaywall/unpaywall-service.js';
19
20
  await createApp({
20
21
  tools: [
21
22
  searchArticlesTool,
@@ -50,10 +51,12 @@ await createApp({
50
51
  envExample: {
51
52
  NCBI_API_KEY: 'your-ncbi-api-key',
52
53
  NCBI_ADMIN_EMAIL: 'you@example.com',
54
+ UNPAYWALL_EMAIL: 'you@example.com',
53
55
  },
54
56
  },
55
57
  setup() {
56
58
  initNcbiService();
59
+ initUnpaywallService();
57
60
  },
58
61
  });
59
62
  //# sourceMappingURL=index.js.map
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,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,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,kBAAkB;QAClB,iBAAiB;QACjB,iBAAiB;QACjB,mBAAmB;QACnB,eAAe;QACf,cAAc;QACd,cAAc;QACd,kBAAkB;QAClB,cAAc;KACf;IACD,SAAS,EAAE,CAAC,oBAAoB,CAAC;IACjC,OAAO,EAAE,CAAC,kBAAkB,CAAC;IAC7B,OAAO,EAAE;QACP,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;SACpC;KACF;IACD,KAAK;QACH,eAAe,EAAE,CAAC;IACpB,CAAC;CACF,CAAC,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,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,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,kBAAkB;QAClB,iBAAiB;QACjB,iBAAiB;QACjB,mBAAmB;QACnB,eAAe;QACf,cAAc;QACd,cAAc;QACd,kBAAkB;QAClB,cAAc;KACf;IACD,SAAS,EAAE,CAAC,oBAAoB,CAAC;IACjC,OAAO,EAAE,CAAC,kBAAkB,CAAC;IAC7B,OAAO,EAAE;QACP,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;IACzB,CAAC;CACF,CAAC,CAAC"}
@@ -1,6 +1,9 @@
1
1
  /**
2
- * @fileoverview PMC full-text fetch tool. Retrieves full-text articles from PubMed
3
- * Central via NCBI EFetch with db=pmc. Supports PMCID input or PMID-to-PMCID resolution.
2
+ * @fileoverview Full-text fetch tool. Primary source is PubMed Central (NCBI
3
+ * EFetch, `db=pmc`). When a PMID has no PMC copy but does have a DOI,
4
+ * transparently falls back to Unpaywall to retrieve a legally-deposited
5
+ * open-access copy (HTML or PDF). Output uses a discriminated union on
6
+ * `source` so callers can reason about structural reliability per article.
4
7
  * @module src/mcp-server/tools/definitions/fetch-fulltext.tool
5
8
  */
6
9
  import { z } from '@cyanheads/mcp-ts-core';
@@ -11,11 +14,13 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
11
14
  maxSections: z.ZodOptional<z.ZodNumber>;
12
15
  sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
13
16
  }, z.core.$strip>, z.ZodObject<{
14
- articles: z.ZodArray<z.ZodObject<{
17
+ articles: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
18
+ source: z.ZodLiteral<"pmc">;
15
19
  pmcId: z.ZodString;
16
20
  pmcUrl: z.ZodString;
17
21
  pmid: z.ZodOptional<z.ZodString>;
18
22
  pubmedUrl: z.ZodOptional<z.ZodString>;
23
+ doi: z.ZodOptional<z.ZodString>;
19
24
  title: z.ZodOptional<z.ZodString>;
20
25
  abstract: z.ZodOptional<z.ZodString>;
21
26
  authors: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -23,7 +28,7 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
23
28
  givenNames: z.ZodOptional<z.ZodString>;
24
29
  lastName: z.ZodOptional<z.ZodString>;
25
30
  }, z.core.$strip>>>;
26
- doi: z.ZodOptional<z.ZodString>;
31
+ affiliations: z.ZodOptional<z.ZodArray<z.ZodString>>;
27
32
  journal: z.ZodOptional<z.ZodObject<{
28
33
  title: z.ZodOptional<z.ZodString>;
29
34
  issn: z.ZodOptional<z.ZodString>;
@@ -32,6 +37,12 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
32
37
  pages: z.ZodOptional<z.ZodString>;
33
38
  }, z.core.$strip>>;
34
39
  keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
40
+ articleType: z.ZodOptional<z.ZodString>;
41
+ publicationDate: z.ZodOptional<z.ZodObject<{
42
+ year: z.ZodOptional<z.ZodString>;
43
+ month: z.ZodOptional<z.ZodString>;
44
+ day: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>>;
35
46
  sections: z.ZodArray<z.ZodObject<{
36
47
  title: z.ZodOptional<z.ZodString>;
37
48
  label: z.ZodOptional<z.ZodString>;
@@ -47,16 +58,37 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
47
58
  id: z.ZodOptional<z.ZodString>;
48
59
  label: z.ZodOptional<z.ZodString>;
49
60
  }, z.core.$strip>>>;
50
- articleType: z.ZodOptional<z.ZodString>;
51
- affiliations: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
- publicationDate: z.ZodOptional<z.ZodObject<{
53
- year: z.ZodOptional<z.ZodString>;
54
- month: z.ZodOptional<z.ZodString>;
55
- day: z.ZodOptional<z.ZodString>;
56
- }, z.core.$strip>>;
57
- }, z.core.$strip>>;
61
+ }, z.core.$strip>, z.ZodObject<{
62
+ source: z.ZodLiteral<"unpaywall">;
63
+ contentFormat: z.ZodEnum<{
64
+ "html-markdown": "html-markdown";
65
+ "pdf-text": "pdf-text";
66
+ }>;
67
+ pmid: z.ZodString;
68
+ pubmedUrl: z.ZodString;
69
+ doi: z.ZodString;
70
+ sourceUrl: z.ZodString;
71
+ title: z.ZodOptional<z.ZodString>;
72
+ content: z.ZodString;
73
+ wordCount: z.ZodOptional<z.ZodNumber>;
74
+ totalPages: z.ZodOptional<z.ZodNumber>;
75
+ license: z.ZodOptional<z.ZodString>;
76
+ hostType: z.ZodOptional<z.ZodString>;
77
+ version: z.ZodOptional<z.ZodString>;
78
+ }, z.core.$strip>], "source">>;
58
79
  totalReturned: z.ZodNumber;
59
- unavailablePmids: z.ZodOptional<z.ZodArray<z.ZodString>>;
80
+ unavailable: z.ZodOptional<z.ZodArray<z.ZodObject<{
81
+ pmid: z.ZodString;
82
+ reason: z.ZodEnum<{
83
+ "no-oa": "no-oa";
84
+ "no-pmc-fallback-disabled": "no-pmc-fallback-disabled";
85
+ "no-doi": "no-doi";
86
+ "fetch-failed": "fetch-failed";
87
+ "parse-failed": "parse-failed";
88
+ "service-error": "service-error";
89
+ }>;
90
+ detail: z.ZodOptional<z.ZodString>;
91
+ }, z.core.$strip>>>;
60
92
  unavailablePmcIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
61
93
  }, z.core.$strip>>;
62
94
  //# sourceMappingURL=fetch-fulltext.tool.d.ts.map
@@ -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;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AA6GjD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqL5B,CAAC"}
1
+ {"version":3,"file":"fetch-fulltext.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-fulltext.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAgL/D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA+N5B,CAAC"}