get_gene_expression
Retrieve gene expression data across 54 human tissue types from GTEx datasets to analyze tissue-specific gene activity using GENCODE gene IDs.
Instructions
Get gene expression data across tissues for a specific gene
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| gencodeId | Yes | GENCODE gene ID (e.g., ENSG00000223972.5) | |
| datasetId | No | GTEx dataset ID (default: gtex_v8) | gtex_v8 |
Implementation Reference
- Core handler function for get_gene_expression tool. Validates input geneIds, fetches data via API client, groups results by gene/tissue, computes statistics (mean, median, range, detection rate), formats comprehensive markdown summary with pagination notes.async getGeneExpression(args: any) { if (!args.geneIds || !Array.isArray(args.geneIds) || args.geneIds.length === 0) { throw new Error('geneIds parameter is required and must be a non-empty array of gene IDs (GENCODE IDs or gene symbols)'); } if (args.geneIds.length > 60) { return { content: [{ type: "text", text: "Maximum 60 genes can be processed at once. Please reduce the number of genes." }] }; } const result = await this.apiClient.getGeneExpression({ gencodeId: args.geneIds, datasetId: args.datasetId || 'gtex_v8', tissueSiteDetailId: args.tissueIds, attributeSubset: args.attributeSubset, page: args.page || 0, itemsPerPage: args.itemsPerPage || 250 }); if (result.error) { return { content: [{ type: "text", text: `Error retrieving gene expression data: ${result.error}` }], isError: true }; } const expressions = result.data || []; if (expressions.length === 0) { return { content: [{ type: "text", text: `No gene expression data found for the specified genes and tissues.${args.tissueIds ? ` Check that tissue IDs are valid: ${args.tissueIds.join(', ')}` : ''}` }] }; } // Group by gene and tissue for better organization const geneGroups: { [key: string]: any[] } = {}; expressions.forEach(expr => { const key = `${expr.geneSymbol} (${expr.gencodeId})`; if (!geneGroups[key]) { geneGroups[key] = []; } geneGroups[key].push(expr); }); let output = `**Gene Expression Data (${expressions.length} results)**\n`; output += `Dataset: ${expressions[0]?.datasetId || args.datasetId}\n`; if (args.attributeSubset) { output += `Subset by: ${args.attributeSubset}\n`; } output += '\n'; Object.entries(geneGroups).forEach(([geneKey, geneExpressions]) => { output += `### ${geneKey}\n`; geneExpressions.forEach(expr => { const tissueDisplayName = this.getTissueDisplayName(expr.tissueSiteDetailId); output += `**${tissueDisplayName}**${expr.subsetGroup ? ` (${expr.subsetGroup})` : ''}:\n`; const stats = this.calculateExpressionStats(expr.data); output += ` • Samples: ${expr.data.length}\n`; output += ` • Mean: ${stats.mean.toFixed(3)} ${expr.unit}\n`; output += ` • Median: ${stats.median.toFixed(3)} ${expr.unit}\n`; output += ` • Range: ${stats.min.toFixed(3)} - ${stats.max.toFixed(3)} ${expr.unit}\n`; output += ` • Non-zero samples: ${stats.nonZeroCount} (${stats.nonZeroPercent.toFixed(1)}%)\n\n`; }); }); if (result.paging_info && result.paging_info.totalNumberOfItems > expressions.length) { output += `**Note:** Showing ${expressions.length} of ${result.paging_info.totalNumberOfItems} total results. `; output += `Use page parameter to retrieve additional results.\n`; } return { content: [{ type: "text", text: output.trim() }] }; }
- src/types/gtex-types.ts:393-400 (schema)Type definition for GetGeneExpressionParams used by the API client and handler for input validation and typing.export interface GetGeneExpressionParams { gencodeId: string[]; datasetId?: string; tissueSiteDetailId?: string[]; attributeSubset?: string; page?: number; itemsPerPage?: number; }
- src/index.ts:625-630 (registration)Tool dispatch/registration in main CallToolRequestSchema handler: maps tool name to expressionHandlers.getGeneExpression call, adapting singular gencodeId to plural geneIds.if (name === "get_gene_expression") { return await expressionHandlers.getGeneExpression({ geneIds: args?.gencodeId ? [args.gencodeId] : [], datasetId: args?.datasetId }); }
- src/index.ts:54-71 (registration)Tool registration in ListToolsRequestSchema: defines name, description, and simplified inputSchema (single gencodeId).name: "get_gene_expression", description: "Get gene expression data across tissues for a specific gene", inputSchema: { type: "object", properties: { gencodeId: { type: "string", description: "GENCODE gene ID (e.g., ENSG00000223972.5)" }, datasetId: { type: "string", description: "GTEx dataset ID (default: gtex_v8)", default: "gtex_v8" } }, required: ["gencodeId"] } },
- src/utils/api-client.ts:279-297 (helper)API client helper method that makes HTTP request to GTEx Portal /expression/geneExpression endpoint, handles query params and error formatting.async getGeneExpression(params: GetGeneExpressionParams): Promise<GTExApiResponse<GeneExpression[]>> { try { const queryParams = this.buildQueryParams({ gencodeId: params.gencodeId, datasetId: params.datasetId || 'gtex_v8', tissueSiteDetailId: params.tissueSiteDetailId, attributeSubset: params.attributeSubset, page: params.page || 0, itemsPerPage: params.itemsPerPage || 250 }); const response = await this.axiosInstance.get(`/expression/geneExpression?${queryParams}`); return { data: response.data.data, paging_info: response.data.paging_info }; } catch (error) { return error as GTExApiResponse<GeneExpression[]>; } }