@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.
71 lines • 3.56 kB
TypeScript
/**
* @fileoverview Europe PMC service. Wraps the EPMC REST API with rate-limiting,
* retries, and JATS XML parsing. Two methods: `search()` for keyword discovery
* across the EPMC corpus (MED/PMC/PPR/PAT/AGR) and `fullTextXml()` for fetching
* a record's full-text JATS. The XML parser matches NCBI's ordered config so
* `parsePmcArticle` consumes the result without modification.
*
* Optional service: only constructed when `EUROPEPMC_ENABLED=true` (the
* default). `getEuropePmcService()` returns `undefined` when disabled so
* callers can skip the chain step gracefully.
*
* @module src/services/europe-pmc/europe-pmc-service
*/
import type { JatsNode } from '../../services/ncbi/parsing/pmc-xml-helpers.js';
import { EuropePmcApiClient } from './api-client.js';
import { EuropePmcRequestQueue } from './request-queue.js';
import type { EuropePmcFullTextResult, EuropePmcSearchParams, EuropePmcSearchResult, EuropePmcSource } from './types.js';
/**
* Facade over the Europe PMC REST API. Two methods:
* - `search()` — keyword search across MED/PMC/PPR/PAT/AGR.
* - `fullTextXml()` — JATS full text for an EPMC record.
*
* Both honor `ctx.signal` for cancellation and retry transient failures with
* capped exponential backoff plus jitter.
*/
export declare class EuropePmcService {
private readonly client;
private readonly queue;
private readonly maxRetries;
private readonly orderedXmlParser;
constructor(client: EuropePmcApiClient, queue: EuropePmcRequestQueue, maxRetries: number);
/**
* Search Europe PMC. Cursor-based pagination — pass `cursorMark: '*'` (or
* omit) for the first page; pass the returned `nextCursorMark` for the next.
*/
search(params: EuropePmcSearchParams): Promise<EuropePmcSearchResult>;
/**
* Fetch the JATS full text for an EPMC record. Returns:
* - `{ kind: 'found', xml, epmcId, source }` — JATS XML string usable
* directly by tool callers that hold their own parser, or via
* `parseFullTextXml()` for the parsed tree.
* - `{ kind: 'not-available', reason }` — EPMC has the record but
* publishes no fullTextXML (404 or empty body).
*/
fullTextXml(epmcId: string, source: EuropePmcSource, signal?: AbortSignal): Promise<EuropePmcFullTextResult>;
/**
* Parse a JATS XML string into the ordered node tree consumed by
* `parsePmcArticle`. Returns the `<article>` JatsNode, or `undefined` when
* the body doesn't contain an article element (malformed / empty).
*
* Throws `SerializationError` only for fundamentally invalid XML; an
* article-free but well-formed body returns `undefined` so callers can
* surface a `no-epmc-fulltext` outcome without a hard failure.
*/
parseFullTextXml(xml: string): JatsNode | undefined;
/**
* Retry wrapper for transient errors. Mirrors NCBI's `withRetry` minus the
* service-level deadline — EPMC requests are cheaper individually and the
* caller (typically `ctx.signal`) bounds the total chain.
*/
private withRetry;
}
/**
* Initialize the Europe PMC service when enabled. Safe to call regardless of
* config — `EUROPEPMC_ENABLED=false` leaves the service unset so callers see
* `undefined` and skip the chain step.
*/
export declare function initEuropePmcService(): void;
/** Returns the initialized service, or `undefined` when EPMC is disabled. */
export declare function getEuropePmcService(): EuropePmcService | undefined;
//# sourceMappingURL=europe-pmc-service.d.ts.map