@cyanheads/pubmed-mcp-server 2.10.19 → 2.10.21
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 +8 -5
- package/CLAUDE.md +8 -5
- package/Dockerfile +12 -3
- package/README.md +12 -11
- package/changelog/2.10.x/2.10.20.md +63 -0
- package/changelog/2.10.x/2.10.21.md +42 -0
- package/dist/mcp-server/tools/definitions/_text.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/_text.js +10 -5
- package/dist/mcp-server/tools/definitions/_text.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts +8 -0
- package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-articles.tool.js +64 -14
- package/dist/mcp-server/tools/definitions/fetch-articles.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts +44 -9
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js +815 -563
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/find-related.tool.d.ts +5 -5
- package/dist/mcp-server/tools/definitions/find-related.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/find-related.tool.js +12 -8
- package/dist/mcp-server/tools/definitions/find-related.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/format-citations.tool.d.ts +12 -0
- package/dist/mcp-server/tools/definitions/format-citations.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/format-citations.tool.js +53 -7
- package/dist/mcp-server/tools/definitions/format-citations.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts +11 -7
- package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-citation.tool.js +72 -34
- package/dist/mcp-server/tools/definitions/lookup-citation.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.d.ts +2 -1
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.js +11 -3
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.d.ts +18 -0
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js +96 -13
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts +4 -3
- 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 +7 -5
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts +6 -4
- package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-articles.tool.js +33 -11
- package/dist/mcp-server/tools/definitions/search-articles.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/spell-check.tool.d.ts +2 -1
- package/dist/mcp-server/tools/definitions/spell-check.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/spell-check.tool.js +5 -1
- package/dist/mcp-server/tools/definitions/spell-check.tool.js.map +1 -1
- package/dist/services/error-contracts.d.ts +1 -1
- package/dist/services/error-contracts.d.ts.map +1 -1
- package/dist/services/error-contracts.js +1 -1
- package/dist/services/error-contracts.js.map +1 -1
- package/dist/services/europe-pmc/api-client.d.ts.map +1 -1
- package/dist/services/europe-pmc/api-client.js +4 -3
- package/dist/services/europe-pmc/api-client.js.map +1 -1
- package/dist/services/fetch-redaction.d.ts +23 -0
- package/dist/services/fetch-redaction.d.ts.map +1 -0
- package/dist/services/fetch-redaction.js +62 -0
- package/dist/services/fetch-redaction.js.map +1 -0
- package/dist/services/ncbi/api-client.d.ts +3 -0
- package/dist/services/ncbi/api-client.d.ts.map +1 -1
- package/dist/services/ncbi/api-client.js +21 -8
- package/dist/services/ncbi/api-client.js.map +1 -1
- package/dist/services/ncbi/formatting/citation-formatter.d.ts +42 -2
- package/dist/services/ncbi/formatting/citation-formatter.d.ts.map +1 -1
- package/dist/services/ncbi/formatting/citation-formatter.js +370 -91
- package/dist/services/ncbi/formatting/citation-formatter.js.map +1 -1
- package/dist/services/ncbi/ncbi-service.d.ts +16 -1
- package/dist/services/ncbi/ncbi-service.d.ts.map +1 -1
- package/dist/services/ncbi/ncbi-service.js +117 -71
- package/dist/services/ncbi/ncbi-service.js.map +1 -1
- package/dist/services/ncbi/parsing/article-parser.d.ts.map +1 -1
- package/dist/services/ncbi/parsing/article-parser.js +116 -61
- package/dist/services/ncbi/parsing/article-parser.js.map +1 -1
- package/dist/services/ncbi/parsing/esummary-parser.d.ts +9 -0
- package/dist/services/ncbi/parsing/esummary-parser.d.ts.map +1 -1
- package/dist/services/ncbi/parsing/esummary-parser.js +26 -2
- package/dist/services/ncbi/parsing/esummary-parser.js.map +1 -1
- package/dist/services/ncbi/parsing/pmc-article-parser.d.ts +8 -7
- package/dist/services/ncbi/parsing/pmc-article-parser.d.ts.map +1 -1
- package/dist/services/ncbi/parsing/pmc-article-parser.js +633 -185
- package/dist/services/ncbi/parsing/pmc-article-parser.js.map +1 -1
- package/dist/services/ncbi/parsing/pmc-xml-helpers.d.ts +102 -5
- package/dist/services/ncbi/parsing/pmc-xml-helpers.d.ts.map +1 -1
- package/dist/services/ncbi/parsing/pmc-xml-helpers.js +389 -28
- package/dist/services/ncbi/parsing/pmc-xml-helpers.js.map +1 -1
- package/dist/services/ncbi/parsing/text-helpers.d.ts +8 -6
- package/dist/services/ncbi/parsing/text-helpers.d.ts.map +1 -1
- package/dist/services/ncbi/parsing/text-helpers.js +95 -19
- package/dist/services/ncbi/parsing/text-helpers.js.map +1 -1
- package/dist/services/ncbi/response-handler.d.ts +20 -12
- package/dist/services/ncbi/response-handler.d.ts.map +1 -1
- package/dist/services/ncbi/response-handler.js +115 -19
- package/dist/services/ncbi/response-handler.js.map +1 -1
- package/dist/services/ncbi/types.d.ts +44 -4
- package/dist/services/ncbi/types.d.ts.map +1 -1
- package/dist/services/openalex/api-client.d.ts.map +1 -1
- package/dist/services/openalex/api-client.js +4 -3
- package/dist/services/openalex/api-client.js.map +1 -1
- package/dist/services/openalex/openalex-service.d.ts +10 -6
- package/dist/services/openalex/openalex-service.d.ts.map +1 -1
- package/dist/services/openalex/openalex-service.js +13 -9
- package/dist/services/openalex/openalex-service.js.map +1 -1
- package/dist/services/unpaywall/unpaywall-service.d.ts +3 -0
- package/dist/services/unpaywall/unpaywall-service.d.ts.map +1 -1
- package/dist/services/unpaywall/unpaywall-service.js +18 -8
- package/dist/services/unpaywall/unpaywall-service.js.map +1 -1
- package/package.json +14 -12
- package/server.json +10 -24
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview PubMed spell-check tool. Uses NCBI's ESpell service to correct
|
|
3
3
|
* every misspelled token of a PubMed search query in one call — the recovery
|
|
4
|
-
* step after a zero-hit or thin `pubmed_search_articles` result.
|
|
4
|
+
* step after a zero-hit or thin `pubmed_search_articles` result. `term` is
|
|
5
|
+
* accepted as an alias for `query`.
|
|
5
6
|
* @module src/mcp-server/tools/definitions/spell-check.tool
|
|
6
7
|
*/
|
|
7
8
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spell-check.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/spell-check.tool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"spell-check.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/spell-check.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAMjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkEzB,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview PubMed spell-check tool. Uses NCBI's ESpell service to correct
|
|
3
3
|
* every misspelled token of a PubMed search query in one call — the recovery
|
|
4
|
-
* step after a zero-hit or thin `pubmed_search_articles` result.
|
|
4
|
+
* step after a zero-hit or thin `pubmed_search_articles` result. `term` is
|
|
5
|
+
* accepted as an alias for `query`.
|
|
5
6
|
* @module src/mcp-server/tools/definitions/spell-check.tool
|
|
6
7
|
*/
|
|
7
8
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
@@ -15,6 +16,9 @@ export const spellCheckTool = tool('pubmed_spell_check', {
|
|
|
15
16
|
_meta: conceptMeta([SCHEMA_SEARCH_ACTION]),
|
|
16
17
|
sourceUrl: 'https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/spell-check.tool.ts',
|
|
17
18
|
errors: [...NCBI_SERVICE_ERRORS, ...QUERY_INPUT_ERRORS],
|
|
19
|
+
// Never advertised; rewritten to the canonical key before the schema parses.
|
|
20
|
+
// ESpell's own name for the query. (#190)
|
|
21
|
+
inputAliases: { term: 'query' },
|
|
18
22
|
input: z.object({
|
|
19
23
|
query: z
|
|
20
24
|
.string()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spell-check.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/spell-check.tool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"spell-check.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/spell-check.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE;IACvD,WAAW,EACT,8bAA8b;IAChc,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IACxD,KAAK,EAAE,WAAW,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC1C,SAAS,EACP,+GAA+G;IAEjH,MAAM,EAAE,CAAC,GAAG,mBAAmB,EAAE,GAAG,kBAAkB,CAAU;IAEhE,6EAA6E;IAC7E,0CAA0C;IAC1C,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;IAE/B,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACP,gLAAgL,CACjL;KACJ,CAAC;IAEF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC/C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;QACrF,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;KAC3E,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1E,4EAA4E;QAC5E,4EAA4E;QAC5E,wEAAwE;QACxE,yEAAyE;QACzE,0CAA0C;QAC1C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,yDAAyD,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC,MAAM,CAC1C,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,EACnC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CACvB,CAAC;QACF,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QACjB,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO;gBACL;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,oBAAoB,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,QAAQ,IAAI;iBAC/E;aACF,CAAC;QACJ,CAAC;QACD,OAAO;YACL;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,0BAA0B,MAAM,CAAC,QAAQ,+BAA+B;aAC/E;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -122,7 +122,7 @@ export declare const OPENALEX_SERVICE_ERRORS: readonly [{
|
|
|
122
122
|
}, {
|
|
123
123
|
readonly reason: 'openalex_invalid_response';
|
|
124
124
|
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
125
|
-
readonly when: 'OpenAlex returned a body that could not be parsed
|
|
125
|
+
readonly when: 'The last of the retry attempts against OpenAlex returned a body that could not be parsed as JSON.';
|
|
126
126
|
readonly recovery: 'Retry the request; OpenAlex returned a malformed response that could not be parsed.';
|
|
127
127
|
readonly retryable: true;
|
|
128
128
|
readonly thrownBy: 'service';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-contracts.d.ts","sourceRoot":"","sources":["../../src/services/error-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;aAE5B,MAAM,EAAE,YAAY;aACpB,IAAI;aACJ,IAAI,EAAE,gLAAgL;aACtL,QAAQ,EACN,iIAAiI;aACnI,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,kBAAkB;aAC1B,IAAI;aACJ,IAAI,EAAE,4IAA4I;aAClJ,QAAQ,EAAE,yEAAyE;aACnF,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,mBAAmB;aAC3B,IAAI;aACJ,IAAI,EAAE,gOAAgO;aACtO,QAAQ,EACN,0ZAA0Z;aAC5Z,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,wBAAwB;aAChC,IAAI;aACJ,IAAI,EAAE,mIAAmI;aACzI,QAAQ,EACN,8GAA8G;aAChH,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,uBAAuB;aAC/B,IAAI;aACJ,IAAI,EAAE,mEAAmE;aACzE,QAAQ,EAAE,iFAAiF;aAC3F,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,yBAAyB;aACjC,IAAI;aACJ,IAAI,EAAE,uEAAuE;aAC7E,QAAQ,EACN,gGAAgG;aAClG,SAAS;aACT,QAAQ,EAAE,SAAS;EAEb,CAAC;AAEX;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB;aAE3B,MAAM,EAAE,aAAa;aACrB,IAAI;aACJ,IAAI,EAAE,qYAAqY;aAC3Y,QAAQ,EAAE,6EAA6E;aACvF,SAAS;EAEH,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;aAE7B,MAAM,EAAE,cAAc;aACtB,IAAI;aACJ,IAAI,EAAE,0LAA0L;aAChM,QAAQ,EACN,uHAAuH;aACzH,SAAS;EAEH,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;aAEhC,MAAM,EAAE,sBAAsB;aAC9B,IAAI;aACJ,IAAI,EAAE,oDAAoD;aAC1D,QAAQ,EACN,4FAA4F;aAC9F,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,2BAA2B;aACnC,IAAI;aACJ,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"error-contracts.d.ts","sourceRoot":"","sources":["../../src/services/error-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;aAE5B,MAAM,EAAE,YAAY;aACpB,IAAI;aACJ,IAAI,EAAE,gLAAgL;aACtL,QAAQ,EACN,iIAAiI;aACnI,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,kBAAkB;aAC1B,IAAI;aACJ,IAAI,EAAE,4IAA4I;aAClJ,QAAQ,EAAE,yEAAyE;aACnF,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,mBAAmB;aAC3B,IAAI;aACJ,IAAI,EAAE,gOAAgO;aACtO,QAAQ,EACN,0ZAA0Z;aAC5Z,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,wBAAwB;aAChC,IAAI;aACJ,IAAI,EAAE,mIAAmI;aACzI,QAAQ,EACN,8GAA8G;aAChH,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,uBAAuB;aAC/B,IAAI;aACJ,IAAI,EAAE,mEAAmE;aACzE,QAAQ,EAAE,iFAAiF;aAC3F,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,yBAAyB;aACjC,IAAI;aACJ,IAAI,EAAE,uEAAuE;aAC7E,QAAQ,EACN,gGAAgG;aAClG,SAAS;aACT,QAAQ,EAAE,SAAS;EAEb,CAAC;AAEX;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB;aAE3B,MAAM,EAAE,aAAa;aACrB,IAAI;aACJ,IAAI,EAAE,qYAAqY;aAC3Y,QAAQ,EAAE,6EAA6E;aACvF,SAAS;EAEH,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;aAE7B,MAAM,EAAE,cAAc;aACtB,IAAI;aACJ,IAAI,EAAE,0LAA0L;aAChM,QAAQ,EACN,uHAAuH;aACzH,SAAS;EAEH,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;aAEhC,MAAM,EAAE,sBAAsB;aAC9B,IAAI;aACJ,IAAI,EAAE,oDAAoD;aAC1D,QAAQ,EACN,4FAA4F;aAC9F,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,2BAA2B;aACnC,IAAI;aACJ,IAAI,EAAE,mGAAmG;aACzG,QAAQ,EAAE,qFAAqF;aAC/F,SAAS;aACT,QAAQ,EAAE,SAAS;EAEb,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;aAEjC,MAAM,EAAE,uBAAuB;aAC/B,IAAI;aACJ,IAAI,EAAE,qKAAqK;aAC3K,QAAQ,EACN,iGAAiG;aACnG,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,4BAA4B;aACpC,IAAI;aACJ,IAAI,EAAE,4EAA4E;aAClF,QAAQ,EACN,uFAAuF;aACzF,SAAS;aACT,QAAQ,EAAE,SAAS;;aAGnB,MAAM,EAAE,yBAAyB;aACjC,IAAI;aACJ,IAAI,EAAE,6UAA6U;aACnV,QAAQ,EACN,iNAAiN;aACnN,SAAS;aACT,QAAQ,EAAE,SAAS;EAEb,CAAC"}
|
|
@@ -135,7 +135,7 @@ export const OPENALEX_SERVICE_ERRORS = [
|
|
|
135
135
|
{
|
|
136
136
|
reason: 'openalex_invalid_response',
|
|
137
137
|
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
138
|
-
when: 'OpenAlex returned a body that could not be parsed
|
|
138
|
+
when: 'The last of the retry attempts against OpenAlex returned a body that could not be parsed as JSON.',
|
|
139
139
|
recovery: 'Retry the request; OpenAlex returned a malformed response that could not be parsed.',
|
|
140
140
|
retryable: true,
|
|
141
141
|
thrownBy: 'service',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-contracts.js","sourceRoot":"","sources":["../../src/services/error-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC;QACE,MAAM,EAAE,YAAY;QACpB,IAAI,EAAE,gBAAgB,CAAC,WAAW;QAClC,IAAI,EAAE,gLAAgL;QACtL,QAAQ,EACN,iIAAiI;QACnI,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,IAAI,EAAE,gBAAgB,CAAC,kBAAkB;QACzC,IAAI,EAAE,4IAA4I;QAClJ,QAAQ,EAAE,yEAAyE;QACnF,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,IAAI,EAAE,gBAAgB,CAAC,WAAW;QAClC,IAAI,EAAE,gOAAgO;QACtO,QAAQ,EACN,0ZAA0Z;QAC5Z,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,MAAM,EAAE,wBAAwB;QAChC,IAAI,EAAE,gBAAgB,CAAC,OAAO;QAC9B,IAAI,EAAE,mIAAmI;QACzI,QAAQ,EACN,8GAA8G;QAChH,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,MAAM,EAAE,uBAAuB;QAC/B,IAAI,EAAE,gBAAgB,CAAC,kBAAkB;QACzC,IAAI,EAAE,mEAAmE;QACzE,QAAQ,EAAE,iFAAiF;QAC3F,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,MAAM,EAAE,yBAAyB;QACjC,IAAI,EAAE,gBAAgB,CAAC,QAAQ;QAC/B,IAAI,EAAE,uEAAuE;QAC7E,QAAQ,EACN,gGAAgG;QAClG,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,SAAS;KACpB;CACO,CAAC;AAEX;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC;QACE,MAAM,EAAE,aAAa;QACrB,IAAI,EAAE,gBAAgB,CAAC,eAAe;QACtC,IAAI,EAAE,qYAAqY;QAC3Y,QAAQ,EAAE,6EAA6E;QACvF,SAAS,EAAE,KAAK;KACjB;CACO,CAAC;AAEX;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC;QACE,MAAM,EAAE,cAAc;QACtB,IAAI,EAAE,gBAAgB,CAAC,eAAe;QACtC,IAAI,EAAE,0LAA0L;QAChM,QAAQ,EACN,uHAAuH;QACzH,SAAS,EAAE,KAAK;KACjB;CACO,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC;QACE,MAAM,EAAE,sBAAsB;QAC9B,IAAI,EAAE,gBAAgB,CAAC,kBAAkB;QACzC,IAAI,EAAE,oDAAoD;QAC1D,QAAQ,EACN,4FAA4F;QAC9F,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,MAAM,EAAE,2BAA2B;QACnC,IAAI,EAAE,gBAAgB,CAAC,kBAAkB;QACzC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"error-contracts.js","sourceRoot":"","sources":["../../src/services/error-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/services/europe-pmc/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/services/europe-pmc/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAI5E,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GACpC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,wBAAwB,EAAI;IAEjE;;;;;;;;;;;;;;OAcG;IACG,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2C3D;IAED;;;;;;;;;OASG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,4BAA4B,CAAC,CA4C7F;IAED;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7F;IAED;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9F;IAED,iFAAiF;YACnE,cAAc;IA8B5B,OAAO,CAAC,cAAc;CAavB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,SAAS,CAAC,GAAG,MAAM,CAOjG"}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { JsonRpcErrorCode, McpError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
12
12
|
import { fetchWithTimeout, logger, requestContextService } from '@cyanheads/mcp-ts-core/utils';
|
|
13
|
+
import { readBody } from '../fetch-redaction.js';
|
|
13
14
|
import { EUROPEPMC_API_BASE } from './types.js';
|
|
14
15
|
const USER_AGENT = 'pubmed-mcp-server (+https://github.com/cyanheads/pubmed-mcp-server)';
|
|
15
16
|
/**
|
|
@@ -73,7 +74,7 @@ export class EuropePmcApiClient {
|
|
|
73
74
|
const msg = error instanceof Error ? error.message : String(error);
|
|
74
75
|
throw serviceUnavailable(`Europe PMC search request failed: ${msg}`, { reason: 'europepmc_unreachable' }, { cause: error });
|
|
75
76
|
}
|
|
76
|
-
return response.text();
|
|
77
|
+
return readBody(response.text());
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
79
80
|
* Fetch the JATS full-text XML for an EPMC record by its internal id.
|
|
@@ -112,7 +113,7 @@ export class EuropePmcApiClient {
|
|
|
112
113
|
const msg = error instanceof Error ? error.message : String(error);
|
|
113
114
|
throw serviceUnavailable(`Europe PMC fullTextXML request failed: ${msg}`, { reason: 'europepmc_unreachable', epmcId }, { cause: error });
|
|
114
115
|
}
|
|
115
|
-
const xml = await response.text();
|
|
116
|
+
const xml = await readBody(response.text());
|
|
116
117
|
if (!xml.trim()) {
|
|
117
118
|
logger.debug('Europe PMC returned an empty fullTextXML body.', requestContextService.createRequestContext({
|
|
118
119
|
operation: 'EuropePmcFullTextXmlEmpty',
|
|
@@ -159,7 +160,7 @@ export class EuropePmcApiClient {
|
|
|
159
160
|
const msg = error instanceof Error ? error.message : String(error);
|
|
160
161
|
throw serviceUnavailable(`Europe PMC links request failed: ${msg}`, { reason: 'europepmc_unreachable' }, { cause: error });
|
|
161
162
|
}
|
|
162
|
-
return response.text();
|
|
163
|
+
return readBody(response.text());
|
|
163
164
|
}
|
|
164
165
|
buildSearchUrl(params) {
|
|
165
166
|
const finalParams = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/services/europe-pmc/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAE/F,OAAO,EAAE,kBAAkB,EAA8B,MAAM,YAAY,CAAC;AAE5E,MAAM,UAAU,GAAG,qEAAqE,CAAC;AAezF;;;;;;;;GAQG;AACH,MAAM,OAAO,kBAAkB;IACA,MAAM;IAAnC,YAA6B,MAAgC;sBAAhC,MAAM;IAA6B,CAAC;IAEjE;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,MAAM,CAAC,MAA6B;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,qBAAqB,CAAC,oBAAoB,CAAC;YACrD,SAAS,EAAE,iBAAiB;YAC5B,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;SAC3C,CAAC,CAAC;QAEH,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE;gBACjE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,UAAU,EAAE;gBACjE,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;aAChD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;gBAClC,MAAM,QAAQ,GACZ,MAAM,KAAK,GAAG;oBACd,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC;gBACnF,IAAI,CAAC,QAAQ;oBAAE,MAAM,KAAK,CAAC;gBAC3B,MAAM,IAAI,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC/E,MAAM,IAAI,QAAQ,CAChB,IAAI,EACJ,qCAAqC,KAAK,CAAC,OAAO,EAAE,EACpD;oBACE,GAAG,CAAC,IAAI,KAAK,gBAAgB,CAAC,kBAAkB,IAAI;wBAClD,MAAM,EAAE,uBAAuB;qBAChC,CAAC;oBACF,MAAM;oBACN,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;iBACnF,EACD,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,MAAM,kBAAkB,CACtB,qCAAqC,GAAG,EAAE,EAC1C,EAAE,MAAM,EAAE,uBAAuB,EAAE,EACnC,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/services/europe-pmc/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Keeps request URLs out of the text of fetch rejections. Runtimes can
|
|
3
|
+
* quote the whole request URL in a rejection message (Bun 1.4 does, for some malformed
|
|
4
|
+
* responses, in both the header and the body phase), and these services' query strings
|
|
5
|
+
* carry an API key, the operator's contact email, and the caller's query. The message
|
|
6
|
+
* becomes caller-facing error text, and the rejection rides `cause` into the log
|
|
7
|
+
* record's cause chain, so every URL in it is cut to its origin first.
|
|
8
|
+
* @module src/services/fetch-redaction
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* A fetch rejection with every URL its text quotes reduced to the URL's origin. An
|
|
12
|
+
* `Error` is rewritten in place, keeping its identity and transport `code`; one whose
|
|
13
|
+
* `message` refuses the write is replaced by a stand-in carrying its `name` and `code`.
|
|
14
|
+
* A non-`Error` rejection comes back as its redacted text.
|
|
15
|
+
*/
|
|
16
|
+
export declare function redactRejection(error: unknown): unknown;
|
|
17
|
+
/**
|
|
18
|
+
* Awaits a response-body read (`response.text()`, `.json()`, `.arrayBuffer()`),
|
|
19
|
+
* rethrowing its rejection with {@link redactRejection} applied. A failure while the
|
|
20
|
+
* body streams is otherwise unchanged: same error, same classification.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readBody<T>(read: Promise<T>): Promise<T>;
|
|
23
|
+
//# sourceMappingURL=fetch-redaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-redaction.d.ts","sourceRoot":"","sources":["../../src/services/fetch-redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiBH;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAcvD;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAM9D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Keeps request URLs out of the text of fetch rejections. Runtimes can
|
|
3
|
+
* quote the whole request URL in a rejection message (Bun 1.4 does, for some malformed
|
|
4
|
+
* responses, in both the header and the body phase), and these services' query strings
|
|
5
|
+
* carry an API key, the operator's contact email, and the caller's query. The message
|
|
6
|
+
* becomes caller-facing error text, and the rejection rides `cause` into the log
|
|
7
|
+
* record's cause chain, so every URL in it is cut to its origin first.
|
|
8
|
+
* @module src/services/fetch-redaction
|
|
9
|
+
*/
|
|
10
|
+
/** An absolute `http:`/`https:` URL inside free text, up to the first quote, bracket, or space. */
|
|
11
|
+
const EMBEDDED_URL = /https?:\/\/[^\s"'`<>]+/gi;
|
|
12
|
+
/**
|
|
13
|
+
* Names a URL by its origin, path and query elided behind markers
|
|
14
|
+
* (`https://host/…?…`); an unparseable one becomes a fixed placeholder.
|
|
15
|
+
*/
|
|
16
|
+
function redactUrl(url) {
|
|
17
|
+
const parsed = URL.parse(url);
|
|
18
|
+
if (!parsed)
|
|
19
|
+
return '[unparseable URL]';
|
|
20
|
+
const path = parsed.pathname === '/' ? '' : '/…';
|
|
21
|
+
const query = parsed.search ? '?…' : '';
|
|
22
|
+
return `${parsed.origin}${path}${query}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A fetch rejection with every URL its text quotes reduced to the URL's origin. An
|
|
26
|
+
* `Error` is rewritten in place, keeping its identity and transport `code`; one whose
|
|
27
|
+
* `message` refuses the write is replaced by a stand-in carrying its `name` and `code`.
|
|
28
|
+
* A non-`Error` rejection comes back as its redacted text.
|
|
29
|
+
*/
|
|
30
|
+
export function redactRejection(error) {
|
|
31
|
+
if (!(error instanceof Error))
|
|
32
|
+
return String(error).replace(EMBEDDED_URL, redactUrl);
|
|
33
|
+
const message = error.message.replace(EMBEDDED_URL, redactUrl);
|
|
34
|
+
if (message === error.message)
|
|
35
|
+
return error;
|
|
36
|
+
try {
|
|
37
|
+
error.message = message;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// A frozen or read-only `message`; the stand-in below takes over.
|
|
41
|
+
}
|
|
42
|
+
if (error.message === message)
|
|
43
|
+
return error;
|
|
44
|
+
const standIn = new Error(message);
|
|
45
|
+
standIn.name = error.name;
|
|
46
|
+
const { code } = error;
|
|
47
|
+
return typeof code === 'string' ? Object.assign(standIn, { code }) : standIn;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Awaits a response-body read (`response.text()`, `.json()`, `.arrayBuffer()`),
|
|
51
|
+
* rethrowing its rejection with {@link redactRejection} applied. A failure while the
|
|
52
|
+
* body streams is otherwise unchanged: same error, same classification.
|
|
53
|
+
*/
|
|
54
|
+
export async function readBody(read) {
|
|
55
|
+
try {
|
|
56
|
+
return await read;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw redactRejection(error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=fetch-redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-redaction.js","sourceRoot":"","sources":["../../src/services/fetch-redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,mGAAmG;AACnG,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD;;;GAGG;AACH,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM;QAAE,OAAO,mBAAmB,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC/D,IAAI,OAAO,KAAK,KAAK,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC;QACH,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,KAA2B,CAAC;IAC7C,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,IAAgB;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC;IACpB,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
|
|
@@ -25,6 +25,9 @@ export declare class NcbiApiClient {
|
|
|
25
25
|
* Uses plain fetch (not fetchWithTimeout) so we can capture response bodies on
|
|
26
26
|
* error status codes — fetchWithTimeout throws before the body can be read.
|
|
27
27
|
* Injects tool and email params but not api_key (eutils-specific).
|
|
28
|
+
*
|
|
29
|
+
* Records and error data name the URL's host and the caller's own params,
|
|
30
|
+
* never the request URL, whose query carries the operator's email.
|
|
28
31
|
*/
|
|
29
32
|
makeExternalRequest(url: string, params: NcbiRequestParams, externalSignal?: AbortSignal): Promise<string>;
|
|
30
33
|
private buildParams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/services/ncbi/api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/services/ncbi/api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EAAwB,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAoBnG,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,mBAAmB,EAAI;IAEtD,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAqCjB;IAED;;;;;;;;OAQG;IACG,mBAAmB,CACvB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,iBAAiB,EACzB,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,MAAM,CAAC,CAwCjB;IAED,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAUlB,sFAAsF;IACtF,OAAO,CAAC,WAAW;IAcnB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAI3B"}
|
|
@@ -6,9 +6,20 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { McpError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
8
8
|
import { httpErrorFromResponse, logger, requestContextService } from '@cyanheads/mcp-ts-core/utils';
|
|
9
|
+
import { redactRejection } from '../fetch-redaction.js';
|
|
9
10
|
import { NCBI_EUTILS_BASE_URL } from './types.js';
|
|
10
11
|
/** Maximum encoded query-string length before automatically switching to POST. */
|
|
11
12
|
const POST_THRESHOLD = 2000;
|
|
13
|
+
/**
|
|
14
|
+
* Wraps a non-`McpError` fetch rejection — header or body phase — as `ncbi_unreachable`.
|
|
15
|
+
* The request URL carries `api_key` and the operator's `email`, and a runtime can quote
|
|
16
|
+
* it in the rejection text, so that text is redacted before it becomes the message.
|
|
17
|
+
*/
|
|
18
|
+
function unreachable(error, data) {
|
|
19
|
+
const cause = redactRejection(error);
|
|
20
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
21
|
+
return serviceUnavailable(`NCBI request failed: ${msg}`, { reason: 'ncbi_unreachable', ...data }, { cause });
|
|
22
|
+
}
|
|
12
23
|
/**
|
|
13
24
|
* Low-level HTTP client for NCBI E-utilities. Constructs URLs, injects credentials,
|
|
14
25
|
* and chooses GET/POST based on payload size. Single-attempt — retry logic lives
|
|
@@ -25,7 +36,7 @@ export class NcbiApiClient {
|
|
|
25
36
|
const suffix = endpoint.includes('.') ? '' : '.fcgi';
|
|
26
37
|
const url = `${NCBI_EUTILS_BASE_URL}/${endpoint}${suffix}`;
|
|
27
38
|
try {
|
|
28
|
-
logger.debug(`NCBI HTTP request: ${usePost ? 'POST' : 'GET'} ${
|
|
39
|
+
logger.debug(`NCBI HTTP request: ${usePost ? 'POST' : 'GET'} ${endpoint}`, requestContextService.createRequestContext({
|
|
29
40
|
operation: 'NcbiHttpRequest',
|
|
30
41
|
additionalContext: { endpoint },
|
|
31
42
|
}));
|
|
@@ -49,8 +60,7 @@ export class NcbiApiClient {
|
|
|
49
60
|
catch (error) {
|
|
50
61
|
if (error instanceof McpError)
|
|
51
62
|
throw error;
|
|
52
|
-
|
|
53
|
-
throw serviceUnavailable(`NCBI request failed: ${msg}`, { reason: 'ncbi_unreachable', endpoint }, { cause: error });
|
|
63
|
+
throw unreachable(error, { endpoint });
|
|
54
64
|
}
|
|
55
65
|
}
|
|
56
66
|
/**
|
|
@@ -58,6 +68,9 @@ export class NcbiApiClient {
|
|
|
58
68
|
* Uses plain fetch (not fetchWithTimeout) so we can capture response bodies on
|
|
59
69
|
* error status codes — fetchWithTimeout throws before the body can be read.
|
|
60
70
|
* Injects tool and email params but not api_key (eutils-specific).
|
|
71
|
+
*
|
|
72
|
+
* Records and error data name the URL's host and the caller's own params,
|
|
73
|
+
* never the request URL, whose query carries the operator's email.
|
|
61
74
|
*/
|
|
62
75
|
async makeExternalRequest(url, params, externalSignal) {
|
|
63
76
|
const finalParams = {
|
|
@@ -70,11 +83,12 @@ export class NcbiApiClient {
|
|
|
70
83
|
}
|
|
71
84
|
const qs = new URLSearchParams(finalParams).toString();
|
|
72
85
|
const fullUrl = qs ? `${url}?${qs}` : url;
|
|
86
|
+
const host = URL.parse(url)?.host;
|
|
73
87
|
const signal = this.buildTimeoutSignal(externalSignal);
|
|
74
88
|
try {
|
|
75
|
-
logger.debug(
|
|
89
|
+
logger.debug('NCBI external request: GET', requestContextService.createRequestContext({
|
|
76
90
|
operation: 'NcbiExternalRequest',
|
|
77
|
-
additionalContext: {
|
|
91
|
+
additionalContext: { host, params },
|
|
78
92
|
}));
|
|
79
93
|
const response = await fetch(fullUrl, { signal });
|
|
80
94
|
const body = await response.text();
|
|
@@ -82,7 +96,7 @@ export class NcbiApiClient {
|
|
|
82
96
|
throw await httpErrorFromResponse(response, {
|
|
83
97
|
service: 'NCBI',
|
|
84
98
|
captureBody: false,
|
|
85
|
-
data: {
|
|
99
|
+
data: { host, body: body.substring(0, 500) },
|
|
86
100
|
});
|
|
87
101
|
}
|
|
88
102
|
return body;
|
|
@@ -90,8 +104,7 @@ export class NcbiApiClient {
|
|
|
90
104
|
catch (error) {
|
|
91
105
|
if (error instanceof McpError)
|
|
92
106
|
throw error;
|
|
93
|
-
|
|
94
|
-
throw serviceUnavailable(`NCBI request failed: ${msg}`, { reason: 'ncbi_unreachable', url }, { cause: error });
|
|
107
|
+
throw unreachable(error, { host });
|
|
95
108
|
}
|
|
96
109
|
}
|
|
97
110
|
buildParams(params) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/services/ncbi/api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEpG,OAAO,EAAE,oBAAoB,EAAmD,MAAM,YAAY,CAAC;AAEnG,kFAAkF;AAClF,MAAM,cAAc,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/services/ncbi/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,23 @@
|
|
|
4
4
|
* Pure TypeScript, zero dependencies, Workers-compatible.
|
|
5
5
|
* @module src/services/ncbi/formatting/citation-formatter
|
|
6
6
|
*/
|
|
7
|
-
import type { ParsedArticle } from '../types.js';
|
|
7
|
+
import type { ParsedArticle, ParsedCommentsCorrection } from '../types.js';
|
|
8
8
|
/** Supported citation output formats. */
|
|
9
9
|
export type CitationStyle = 'apa' | 'mla' | 'bibtex' | 'ris' | 'vancouver';
|
|
10
|
+
/**
|
|
11
|
+
* NCBI `RefType`s that qualify the cited article itself — it was retracted,
|
|
12
|
+
* corrected, or questioned. A link from a record that is itself a notice
|
|
13
|
+
* (`RetractionOf`, `ErratumFor`) and comment or update links are not among them:
|
|
14
|
+
* citing a retraction notice is not citing a retracted work. (#215)
|
|
15
|
+
*/
|
|
16
|
+
export declare const CITATION_NOTICE_TYPES: readonly ['RetractionIn', 'RetractedandRepublishedIn', 'ExpressionOfConcernIn', 'ErratumIn', 'CorrectedandRepublishedIn'];
|
|
17
|
+
export type CitationNoticeType = (typeof CITATION_NOTICE_TYPES)[number];
|
|
18
|
+
/** A linked notice that qualifies the cited article. */
|
|
19
|
+
export type CitationNotice = ParsedCommentsCorrection & {
|
|
20
|
+
refType: CitationNoticeType;
|
|
21
|
+
};
|
|
22
|
+
/** The record's linked notices that qualify the cited article, in NCBI's order. */
|
|
23
|
+
export declare function citationNotices(article: ParsedArticle): CitationNotice[];
|
|
10
24
|
/**
|
|
11
25
|
* Format a PubMed article as an APA 7th edition citation.
|
|
12
26
|
*
|
|
@@ -18,9 +32,19 @@ export type CitationStyle = 'apa' | 'mla' | 'bibtex' | 'ris' | 'vancouver';
|
|
|
18
32
|
* ```
|
|
19
33
|
* Title. (Year). *Journal*, *Volume*(Issue), Pages. https://doi.org/DOI
|
|
20
34
|
* ```
|
|
21
|
-
* A
|
|
35
|
+
* A retracted article ends on `(Retraction published <RefSource>)`. A Bookshelf
|
|
36
|
+
* record routes to {@link formatApaBook}.
|
|
22
37
|
*/
|
|
23
38
|
export declare function formatApa(article: ParsedArticle): string;
|
|
39
|
+
/**
|
|
40
|
+
* Format a PubMed article as an MLA 9th edition citation.
|
|
41
|
+
*
|
|
42
|
+
* Pattern:
|
|
43
|
+
* ```
|
|
44
|
+
* Last, First, et al. "Title." *Journal*, vol. 12, no. 3, 2024, pp. 45-67. DOI.
|
|
45
|
+
* ```
|
|
46
|
+
* A Bookshelf record routes to {@link formatMlaBook}.
|
|
47
|
+
*/
|
|
24
48
|
export declare function formatMla(article: ParsedArticle): string;
|
|
25
49
|
/**
|
|
26
50
|
* Format a PubMed article as a BibTeX entry.
|
|
@@ -43,6 +67,22 @@ export declare function formatBibtex(article: ParsedArticle): string;
|
|
|
43
67
|
* Record ends with `ER - ` (trailing spaces per spec).
|
|
44
68
|
*/
|
|
45
69
|
export declare function formatRis(article: ParsedArticle): string;
|
|
70
|
+
/**
|
|
71
|
+
* Format a PubMed article as a Vancouver (ICMJE/NLM) reference — the numbered
|
|
72
|
+
* style used by NEJM, Lancet, JAMA, BMJ, and most biomedical journals.
|
|
73
|
+
*
|
|
74
|
+
* Pattern (the leading list number is the consumer's responsibility — entries
|
|
75
|
+
* are formatted independently, so this returns the unnumbered reference body):
|
|
76
|
+
* ```
|
|
77
|
+
* Surname AB, Surname CD, et al. Article title. Abbrev J Name. Year;Vol(Issue):Pages. doi: 10.x/y
|
|
78
|
+
* ```
|
|
79
|
+
* Journal name uses the NLM/ISO abbreviation when available; pages are used as
|
|
80
|
+
* PubMed supplies them (often elided, e.g. "583-9"); the DOI carries no trailing
|
|
81
|
+
* period so it stays copy-pasteable, unless a note follows it. An article number replaces nothing — with
|
|
82
|
+
* no pagination it trails the source as an NLM note (`. pii: 2400512.`). A
|
|
83
|
+
* retraction or erratum follows as a note (`Retraction in: <RefSource>`). A
|
|
84
|
+
* Bookshelf record routes to {@link formatVancouverBook}.
|
|
85
|
+
*/
|
|
46
86
|
export declare function formatVancouver(article: ParsedArticle): string;
|
|
47
87
|
/**
|
|
48
88
|
* Format a single article in the requested citation style.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"citation-formatter.d.ts","sourceRoot":"","sources":["../../../../src/services/ncbi/formatting/citation-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,aAAa,
|
|
1
|
+
{"version":3,"file":"citation-formatter.d.ts","sourceRoot":"","sources":["../../../../src/services/ncbi/formatting/citation-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,aAAa,EAIb,wBAAwB,EAEzB,MAAM,aAAa,CAAC;AAErB,yCAAyC;AACzC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,WAAW,CAAC;AAE3E;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,YAChC,cAAc,EACd,2BAA2B,EAC3B,uBAAuB,EACvB,WAAW,EACX,2BAA2B,CACnB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,wBAAwB,GAAG;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAQxF,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,EAAE,CAExE;AAonBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAkExD;AAwDD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAwDxD;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAkH3D;AAMD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAwHxD;AAsGD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CA2D9D;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAanF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,aAAa,EAAE,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB"}
|