Skip to main content
Glama
flyanima

Open Search MCP

by flyanima

pubmed_article_details

Retrieve comprehensive details for specific PubMed articles using their PMID identifiers to access publication information, abstracts, and metadata.

Instructions

Get detailed information about a specific PubMed article

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pmidYesPubMed ID (PMID) of the article

Implementation Reference

  • The main handler function that executes the tool logic: fetches article summary via PubMed ESummary API, attempts to fetch full abstract, constructs detailed article object with metadata.
    execute: async (args: any) => {
      const { pmid } = args;
    
      try {
        // 获取文章摘要信息
        const summaryParams = {
          db: 'pubmed',
          id: pmid,
          retmode: 'json'
        };
    
        const summaryResult = await client.makeRequest('esummary.fcgi', summaryParams);
    
        if (!summaryResult.result || !summaryResult.result[pmid]) {
          return {
            success: false,
            error: `Article with PMID ${pmid} not found`
          };
        }
    
        const article = summaryResult.result[pmid];
    
        // 尝试获取全文摘要
        let fullAbstract = null;
        try {
          const fetchParams = {
            db: 'pubmed',
            id: pmid,
            retmode: 'xml',
            rettype: 'abstract'
          };
    
          const fetchResult = await client.makeRequest('efetch.fcgi', fetchParams);
          // 这里可以解析XML获取完整摘要,暂时使用summary中的摘要
          fullAbstract = article.abstract || 'No abstract available';
        } catch (fetchError) {
          fullAbstract = article.abstract || 'No abstract available';
        }
    
        const articleDetails = {
          pmid: article.uid,
          title: article.title || 'No title available',
          abstract: fullAbstract,
          authors: (article.authors || []).map((author: any) => ({
            name: author.name,
            affiliation: author.affiliation || null
          })),
          journal: {
            name: article.fulljournalname || article.source || 'Unknown journal',
            abbreviation: article.source || null,
            volume: article.volume || null,
            issue: article.issue || null,
            pages: article.pages || null
          },
          publicationDate: article.pubdate || 'Unknown date',
          publicationType: (article.pubtype || []).join(', ') || 'Unknown type',
          doi: article.elocationid && article.elocationid.includes('doi:')
            ? article.elocationid.replace('doi: ', '')
            : null,
          pmcid: article.pmcid || null,
          meshTerms: article.keywords || [],
          url: `https://pubmed.ncbi.nlm.nih.gov/${article.uid}/`,
          fullTextUrl: article.pmcid ? `https://www.ncbi.nlm.nih.gov/pmc/articles/${article.pmcid}/` : null,
          citationCount: null, // PubMed API不直接提供引用数
          source: 'PubMed'
        };
    
        return {
          success: true,
          data: {
            source: 'PubMed API',
            article: articleDetails,
            timestamp: Date.now(),
            apiUsed: true
          }
        };
      } catch (error) {
        return {
          success: false,
          error: `Failed to get PubMed article details: ${error instanceof Error ? error.message : String(error)}`
        };
      }
    }
  • Input schema defining the required 'pmid' parameter as a string.
    inputSchema: {
      type: 'object',
      properties: {
        pmid: {
          type: 'string',
          description: 'PubMed ID (PMID) of the article'
        }
      },
      required: ['pmid']
    },
  • Tool registration call within registerPubMedTools function, including name, description, schema, and handler reference.
    registry.registerTool({
      name: 'pubmed_article_details',
      description: 'Get detailed information about a specific PubMed article',
      category: 'academic',
      source: 'PubMed',
      inputSchema: {
        type: 'object',
        properties: {
          pmid: {
            type: 'string',
            description: 'PubMed ID (PMID) of the article'
          }
        },
        required: ['pmid']
      },
      execute: async (args: any) => {
        const { pmid } = args;
    
        try {
          // 获取文章摘要信息
          const summaryParams = {
            db: 'pubmed',
            id: pmid,
            retmode: 'json'
          };
    
          const summaryResult = await client.makeRequest('esummary.fcgi', summaryParams);
    
          if (!summaryResult.result || !summaryResult.result[pmid]) {
            return {
              success: false,
              error: `Article with PMID ${pmid} not found`
            };
          }
    
          const article = summaryResult.result[pmid];
    
          // 尝试获取全文摘要
          let fullAbstract = null;
          try {
            const fetchParams = {
              db: 'pubmed',
              id: pmid,
              retmode: 'xml',
              rettype: 'abstract'
            };
    
            const fetchResult = await client.makeRequest('efetch.fcgi', fetchParams);
            // 这里可以解析XML获取完整摘要,暂时使用summary中的摘要
            fullAbstract = article.abstract || 'No abstract available';
          } catch (fetchError) {
            fullAbstract = article.abstract || 'No abstract available';
          }
    
          const articleDetails = {
            pmid: article.uid,
            title: article.title || 'No title available',
            abstract: fullAbstract,
            authors: (article.authors || []).map((author: any) => ({
              name: author.name,
              affiliation: author.affiliation || null
            })),
            journal: {
              name: article.fulljournalname || article.source || 'Unknown journal',
              abbreviation: article.source || null,
              volume: article.volume || null,
              issue: article.issue || null,
              pages: article.pages || null
            },
            publicationDate: article.pubdate || 'Unknown date',
            publicationType: (article.pubtype || []).join(', ') || 'Unknown type',
            doi: article.elocationid && article.elocationid.includes('doi:')
              ? article.elocationid.replace('doi: ', '')
              : null,
            pmcid: article.pmcid || null,
            meshTerms: article.keywords || [],
            url: `https://pubmed.ncbi.nlm.nih.gov/${article.uid}/`,
            fullTextUrl: article.pmcid ? `https://www.ncbi.nlm.nih.gov/pmc/articles/${article.pmcid}/` : null,
            citationCount: null, // PubMed API不直接提供引用数
            source: 'PubMed'
          };
    
          return {
            success: true,
            data: {
              source: 'PubMed API',
              article: articleDetails,
              timestamp: Date.now(),
              apiUsed: true
            }
          };
        } catch (error) {
          return {
            success: false,
            error: `Failed to get PubMed article details: ${error instanceof Error ? error.message : String(error)}`
          };
        }
      }
    });
  • PubMedAPIClient class providing makeRequest method used by the handler to query PubMed EUtils APIs.
    class PubMedAPIClient {
      private baseURL = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils';
      private apiKey: string | undefined;
    
      constructor(apiKey?: string) {
        this.apiKey = apiKey;
      }
    
      async makeRequest(endpoint: string, params: Record<string, any> = {}) {
        try {
          const requestParams = {
            ...params,
            retmode: 'json',
            retmax: Math.min(params.retmax || 20, 200),
            tool: 'open-search-mcp',
            email: 'support@open-search-mcp.com'
          };
    
          if (this.apiKey) {
            (requestParams as any).api_key = this.apiKey;
          }
    
          const response = await axios.get(`${this.baseURL}/${endpoint}`, {
            params: requestParams,
            timeout: 20000,
            headers: {
              'User-Agent': 'Open-Search-MCP/2.0'
            }
          });
    
          return response.data;
        } catch (error) {
          throw error;
        }
      }
    
      async searchPubMed(query: string, options: any = {}) {
        // 第一步:搜索获取PMID列表
        const searchParams = {
          db: 'pubmed',
          term: query,
          retmax: options.maxResults || 20,
          sort: options.sort === 'date' ? 'pub_date' : 'relevance',
          datetype: 'pdat'
        };
    
        // 添加日期过滤
        if (options.dateRange && options.dateRange !== 'all') {
          const now = new Date();
          let startDate;
    
          switch (options.dateRange) {
            case '1year':
              startDate = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate());
              break;
            case '5years':
              startDate = new Date(now.getFullYear() - 5, now.getMonth(), now.getDate());
              break;
            case '10years':
              startDate = new Date(now.getFullYear() - 10, now.getMonth(), now.getDate());
              break;
          }
    
          if (startDate) {
            const startDateStr = startDate.toISOString().split('T')[0].replace(/-/g, '/');
            const endDateStr = now.toISOString().split('T')[0].replace(/-/g, '/');
            searchParams.term += ` AND ("${startDateStr}"[Date - Publication] : "${endDateStr}"[Date - Publication])`;
          }
        }
    
        // 添加出版物类型过滤
        if (options.publicationType && options.publicationType !== 'all') {
          const typeMap: Record<string, string> = {
            'review': 'Review[Publication Type]',
            'clinical_trial': 'Clinical Trial[Publication Type]',
            'meta_analysis': 'Meta-Analysis[Publication Type]',
            'case_report': 'Case Reports[Publication Type]'
          };
    
          const pubType = options.publicationType as string;
          if (typeMap[pubType]) {
            searchParams.term += ` AND ${typeMap[pubType]}`;
          }
        }
    
        const searchResult = await this.makeRequest('esearch.fcgi', searchParams);
    
        if (!searchResult.esearchresult || !searchResult.esearchresult.idlist || searchResult.esearchresult.idlist.length === 0) {
          return { articles: [], count: 0 };
        }
    
        const pmids = searchResult.esearchresult.idlist;
    
        // 第二步:获取详细信息
        const summaryParams = {
          db: 'pubmed',
          id: pmids.join(','),
          retmode: 'json'
        };
    
        const summaryResult = await this.makeRequest('esummary.fcgi', summaryParams);
    
        return {
          articles: this.parseSummaryResult(summaryResult),
          count: parseInt(searchResult.esearchresult.count) || 0
        };
      }
    
      private parseSummaryResult(summaryResult: any): any[] {
        if (!summaryResult.result) return [];
    
        const articles = [];
        const uids = summaryResult.result.uids || [];
    
        for (const uid of uids) {
          const article = summaryResult.result[uid];
          if (!article) continue;
    
          articles.push({
            pmid: article.uid,
            title: article.title || 'No title available',
            abstract: article.abstract || 'No abstract available',
            authors: (article.authors || []).map((author: any) => author.name).join(', '),
            journal: article.fulljournalname || article.source || 'Unknown journal',
            publicationDate: article.pubdate || 'Unknown date',
            publicationType: (article.pubtype || []).join(', ') || 'Unknown type',
            doi: article.elocationid && article.elocationid.includes('doi:')
              ? article.elocationid.replace('doi: ', '')
              : null,
            pmcid: article.pmcid || null,
            volume: article.volume || null,
            issue: article.issue || null,
            pages: article.pages || null,
            url: `https://pubmed.ncbi.nlm.nih.gov/${article.uid}/`,
            fullTextUrl: article.pmcid ? `https://www.ncbi.nlm.nih.gov/pmc/articles/${article.pmcid}/` : null
          });
        }
    
        return articles;
      }
    }

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/flyanima/open-search-mcp'

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