Skip to main content
Glama

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
NameRequiredDescriptionDefault
gencodeIdYesGENCODE gene ID (e.g., ENSG00000223972.5)
datasetIdNoGTEx 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()
        }]
      };
    }
  • 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"]
      }
    },
  • 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[]>;
      }
    }

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/Augmented-Nature/GTEx-MCP-Server'

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