@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.
561 lines • 16.4 kB
TypeScript
/**
* @fileoverview Type definitions for NCBI E-utilities XML structures and parsed results.
* Used for parsing data from EFetch, ESummary, and ESearch endpoints.
* @module src/services/ncbi/types
*/
/** Base URL for all NCBI E-utility endpoints. */
export declare const NCBI_EUTILS_BASE_URL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils";
/** Base URL for the PMC ID Converter API (separate from E-utilities). */
export declare const NCBI_PMC_IDCONV_URL = "https://pmc.ncbi.nlm.nih.gov/tools/idconv/api/v1/articles/";
/**
* Common NCBI E-utility request parameters.
* Specific endpoints extend this with their own fields via the index signature.
*/
export interface NcbiRequestParams {
/** Target database (e.g. 'pubmed', 'pmc'). Optional for einfo when listing all databases. */
db?: string;
[key: string]: string | number | undefined;
}
/**
* Options controlling how an NCBI request is made and how the response is handled.
*/
export interface NcbiRequestOptions {
/** Desired response format. */
retmode?: 'xml' | 'json' | 'text';
/** Specific return type (e.g. 'abstract', 'medline'). */
rettype?: string;
/** When true and retmode is 'xml', return the raw XML string after error checking. */
returnRawXml?: boolean;
/**
* Combined abort signal — internal service-level deadline OR'd with the
* caller's `ctx.signal`. Cancels the in-flight fetch and short-circuits
* backoff sleeps.
*/
signal?: AbortSignal;
/**
* Parse XML in `preserveOrder: true` mode (returns `JatsNodeList`). Required
* for JATS mixed-content responses (PMC full-text) where inline element order
* must be preserved in the output. Leave false for all other E-utilities.
*/
useOrderedParser?: boolean;
/** Force HTTP POST (for large payloads). */
usePost?: boolean;
}
/**
* Runtime options accepted by public NCBI service methods.
* Lets callers thread `ctx.signal` (from tool handlers) through the retry layer.
*/
export interface NcbiCallOptions {
/** Caller-provided abort signal; combined with the service's internal deadline. */
signal?: AbortSignal;
}
/**
* Options for the parseFullArticle convenience function.
*/
export interface ParseFullArticleOptions {
includeGrants?: boolean;
includeMesh?: boolean;
}
export interface XmlTextElement {
'#text'?: string;
[key: string]: unknown;
}
export type XmlPMID = XmlTextElement;
export interface XmlArticleDate extends XmlTextElement {
'@_DateType'?: string;
Day?: XmlTextElement;
Month?: XmlTextElement;
Year?: XmlTextElement;
}
export interface XmlIdentifier extends XmlTextElement {
'@_Source'?: string;
}
export interface XmlAuthor {
AffiliationInfo?: {
Affiliation?: XmlTextElement;
}[];
CollectiveName?: XmlTextElement;
ForeName?: XmlTextElement;
Identifier?: XmlIdentifier[] | XmlIdentifier;
Initials?: XmlTextElement;
LastName?: XmlTextElement;
}
export interface XmlAuthorList {
'@_CompleteYN'?: 'Y' | 'N';
Author?: XmlAuthor[] | XmlAuthor;
}
export interface XmlPublicationType extends XmlTextElement {
'@_UI'?: string;
}
export interface XmlPublicationTypeList {
PublicationType: XmlPublicationType[] | XmlPublicationType;
}
export interface XmlELocationID extends XmlTextElement {
'@_EIdType'?: string;
'@_ValidYN'?: 'Y' | 'N';
}
export interface XmlArticleId extends XmlTextElement {
'@_IdType'?: string;
}
export interface XmlArticleIdList {
ArticleId: XmlArticleId[] | XmlArticleId;
}
export interface XmlAbstractText extends XmlTextElement {
'@_Label'?: string;
'@_NlmCategory'?: string;
}
export interface XmlAbstract {
AbstractText: XmlAbstractText[] | XmlAbstractText;
CopyrightInformation?: XmlTextElement;
}
export interface XmlPagination {
EndPage?: XmlTextElement;
MedlinePgn?: XmlTextElement;
StartPage?: XmlTextElement;
}
export interface XmlPubDate {
Day?: XmlTextElement;
MedlineDate?: XmlTextElement;
Month?: XmlTextElement;
Year?: XmlTextElement;
}
export interface XmlJournalIssue {
'@_CitedMedium'?: string;
Issue?: XmlTextElement;
PubDate?: XmlPubDate;
Volume?: XmlTextElement;
}
export interface XmlJournal {
ISOAbbreviation?: XmlTextElement;
ISSN?: XmlTextElement & {
'@_IssnType'?: string;
};
JournalIssue?: XmlJournalIssue;
Title?: XmlTextElement;
}
export interface XmlArticle {
Abstract?: XmlAbstract;
ArticleDate?: XmlArticleDate[] | XmlArticleDate;
ArticleIdList?: XmlArticleIdList;
ArticleTitle?: XmlTextElement | string;
AuthorList?: XmlAuthorList;
ELocationID?: XmlELocationID[] | XmlELocationID;
GrantList?: XmlGrantList;
Journal?: XmlJournal;
KeywordList?: XmlKeywordList[] | XmlKeywordList;
Language?: XmlTextElement[] | XmlTextElement;
Pagination?: XmlPagination;
PublicationTypeList?: XmlPublicationTypeList;
}
export interface XmlMeshQualifierName extends XmlTextElement {
'@_MajorTopicYN'?: 'Y' | 'N';
'@_UI'?: string;
}
export interface XmlMeshDescriptorName extends XmlTextElement {
'@_MajorTopicYN'?: 'Y' | 'N';
'@_UI'?: string;
}
export interface XmlMeshHeading {
'@_MajorTopicYN'?: 'Y' | 'N';
DescriptorName: XmlMeshDescriptorName;
QualifierName?: XmlMeshQualifierName[] | XmlMeshQualifierName;
}
export interface XmlMeshHeadingList {
MeshHeading: XmlMeshHeading[] | XmlMeshHeading;
}
export interface XmlKeyword extends XmlTextElement {
'@_MajorTopicYN'?: 'Y' | 'N';
'@_Owner'?: string;
}
export interface XmlKeywordList {
'@_Owner'?: string;
Keyword: XmlKeyword[] | XmlKeyword;
}
export interface XmlGrant {
Acronym?: XmlTextElement;
Agency?: XmlTextElement;
Country?: XmlTextElement;
GrantID?: XmlTextElement;
}
export interface XmlGrantList {
'@_CompleteYN'?: 'Y' | 'N';
Grant: XmlGrant[] | XmlGrant;
}
export interface XmlMedlineCitation {
'@_Owner'?: string;
'@_Status'?: string;
Article?: XmlArticle;
CitationSubset?: XmlTextElement[] | XmlTextElement;
DateCompleted?: XmlArticleDate;
DateCreated?: XmlArticleDate;
DateRevised?: XmlArticleDate;
GeneralNote?: (XmlTextElement & {
'@_Owner'?: string;
})[];
KeywordList?: XmlKeywordList[] | XmlKeywordList;
MeshHeadingList?: XmlMeshHeadingList;
PMID: XmlPMID;
}
export interface XmlPubmedArticle {
MedlineCitation: XmlMedlineCitation;
PubmedData?: {
History?: {
PubMedPubDate: (XmlArticleDate & {
'@_PubStatus'?: string;
})[];
};
PublicationStatus?: XmlTextElement;
ArticleIdList?: XmlArticleIdList;
ReferenceList?: unknown;
};
}
export interface XmlPubmedArticleSet {
DeleteCitation?: {
PMID: XmlPMID[] | XmlPMID;
};
PubmedArticle?: XmlPubmedArticle[] | XmlPubmedArticle;
}
export interface ParsedArticleAuthor {
affiliationIndices?: number[];
collectiveName?: string;
firstName?: string;
initials?: string;
lastName?: string;
orcid?: string;
}
export interface ParsedArticleDate {
dateType?: string;
day?: string;
month?: string;
year?: string;
}
export interface ParsedJournalPublicationDate {
day?: string;
medlineDate?: string;
month?: string;
year?: string;
}
export interface ParsedJournalInfo {
eIssn?: string;
isoAbbreviation?: string;
issn?: string;
issue?: string;
pages?: string;
publicationDate?: ParsedJournalPublicationDate;
title?: string;
volume?: string;
}
export interface ParsedMeshQualifier {
isMajorTopic: boolean;
qualifierName: string;
qualifierUi?: string;
}
export interface ParsedMeshTerm {
descriptorName?: string;
descriptorUi?: string;
isMajorTopic: boolean;
qualifiers?: ParsedMeshQualifier[];
}
export interface ParsedGrant {
acronym?: string;
agency?: string;
country?: string;
grantId?: string;
}
export interface ParsedArticle {
abstractText?: string;
affiliations?: string[];
articleDates?: ParsedArticleDate[];
authors?: ParsedArticleAuthor[];
doi?: string;
grantList?: ParsedGrant[];
journalInfo?: ParsedJournalInfo;
keywords?: string[];
meshTerms?: ParsedMeshTerm[];
pmcId?: string;
pmid: string;
publicationTypes?: string[];
title?: string;
}
/**
* Represents a raw author entry as parsed from ESummary XML.
* This type accounts for potential inconsistencies in property naming (e.g., Name/name)
* and structure directly from the XML-to-JavaScript conversion.
* It is intended for use as an intermediate type before normalization into ESummaryAuthor.
*/
export interface XmlESummaryAuthorRaw {
'#text'?: string;
AuthType?: string;
authtype?: string;
ClusterId?: string;
clusterid?: string;
Name?: string;
name?: string;
[key: string]: unknown;
}
/**
* Represents a normalized author entry after parsing from ESummary data.
* This is the clean, canonical structure for application use.
*/
export interface ESummaryAuthor {
authtype?: string;
clusterid?: string;
name: string;
}
/**
* NCBI returns ArticleId entries in two shapes depending on retmode:
* - JSON (`retmode=json&version=2.0`): lowercase keys `{ idtype, idtypen, value }`
* - XML (`retmode=xml&version=2.0`): capitalized child elements parsed as
* `{ IdType, IdTypeN, Value }` by fast-xml-parser.
*
* Both shapes are supported so callers don't have to care which retmode produced
* the summary. Use the helpers in `esummary-parser.ts` to read them safely.
*/
export interface ESummaryArticleId {
IdType?: string;
IdTypeN?: number;
idtype?: string;
idtypen?: number;
Value?: string | number;
value?: string | number;
[key: string]: unknown;
}
export interface ESummaryHistory {
date: string;
pubstatus: string;
}
export interface ESummaryItem {
'@_Name': string;
'@_Type': 'String' | 'Integer' | 'Date' | 'List' | 'Structure' | 'Unknown' | 'ERROR';
'#text'?: string;
Item?: ESummaryItem[] | ESummaryItem;
[key: string]: unknown;
}
export interface ESummaryDocSumOldXml {
Id: string;
Item: ESummaryItem[];
}
export interface ESummaryDocumentSummary {
'@_uid': string;
ArticleIds?: ESummaryArticleId[] | {
ArticleId: ESummaryArticleId[] | ESummaryArticleId;
};
Attributes?: string[];
Authors?: XmlESummaryAuthorRaw[] | {
Author: XmlESummaryAuthorRaw[] | XmlESummaryAuthorRaw;
} | string;
DOI?: string;
EPubDate?: string;
ESSN?: string;
FullJournalName?: string;
History?: ESummaryHistory[] | {
PubMedPubDate: ESummaryHistory[] | ESummaryHistory;
};
ISSN?: string;
Issue?: string;
Lang?: string[];
LastAuthor?: string;
Pages?: string;
PubDate?: string;
PubStatus?: string;
PubType?: string[];
RecordStatus?: string;
References?: unknown[];
SO?: string;
SortTitle?: string;
Source?: string;
Title?: string;
Volume?: string;
[key: string]: unknown;
}
export interface ESummaryDocumentSummarySet {
DocumentSummary: ESummaryDocumentSummary[] | ESummaryDocumentSummary;
}
export interface ESummaryResult {
DocSum?: ESummaryDocSumOldXml[] | ESummaryDocSumOldXml;
DocumentSummarySet?: ESummaryDocumentSummarySet;
ERROR?: string;
[key: string]: unknown;
}
export interface ESummaryResponseContainer {
eSummaryResult: ESummaryResult;
}
export interface ParsedBriefSummary {
authors?: string;
doi?: string;
epubDate?: string;
pmcId?: string;
pmid: string;
pubDate?: string;
source?: string;
title?: string;
}
export interface ESearchResultIdList {
Id: string[];
}
export interface ESearchTranslation {
From: string;
To: string;
}
export interface ESearchTranslationSet {
Translation: ESearchTranslation[];
}
export interface ESearchWarningList {
FieldNotFound?: string[];
OutputMessage?: string[];
PhraseNotFound?: string[];
QuotedPhraseNotFound?: string[];
}
export interface ESearchErrorList {
FieldNotFound?: string[];
PhraseNotFound?: string[];
}
export interface ESearchResultContent {
Count: string;
ErrorList?: ESearchErrorList;
IdList?: ESearchResultIdList;
QueryKey?: string;
QueryTranslation: string;
RetMax: string;
RetStart: string;
TranslationSet?: ESearchTranslationSet;
TranslationStack?: unknown;
WarningList?: ESearchWarningList;
WebEnv?: string;
}
export interface ESearchResponseContainer {
eSearchResult: ESearchResultContent;
}
export interface ESearchResult {
count: number;
errorList?: ESearchErrorList;
idList: string[];
queryKey?: string;
queryTranslation: string;
retmax: number;
retstart: number;
warningList?: ESearchWarningList;
webEnv?: string;
}
/** Normalized ESpell result. */
export interface ESpellResult {
corrected: string;
hasSuggestion: boolean;
original: string;
}
/** Raw parsed XML container for eSpellResult. */
export interface ESpellResponseContainer {
eSpellResult: {
Query?: string;
CorrectedQuery?: string;
SpelledQuery?: unknown;
};
}
export interface EFetchArticleSet {
articles: ParsedArticle[];
}
/** Parsed full-text article from PMC. */
export interface ParsedPmcArticle {
abstract?: string;
affiliations?: string[];
articleType?: string;
authors?: ParsedPmcAuthor[];
doi?: string;
journal?: ParsedPmcJournal;
keywords?: string[];
pmcId: string;
pmcUrl: string;
pmid?: string;
publicationDate?: {
year?: string;
month?: string;
day?: string;
};
pubmedUrl?: string;
references?: ParsedPmcReference[];
sections: ParsedPmcSection[];
title?: string;
}
/** Parsed PMC author. */
export interface ParsedPmcAuthor {
collectiveName?: string;
givenNames?: string;
lastName?: string;
}
/** Parsed PMC journal info. */
export interface ParsedPmcJournal {
issn?: string;
issue?: string;
pages?: string;
title?: string;
volume?: string;
}
/** Parsed PMC article section. */
export interface ParsedPmcSection {
label?: string;
subsections?: ParsedPmcSection[];
text: string;
title?: string;
}
/** Parsed PMC reference. */
export interface ParsedPmcReference {
citation: string;
id?: string;
label?: string;
}
/** Single citation for ECitMatch lookup. */
export interface ECitMatchCitation {
/** Author name (e.g., "mann bj") */
authorName?: string | undefined;
/** First page number */
firstPage?: string | undefined;
/** Journal title or ISO abbreviation */
journal?: string | undefined;
/** Arbitrary key for tracking this citation in results */
key: string;
/** Volume number */
volume?: string | undefined;
/** Publication year */
year?: string | undefined;
}
/** Single result from ECitMatch lookup. */
export interface ECitMatchResult {
/**
* Candidate PMIDs for AMBIGUOUS results, parsed from the `AMBIGUOUS <csv>`
* detail string. Only present when status is `ambiguous`.
*/
candidatePmids?: string[];
/** Raw non-match detail returned by ECitMatch when present */
detail?: string;
/** The tracking key from the input citation */
key: string;
/** Whether a PMID was found */
matched: boolean;
/** Matched PubMed ID, or null if no match */
pmid: string | null;
/** Lookup outcome classification for recovery guidance */
status: 'matched' | 'not_found' | 'ambiguous';
}
/** Single record from the PMC ID Converter API response. */
export interface IdConvertRecord {
/** Digital Object Identifier */
doi?: string;
/** Error message if conversion failed for this ID */
errmsg?: string;
/** PubMed Central ID (e.g., "PMC1234567") */
pmcid?: string;
/** PubMed ID (numeric string) */
pmid?: string;
/** The ID that was originally requested */
'requested-id': string;
/** Record-level status: present only on error records */
status?: string;
}
/** JSON response from the PMC ID Converter API. */
export interface IdConvertResponse {
records: IdConvertRecord[];
request: Record<string, unknown>;
'response-date': string;
status: string;
}
//# sourceMappingURL=types.d.ts.map