Skip to main content
Glama
PancrePal-xiaoyibao

Clinical Trials MCP Server

search_clinical_trials

Search for clinical trials by keywords, disease type, and location to find recruiting studies with recent updates from ClinicalTrials.gov.

Instructions

搜索临床试验。默认查询招募中且过去3个月内更新的试验,按更新时间降序返回30个最相关结果。支持根据关键词(如KRAS-12D)、疾病类型(如胰腺癌)、地理位置(国家/城市)等条件查询。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keywordsNo关键词,例如:KRAS-12D、PD-1、Pembrolizumab等
conditionNo疾病或状况,例如:胰腺癌、肺癌、Pancreatic Cancer等
countryNo国家,例如:中国、美国、China、United States等
cityNo城市名称,例如:北京、上海、Beijing等
monthsNo查询过去N个月的临床试验,默认3个月(推荐:3个月内的更有可能还在招募)
statusNo招募状态,默认RECRUITING(招募中)。其他选项:COMPLETED、NOT_YET_RECRUITING等。多个状态用逗号分隔RECRUITING
pageSizeNo每页返回的结果数量,默认30,最大100(推荐:20-30个最相关结果已足够)
pageTokenNo分页令牌,用于获取下一页结果

Implementation Reference

  • src/index.js:38-81 (registration)
    Registration of the 'search_clinical_trials' tool in the ListToolsRequestHandler, including name, description, and detailed inputSchema.
    {
      name: 'search_clinical_trials',
      description: '搜索临床试验。默认查询招募中且过去3个月内更新的试验,按更新时间降序返回30个最相关结果。支持根据关键词(如KRAS-12D)、疾病类型(如胰腺癌)、地理位置(国家/城市)等条件查询。',
      inputSchema: {
        type: 'object',
        properties: {
          keywords: {
            type: 'string',
            description: '关键词,例如:KRAS-12D、PD-1、Pembrolizumab等',
          },
          condition: {
            type: 'string',
            description: '疾病或状况,例如:胰腺癌、肺癌、Pancreatic Cancer等',
          },
          country: {
            type: 'string',
            description: '国家,例如:中国、美国、China、United States等',
          },
          city: {
            type: 'string',
            description: '城市名称,例如:北京、上海、Beijing等',
          },
          months: {
            type: 'number',
            description: '查询过去N个月的临床试验,默认3个月(推荐:3个月内的更有可能还在招募)',
            default: 3,
          },
          status: {
            type: 'string',
            description: '招募状态,默认RECRUITING(招募中)。其他选项:COMPLETED、NOT_YET_RECRUITING等。多个状态用逗号分隔',
            default: 'RECRUITING',
          },
          pageSize: {
            type: 'number',
            description: '每页返回的结果数量,默认30,最大100(推荐:20-30个最相关结果已足够)',
            default: 30,
          },
          pageToken: {
            type: 'string',
            description: '分页令牌,用于获取下一页结果',
          },
        },
      },
    },
  • MCP CallToolRequestHandler switch case that invokes the searchTrials method on the ClinicalTrialsClient with the input arguments and returns the JSON-formatted results.
    case 'search_clinical_trials': {
      const results = await clinicalTrialsClient.searchTrials(args);
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(results, null, 2),
          },
        ],
      };
    }
  • Core implementation of search_clinical_trials: constructs advanced query parameters for ClinicalTrials.gov API v2 /studies endpoint, including filters for keywords, condition, location, recent updates, recruiting status; fetches data with axios, formats results using formatSearchResults, handles errors.
    async searchTrials(params) {
      const {
        keywords,
        condition,
        country,
        city,
        months = 3,  // 默认过去3个月,更符合实际需求
        status = 'RECRUITING',  // 默认只查询招募中的
        pageSize = 30,  // 默认返回30个最相关的结果
        pageToken,
      } = params;
    
      const queryParams = new URLSearchParams();
    
      // 构建查询条件
      const queryParts = [];
    
      // 关键词查询(可以是药物名称、基因突变等)
      if (keywords) {
        queryParts.push(keywords);
      }
    
      // 疾病/状况查询
      if (condition) {
        queryParams.append('query.cond', condition);
      }
    
      // 其他关键词
      if (queryParts.length > 0) {
        queryParams.append('query.term', queryParts.join(' AND '));
      }
    
      // 地理位置过滤
      if (country) {
        queryParams.append('filter.advanced', `AREA[LocationCountry]${country}`);
      }
    
      if (city) {
        // 使用 SEARCH 操作符确保城市和国家在同一位置记录中
        const locationQuery = country 
          ? `SEARCH[Location](AREA[LocationCity]${city} AND AREA[LocationCountry]${country})`
          : `AREA[LocationCity]${city}`;
        
        if (queryParams.has('filter.advanced')) {
          const existing = queryParams.get('filter.advanced');
          queryParams.set('filter.advanced', `${existing} AND ${locationQuery}`);
        } else {
          queryParams.set('filter.advanced', locationQuery);
        }
      }
    
      // 时间范围过滤(过去N个月)
      // 默认3个月内的更新,更有可能还在招募
      const endDate = new Date();
      const startDate = new Date();
      startDate.setMonth(startDate.getMonth() - months);
      
      const startDateStr = this.formatDate(startDate);
      const endDateStr = this.formatDate(endDate);
      
      const dateQuery = `AREA[LastUpdatePostDate]RANGE[${startDateStr},${endDateStr}]`;
      
      if (queryParams.has('filter.advanced')) {
        const existing = queryParams.get('filter.advanced');
        queryParams.set('filter.advanced', `${existing} AND ${dateQuery}`);
      } else {
        queryParams.set('filter.advanced', dateQuery);
      }
    
      // 招募状态过滤(默认只查招募中的)
      queryParams.append('filter.overallStatus', status);
    
      // 分页参数(默认30个,满足大部分需求)
      queryParams.append('pageSize', pageSize.toString());
    
      if (pageToken) {
        queryParams.append('pageToken', pageToken);
      }
    
      // 指定返回字段
      queryParams.append('fields', [
        'NCTId',
        'BriefTitle',
        'OfficialTitle',
        'OverallStatus',
        'Condition',
        'InterventionName',
        'Phase',
        'StudyType',
        'StartDate',
        'PrimaryCompletionDate',
        'CompletionDate',
        'EnrollmentCount',
        'LeadSponsorName',
        'BriefSummary',
        'LocationCity',
        'LocationCountry',
        'LocationStatus',
        'LastUpdatePostDate',
      ].join(','));
    
      // 设置排序(按最近更新时间降序)
      queryParams.append('sort', 'LastUpdatePostDate:desc');
    
      // 计算总数
      queryParams.append('countTotal', 'true');
    
      try {
        const response = await this.axios.get('/studies', {
          params: queryParams,
        });
    
        return this.formatSearchResults(response.data);
      } catch (error) {
        throw this.handleError(error);
      }
    }
  • Helper function to format the raw API response from searchTrials into a structured output with key fields like NCTId, title, status, conditions, interventions, locations, etc.
    formatSearchResults(data) {
      const { studies = [], totalCount = 0, nextPageToken } = data;
    
      const formattedStudies = studies.map(study => {
        const protocol = study.protocolSection || {};
        const identification = protocol.identificationModule || {};
        const status = protocol.statusModule || {};
        const description = protocol.descriptionModule || {};
        const conditions = protocol.conditionsModule || {};
        const design = protocol.designModule || {};
        const arms = protocol.armsInterventionsModule || {};
        const sponsor = protocol.sponsorCollaboratorsModule || {};
        const contacts = protocol.contactsLocationsModule || {};
    
        return {
          nctId: identification.nctId,
          title: identification.briefTitle,
          officialTitle: identification.officialTitle,
          status: status.overallStatus,
          conditions: conditions.conditions || [],
          interventions: arms.interventions?.map(i => ({
            type: i.type,
            name: i.name,
            description: i.description,
          })) || [],
          phase: design.phases || [],
          studyType: design.studyType,
          enrollmentCount: design.enrollmentInfo?.count,
          startDate: status.startDateStruct?.date,
          completionDate: status.completionDateStruct?.date,
          sponsor: sponsor.leadSponsor?.name,
          summary: description.briefSummary,
          locations: contacts.locations?.map(loc => ({
            facility: loc.facility,
            city: loc.city,
            state: loc.state,
            country: loc.country,
            status: loc.status,
            coordinates: loc.geoPoint,
          })) || [],
          lastUpdate: status.lastUpdatePostDateStruct?.date,
        };
      });
    
      return {
        totalCount,
        count: formattedStudies.length,
        nextPageToken,
        studies: formattedStudies,
      };
    }

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/PancrePal-xiaoyibao/xiaoyibao-clinical-trials-mcp-server'

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