Skip to main content
Glama
geneontology

Noctua MCP Server

Official
by geneontology

search_annotations

Find Gene Ontology annotations with evidence by filtering proteins, GO terms, organisms, evidence types, and sources to support biological research.

Instructions

Search for GO annotations (evidence) with filtering.

Args: bioentity: Specific bioentity ID to filter by (e.g., "UniProtKB:P12345") go_term: Specific GO term ID to filter by (e.g., "GO:0008150") evidence_types: Comma-separated evidence codes (e.g., "IDA,IPI,IMP") taxon: Organism filter - accepts numeric (9606) or full ID (NCBITaxon:9606) aspect: GO aspect filter - "C" (cellular component), "F" (molecular function), or "P" (biological process) assigned_by: Annotation source filter (e.g., "GOC", "UniProtKB", "MGI") limit: Maximum number of results (default: 10, max: 1000)

Returns: Dictionary containing: - annotations: List of annotation results with evidence details - total: Number of results returned

Examples: # Find all evidence for a specific protein search_annotations(bioentity="UniProtKB:P53762")

# Find proteins with experimental evidence for a GO term
search_annotations(go_term="GO:0005634", evidence_types="IDA,IPI")

# Find human proteins in nucleus with experimental evidence
search_annotations(
    go_term="GO:0005634",
    taxon="9606",
    evidence_types="IDA,IPI,IMP",
    aspect="C"
)

# Find all UniProt annotations for apoptosis
search_annotations(
    go_term="GO:0006915",
    assigned_by="UniProtKB"
)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bioentityNo
go_termNo
evidence_typesNo
taxonNo
aspectNo
assigned_byNo
limitNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler function for the 'search_annotations' MCP tool. It normalizes inputs, calls AmigoClient.search_annotations, formats the results into a structured dictionary, and handles errors.
    @mcp.tool()
    async def search_annotations(
        bioentity: Optional[str] = None,
        go_term: Optional[str] = None,
        evidence_types: Optional[str] = None,
        taxon: Optional[str] = None,
        aspect: Optional[str] = None,
        assigned_by: Optional[str] = None,
        limit: int = 10
    ) -> Dict[str, Any]:
        """
        Search for GO annotations (evidence) with filtering.
    
        Args:
            bioentity: Specific bioentity ID to filter by (e.g., "UniProtKB:P12345")
            go_term: Specific GO term ID to filter by (e.g., "GO:0008150")
            evidence_types: Comma-separated evidence codes (e.g., "IDA,IPI,IMP")
            taxon: Organism filter - accepts numeric (9606) or full ID (NCBITaxon:9606)
            aspect: GO aspect filter - "C" (cellular component), "F" (molecular function), or "P" (biological process)
            assigned_by: Annotation source filter (e.g., "GOC", "UniProtKB", "MGI")
            limit: Maximum number of results (default: 10, max: 1000)
    
        Returns:
            Dictionary containing:
            - annotations: List of annotation results with evidence details
            - total: Number of results returned
    
        Examples:
            # Find all evidence for a specific protein
            search_annotations(bioentity="UniProtKB:P53762")
    
            # Find proteins with experimental evidence for a GO term
            search_annotations(go_term="GO:0005634", evidence_types="IDA,IPI")
    
            # Find human proteins in nucleus with experimental evidence
            search_annotations(
                go_term="GO:0005634",
                taxon="9606",
                evidence_types="IDA,IPI,IMP",
                aspect="C"
            )
    
            # Find all UniProt annotations for apoptosis
            search_annotations(
                go_term="GO:0006915",
                assigned_by="UniProtKB"
            )
        """
        # Normalize taxon ID
        if taxon and not taxon.startswith("NCBITaxon:"):
            if taxon.isdigit():
                taxon = f"NCBITaxon:{taxon}"
    
        # Parse evidence types
        evidence_list = None
        if evidence_types:
            evidence_list = [e.strip() for e in evidence_types.split(",")]
    
        # Limit bounds
        limit = min(max(1, limit), 1000)
    
        try:
            with AmigoClient() as client:
                results = client.search_annotations(
                    bioentity=bioentity,
                    go_term=go_term,
                    evidence_types=evidence_list,
                    taxon=taxon,
                    aspect=aspect,
                    assigned_by=assigned_by,
                    limit=limit
                )
    
                return {
                    "annotations": [
                        {
                            "bioentity": r.bioentity,
                            "bioentity_label": r.bioentity_label,
                            "bioentity_name": r.bioentity_name,
                            "go_term": r.annotation_class,
                            "go_term_label": r.annotation_class_label,
                            "aspect": r.aspect,
                            "evidence_type": r.evidence_type,
                            "evidence": r.evidence,
                            "evidence_label": r.evidence_label,
                            "reference": r.reference,
                            "assigned_by": r.assigned_by,
                            "date": r.date,
                            "taxon": r.taxon,
                            "taxon_label": r.taxon_label,
                            "qualifier": r.qualifier,
                            "annotation_extension": r.annotation_extension
                        }
                        for r in results
                    ],
                    "total": len(results)
                }
    
        except Exception as e:
            return {
                "error": "Failed to search annotations",
                "message": str(e)
            }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It effectively describes the tool's behavior: it's a search/filter operation (implied read-only), specifies default and max limits ('default: 10, max: 1000'), and details the return structure. However, it doesn't mention potential side effects, authentication needs, or rate limits, which could be relevant for a search tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (Args, Returns, Examples) and front-loads the core purpose. However, it's somewhat lengthy due to comprehensive parameter documentation and multiple examples. Every sentence adds value, but some redundancy exists in the examples that could be condensed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (7 parameters, 0% schema coverage, no annotations) and the presence of an output schema, the description is highly complete. It thoroughly documents all parameters with examples, specifies the return structure, and provides multiple usage scenarios. The output schema means the description doesn't need to explain return values in detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage and 7 parameters, the description must fully compensate, which it does excellently. Each parameter is clearly explained with examples and acceptable values (e.g., 'aspect' with 'C', 'F', or 'P'), going far beyond what the bare schema provides. The examples demonstrate practical usage patterns for multiple parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Search for GO annotations (evidence) with filtering.' This specifies the verb ('search'), resource ('GO annotations/evidence'), and scope ('with filtering'). However, it doesn't explicitly differentiate from sibling tools like 'get_annotations_for_bioentity' or 'search_bioentities,' which prevents a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With sibling tools like 'get_annotations_for_bioentity' and 'search_bioentities' available, there's no indication of how this search differs or when it's preferred. The examples show usage patterns but don't address tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/geneontology/noctua-mcp'

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