UNPKG

@cyanheads/pubmed-mcp-server

Version:

Search PubMed/Europe PMC, fetch articles and full text (PMC/EPMC/Unpaywall), citations, MeSH terms via MCP. STDIO or Streamable HTTP.

53 lines 2.7 kB
/** * @fileoverview Handles parsing of NCBI E-utility responses and NCBI-specific error extraction. * Creates an NCBI-specific XMLParser instance with `isArray` callback support for handling * NCBI's inconsistent XML structures where single-element lists are collapsed to scalars. * @module src/services/ncbi/response-handler */ import type { NcbiRequestOptions } from './types.js'; /** * Flattens inline mixed-content markup (`<sup>`, `<sub>`, `<inf>`, `<i>`, * `<b>`, `<u>`, `<sc>`) inside PubMed/MEDLINE XML before fast-xml-parser * runs. The non-ordered parser used for EFetch responses doesn't preserve * mixed content — `1.73 m<sup>2</sup>` parses to `{ '#text': '1.73 m', sup: * 2 }`, and `extractAbstractText` only reads `#text`, so the superscript * digit is silently dropped from abstracts and titles. * * Numeric and operator characters map to Unicode (²/³/⁻²/₂…); anything else * falls back to a `^X` / `_X` ASCII prefix so the content survives in a * recognizable form. Italic / bold / underline / small-caps tags are * stripped (content kept) since they don't carry meaning in our text * rendering. Only invoked on the regular parser path; the PMC JATS path * already preserves inline markup via `preserveOrder: true`. * * @internal exported for direct unit tests */ export declare function flattenInlineMarkup(xml: string): string; /** * Parses NCBI E-utility responses (XML, JSON, text) and checks for NCBI-specific * error structures embedded in response bodies. */ export declare class NcbiResponseHandler { private readonly xmlParser; /** * Parser configured for JATS mixed content (PMC full-text). `preserveOrder` * keeps document order so inline markup in `<p>`, `<abstract>`, `<title>` * doesn't collapse into reordered text. `trimValues: false` retains spacing * between text nodes and adjacent inline children. */ private readonly orderedXmlParser; constructor(); /** * Extract a structured error from a parsed NCBI XML body and throw it as * `notFound()` for permanent "no such record" responses or `serviceUnavailable()` * for transient backend failures. Never returns. * * NCBI returns "cannot get document summary" / "Empty id list" for invalid * UIDs — these are permanent (the record doesn't exist), so we surface them * as NotFound so the retry loop short-circuits instead of hammering NCBI. */ private throwNcbiError; extractNcbiErrorMessages(parsedXml: Record<string, unknown>): string[]; parseAndHandleResponse<T>(responseText: string, endpoint: string, options?: NcbiRequestOptions): T; } //# sourceMappingURL=response-handler.d.ts.map