Skip to main content
Glama

get_full_text

Retrieve open-access full text articles from PubMed Central using PubMed IDs. Returns complete article content when available or provides alternative access information.

Instructions

Retrieve the full text of an article from PubMed Central (PMC) if available.

Only open-access articles archived in PMC have a full text. Subscription-only articles will return a link to PubMed instead.

Args: pmid: The PubMed ID of the article.

Returns: The full text (title, abstract, and body sections) when the article is open-access in PMC, or a helpful message with links otherwise.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pmidYes

Implementation Reference

  • main.py:444-539 (handler)
    The `get_full_text` function is decorated with `@mcp.tool()` and implements the logic to fetch full-text content from PubMed Central (PMC) based on a provided PubMed ID (PMID). It first retrieves the PMC ID from the PubMed record and then fetches the full text from PMC if it's available.
    @mcp.tool()
    async def get_full_text(pmid: str) -> str:
        """Retrieve the full text of an article from PubMed Central (PMC) if available.
    
        Only open-access articles archived in PMC have a full text.
        Subscription-only articles will return a link to PubMed instead.
    
        Args:
            pmid: The PubMed ID of the article.
    
        Returns:
            The full text (title, abstract, and body sections) when the article
            is open-access in PMC, or a helpful message with links otherwise.
        """
        pmid = pmid.strip()
        if not pmid.isdigit():
            return _err(f"Invalid PMID: {pmid!r}. A PMID must be a numeric string.")
    
        try:
            # 1) Retrieve the PubMed record to find the PMC ID
            fetch_resp = await _get(
                "efetch.fcgi",
                {"db": "pubmed", "id": pmid, "retmode": "xml", "rettype": "abstract"},
            )
            root = _require_xml(fetch_resp, f"efetch PMID {pmid}")
            article_xml = root.find(".//PubmedArticle")
    
            if article_xml is None:
                return _err(f"No article found for PMID {pmid}.")
    
            pmc_id: Optional[str] = None
            for id_el in article_xml.findall(".//ArticleId"):
                if id_el.get("IdType") == "pmc" and id_el.text:
                    pmc_id = id_el.text.strip()
                    break
    
            if not pmc_id:
                title_el = article_xml.find(".//ArticleTitle")
                title = "".join(title_el.itertext()).strip() if title_el is not None else ""
                msg = [f"Full text not available in PubMed Central for PMID {pmid}."]
                if title:
                    msg.append(f"Title: {title}")
                msg.append(
                    "The article may be subscription-only or not yet indexed in PMC.\n"
                    f"PubMed page: https://pubmed.ncbi.nlm.nih.gov/{pmid}/"
                )
                return "\n".join(msg)
    
            # 2) Fetch full-text XML from PMC
            numeric_id = pmc_id.replace("PMC", "")
            pmc_resp = await _get(
                "efetch.fcgi",
                {"db": "pmc", "id": numeric_id, "retmode": "xml", "rettype": "full"},
            )
    
            try:
                pmc_root = ET.fromstring(pmc_resp.text)
            except ET.ParseError as exc:
                return (
                    f"Full text is available in PMC but could not be parsed.\n"
                    f"Reason: {exc}\n"
                    f"PMC URL: https://www.ncbi.nlm.nih.gov/pmc/articles/{pmc_id}/"
                )
    
            sections: list[str] = []
    
            title_el = pmc_root.find(".//article-title")
            if title_el is not None:
                sections.append(f"TITLE\n{''.join(title_el.itertext()).strip()}\n")
    
            abstract_el = pmc_root.find(".//abstract")
            if abstract_el is not None:
                sections.append("ABSTRACT\n" + "".join(abstract_el.itertext()).strip() + "\n")
    
            body = pmc_root.find(".//body")
            if body is not None:
                for sec in body.findall(".//sec"):
                    title_el = sec.find("title")
                    if title_el is not None:
                        sections.append(f"\n{''.join(title_el.itertext()).upper()}")
                    for p in sec.findall("p"):
                        para = "".join(p.itertext()).strip()
                        if para:
                            sections.append(para)
    
            if not sections:
                return (
                    f"Full text is available in PMC but the content could not be extracted.\n"
                    f"PMC URL: https://www.ncbi.nlm.nih.gov/pmc/articles/{pmc_id}/"
                )
    
            header = f"=== Full Text — PMID {pmid} | {pmc_id} ===\n"
            return header + "\n".join(sections)
    
        except PubMedError as exc:
            return _err(str(exc))

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/benoitleq/mcp-pubmed'

If you have feedback or need assistance with the MCP directory API, please join our Discord server