Skip to main content
Glama

get_eqtl_genes

Identify genes with expression quantitative trait loci (eQTL) associations for a specific genomic region using GTEx data. Optionally filter results by tissue type to analyze gene expression regulation.

Instructions

Get genes with eQTL associations for a genomic region

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chrYesChromosome (e.g., chr1, chr2, chrX)
startYesStart position (1-based)
endYesEnd position (1-based)
tissueSiteDetailIdNoTissue site detail ID (optional, for tissue-specific results)
datasetIdNoGTEx dataset ID (default: gtex_v8)gtex_v8

Implementation Reference

  • The main handler function for the 'get_eqtl_genes' tool. It calls the API client to fetch eQTL genes, handles errors, groups results by tissue, sorts by significance, formats a detailed markdown output with top genes, statistics, and summaries per tissue.
    async getEQTLGenes(args: any) {
      const result = await this.apiClient.getEQTLGenes({
        tissueSiteDetailId: args.tissueIds,
        datasetId: args.datasetId || 'gtex_v8',
        page: args.page || 0,
        itemsPerPage: args.itemsPerPage || 250
      });
    
      if (result.error) {
        return {
          content: [{
            type: "text",
            text: `Error retrieving eQTL genes: ${result.error}`
          }],
          isError: true
        };
      }
    
      const eqtlGenes = result.data || [];
      if (eqtlGenes.length === 0) {
        return {
          content: [{
            type: "text",
            text: `No eQTL genes found${args.tissueIds ? ` for tissues: ${args.tissueIds.join(', ')}` : ''}`
          }]
        };
      }
    
      // Group by tissue for better organization
      const tissueGroups: { [key: string]: any[] } = {};
      eqtlGenes.forEach(gene => {
        if (!tissueGroups[gene.tissueSiteDetailId]) {
          tissueGroups[gene.tissueSiteDetailId] = [];
        }
        tissueGroups[gene.tissueSiteDetailId].push(gene);
      });
    
      let output = `**eQTL Genes (${eqtlGenes.length} results)**\n`;
      output += `Dataset: ${eqtlGenes[0]?.datasetId}\n`;
      output += `Tissues: ${Object.keys(tissueGroups).length}\n\n`;
    
      Object.entries(tissueGroups).forEach(([tissueId, genes]) => {
        const tissueDisplayName = this.getTissueDisplayName(tissueId);
        output += `### ${tissueDisplayName} (${genes.length} eGenes)\n`;
    
        // Sort by significance (lowest q-value first)
        const sortedGenes = genes.sort((a, b) => a.qValue - b.qValue);
        
        // Show top significant genes
        const topCount = Math.min(10, sortedGenes.length);
        sortedGenes.slice(0, topCount).forEach((gene, index) => {
          output += `${(index + 1).toString().padStart(2)}. **${gene.geneSymbol}** (${gene.gencodeId})\n`;
          output += `    • p-value: ${gene.pValue.toExponential(2)}\n`;
          output += `    • q-value: ${gene.qValue.toFixed(4)}\n`;
          output += `    • Empirical p-value: ${gene.empiricalPValue.toExponential(2)}\n`;
          output += `    • Log2 allelic fold change: ${gene.log2AllelicFoldChange.toFixed(3)}\n`;
          output += `    • p-value threshold: ${gene.pValueThreshold.toExponential(2)}\n`;
        });
    
        if (sortedGenes.length > topCount) {
          output += `    ... and ${sortedGenes.length - topCount} more eGenes\n`;
        }
    
        // Statistics for this tissue
        const qValues = sortedGenes.map(g => g.qValue);
        const foldChanges = sortedGenes.map(g => Math.abs(g.log2AllelicFoldChange));
        
        output += `\n**Tissue Summary:**\n`;
        output += `  • Total eGenes: ${genes.length}\n`;
        output += `  • Most significant q-value: ${Math.min(...qValues).toExponential(2)}\n`;
        output += `  • Mean |fold change|: ${(foldChanges.reduce((sum, fc) => sum + fc, 0) / foldChanges.length).toFixed(3)}\n`;
        output += `  • Max |fold change|: ${Math.max(...foldChanges).toFixed(3)}\n\n`;
      });
    
      if (result.paging_info && result.paging_info.totalNumberOfItems > eqtlGenes.length) {
        output += `**Note:** Showing ${eqtlGenes.length} of ${result.paging_info.totalNumberOfItems} total results.\n`;
      }
    
      return {
        content: [{
          type: "text",
          text: output.trim()
        }]
      };
    }
  • src/index.ts:219-247 (registration)
    Tool registration in the ListToolsRequestSchema handler, defining the tool name, description, and input schema.
    name: "get_eqtl_genes",
    description: "Get genes with eQTL associations for a genomic region",
    inputSchema: {
      type: "object",
      properties: {
        chr: {
          type: "string",
          description: "Chromosome (e.g., chr1, chr2, chrX)"
        },
        start: {
          type: "integer",
          description: "Start position (1-based)"
        },
        end: {
          type: "integer", 
          description: "End position (1-based)"
        },
        tissueSiteDetailId: {
          type: "string",
          description: "Tissue site detail ID (optional, for tissue-specific results)"
        },
        datasetId: {
          type: "string",
          description: "GTEx dataset ID (default: gtex_v8)",
          default: "gtex_v8"
        }
      },
      required: ["chr", "start", "end"]
    }
  • src/index.ts:672-676 (registration)
    Dispatch registration in the CallToolRequestSchema handler, mapping tool calls to the associationHandlers.getEQTLGenes method.
    if (name === "get_eqtl_genes") {
      return await associationHandlers.getEQTLGenes({
        tissueIds: args?.tissueSiteDetailId ? [args.tissueSiteDetailId] : undefined,
        datasetId: args?.datasetId
      });
  • TypeScript interface defining the input parameters for the getEQTLGenes API call, used by the API client and handler.
    export interface GetEQTLGenesParams {
      tissueSiteDetailId?: string[];
      datasetId?: string;
      page?: number;
      itemsPerPage?: number;
    }
  • API client helper method that makes the HTTP request to GTEx Portal API for eQTL genes data, used by the main handler.
    async getEQTLGenes(params: GetEQTLGenesParams): Promise<GTExApiResponse<EQTLGene[]>> {
      try {
        const queryParams = this.buildQueryParams({
          tissueSiteDetailId: params.tissueSiteDetailId,
          datasetId: params.datasetId || 'gtex_v8',
          page: params.page || 0,
          itemsPerPage: params.itemsPerPage || 250
        });
        const response = await this.axiosInstance.get(`/association/egene?${queryParams}`);
        return { 
          data: response.data.data,
          paging_info: response.data.paging_info
        };
      } catch (error) {
        return error as GTExApiResponse<EQTLGene[]>;
      }
    }

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