search_clinical_trials
Search for actively recruiting clinical trials by condition, location, or keywords to find relevant medical studies for patients or researchers.
Instructions
搜索临床试验。默认查询招募中且过去3个月内更新的试验,按更新时间降序返回30个最相关结果。支持根据关键词(如KRAS-12D)、疾病类型(如胰腺癌)、地理位置(国家/城市)等条件查询。
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | No | 关键词,例如:KRAS-12D、PD-1、Pembrolizumab等 | |
| condition | No | 疾病或状况,例如:胰腺癌、肺癌、Pancreatic Cancer等 | |
| country | No | 国家,例如:中国、美国、China、United States等 | |
| city | No | 城市名称,例如:北京、上海、Beijing等 | |
| months | No | 查询过去N个月的临床试验,默认3个月(推荐:3个月内的更有可能还在招募) | |
| status | No | 招募状态,默认RECRUITING(招募中)。其他选项:COMPLETED、NOT_YET_RECRUITING等。多个状态用逗号分隔 | RECRUITING |
| pageSize | No | 每页返回的结果数量,默认30,最大100(推荐:20-30个最相关结果已足够) | |
| pageToken | No | 分页令牌,用于获取下一页结果 |
Implementation Reference
- src/clinical-trials-client.js:26-142 (handler)The main handler function `searchTrials` in ClinicalTrialsClient class that implements the core logic for searching clinical trials. It constructs advanced filters for keywords, condition, location (country/city), recency (default 3 months), status (default RECRUITING), fetches from ClinicalTrials.gov API v2 /studies endpoint, sorts by last update descending, limits to pageSize (default 30), and formats the results using `formatSearchResults`.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); } }
- src/index.js:41-80 (schema)Input schema for the 'search_clinical_trials' tool, defining parameters like keywords, condition, country, city, months (default 3), status (default 'RECRUITING'), pageSize (default 30), and pageToken.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: '分页令牌,用于获取下一页结果', }, }, },
- src/index.js:38-81 (registration)Tool registration in the ListToolsRequestSchema handler, including name, description, and inputSchema for 'search_clinical_trials'.{ 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: '分页令牌,用于获取下一页结果', }, }, }, },
- src/index.js:154-165 (registration)Registration of the tool handler in the CallToolRequestSchema switch statement: delegates to clinicalTrialsClient.searchTrials and returns JSON stringified results.case 'search_clinical_trials': { const results = await clinicalTrialsClient.searchTrials(args); return { content: [ { type: 'text', text: JSON.stringify(results, null, 2), }, ], }; }
- Helper function `formatSearchResults` used by searchTrials to parse and structure the API response into a clean format with study details, 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, }; }