Skip to main content
Glama
cyanheads

ClinicalTrials.gov MCP Server

clinicaltrials_search_studies

Search and filter clinical studies by conditions, interventions, locations, statuses, or IDs. Retrieve sorted, paginated results with specific fields for targeted research on ClinicalTrials.gov.

Instructions

Searches for clinical studies using a combination of query terms and filters. Supports pagination, sorting, and geographic filtering.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fieldsNoA list of specific top-level fields to include in the response.
filterNoA set of filters that narrow the search results without affecting ranking.
pageSizeNoThe number of studies to return per page (1-200). Defaults to 10.
pageTokenNoA token used to retrieve the next page of results.
queryNoA set of search terms that influence result ranking.
sortNoSpecify the sort order for the results.

Implementation Reference

  • The core handler function `searchStudiesLogic` that executes the tool's business logic. It resolves the `ClinicalTrialsProvider` from the DI container and calls `listStudies` with mapped input parameters for querying clinical trials, handling pagination, filters, and sorting.
    async function searchStudiesLogic( input: SearchStudiesInput, appContext: RequestContext, _sdkContext: SdkContext, ): Promise<SearchStudiesOutput> { logger.debug('Executing searchStudiesLogic', { ...appContext, toolInput: input, }); const provider = container.resolve<IClinicalTrialsProvider>( ClinicalTrialsProvider, ); const pagedStudies = await provider.listStudies( { ...(input.query && { query: input.query }), ...(input.filter && { filter: input.filter }), pageSize: input.pageSize, ...(input.pageToken && { pageToken: input.pageToken }), ...(input.sort && { sort: input.sort }), ...(input.fields && { fields: input.fields }), ...(input.country && { country: input.country }), ...(input.state && { state: input.state }), ...(input.city && { city: input.city }), }, appContext, ); logger.info( `Successfully searched studies: ${pagedStudies.studies?.length ?? 0} results`, { ...appContext, totalCount: pagedStudies.totalCount, }, ); return { pagedStudies }; }
  • Zod schemas defining the structured input (query, filter, pagination, sorting, location filters) and output (pagedStudies using imported PagedStudiesSchema) for the tool.
    const InputSchema = z .object({ query: z .string() .optional() .describe( 'General search query for conditions, interventions, sponsors, or other terms.', ), filter: z .string() .optional() .describe( 'Advanced filter expression using the ClinicalTrials.gov filter syntax.', ), pageSize: z .number() .int() .min(1) .max(200) .default(10) .describe( 'Number of studies to return per page (1-200). Defaults to 10.', ), pageToken: z .string() .optional() .describe('Token for retrieving the next page of results.'), sort: z .string() .optional() .describe( 'Sort order specification (e.g., "LastUpdateDate:desc", "EnrollmentCount").', ), fields: z .array(z.string()) .optional() .describe( 'Specific fields to return (reduces payload size). Example: ["NCTId", "BriefTitle", "OverallStatus"].', ), country: z .string() .optional() .describe('Filter studies by country (e.g., "United States", "Canada").'), state: z .string() .optional() .describe( 'Filter studies by state or province (e.g., "California", "Ontario").', ), city: z .string() .optional() .describe('Filter studies by city (e.g., "New York", "Toronto").'), }) .describe('Input parameters for searching clinical trial studies.'); const OutputSchema = z.object({ pagedStudies: PagedStudiesSchema, }); type SearchStudiesInput = z.infer<typeof InputSchema>;
  • Exports the `searchStudiesTool` ToolDefinition object, wiring together the name, schemas, annotations, auth-wrapped handler logic, and response formatter for use in registration.
    export const searchStudiesTool: ToolDefinition< typeof InputSchema, typeof OutputSchema > = { name: TOOL_NAME, title: TOOL_TITLE, description: TOOL_DESCRIPTION, inputSchema: InputSchema, outputSchema: OutputSchema, annotations: TOOL_ANNOTATIONS, logic: withToolAuth(['tool:clinicaltrials:read'], searchStudiesLogic), responseFormatter, };
  • Barrel export file that imports `searchStudiesTool` and includes it in the `allToolDefinitions` array, enabling bulk registration of all tools.
    import { analyzeTrendsTool } from './clinicaltrials-analyze-trends.tool.js'; import { compareStudiesTool } from './clinicaltrials-compare-studies.tool.js'; import { findEligibleStudiesTool } from './clinicaltrials-find-eligible-studies.tool.js'; import { getStudyTool } from './clinicaltrials-get-study.tool.js'; import { searchStudiesTool } from './clinicaltrials-search-studies.tool.js'; /** * An array containing all tool definitions for easy iteration. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export const allToolDefinitions: any[] = [ analyzeTrendsTool, compareStudiesTool, findEligibleStudiesTool, getStudyTool, searchStudiesTool, ];
  • The `registerTools` function iterates over `allToolDefinitions` (including the clinicaltrials_search_studies tool) and registers each into the DI container as `ToolDefinitions`, which the `ToolRegistry` uses to call `server.registerTool` on the MCP server.
    /** * Registers all tool definitions with the provided dependency container. * This function uses multi-injection to register each tool under the `ToolDefinitions` token. * * @param {DependencyContainer} container - The tsyringe container instance to register tools with. */ export const registerTools = (container: DependencyContainer): void => { for (const tool of allToolDefinitions) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment container.register(ToolDefinitions, { useValue: tool }); } };

Other Tools

Related Tools

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/cyanheads/clinicaltrialsgov-mcp-server'

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