Skip to main content
Glama
pdavis68
by pdavis68

search_identifiers

Find code identifiers across project files to locate definitions and references with file paths, line numbers, and surrounding context for code navigation.

Instructions

Search for identifiers in code files. Get back a list of matching identifiers with their file, line number, and context. When searching, just use the identifier name without any special characters, prefixes or suffixes. The search is case-insensitive.

Args: project_root: Root directory of the project to search. (must be an absolute path!) query: Search query (identifier name) max_results: Maximum number of results to return context_lines: Number of lines of context to show include_definitions: Whether to include definition occurrences include_references: Whether to include reference occurrences

Returns: Dictionary containing search results or error message

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_rootYes
queryYes
max_resultsNo
context_linesNo
include_definitionsNo
include_referencesNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The handler function implementing the 'search_identifiers' tool logic. It is registered via the @mcp.tool() decorator. Searches project files for identifier matches using RepoMap to extract tags (defs/refs), filters and sorts them, and provides context snippets.
    @mcp.tool()
    async def search_identifiers(
        project_root: str,
        query: str,
        max_results: int = 50,
        context_lines: int = 2,
        include_definitions: bool = True,
        include_references: bool = True
    ) -> Dict[str, Any]:
        """Search for identifiers in code files. Get back a list of matching identifiers with their file, line number, and context.
           When searching, just use the identifier name without any special characters, prefixes or suffixes. The search is 
           case-insensitive.
    
        Args:
            project_root: Root directory of the project to search.  (must be an absolute path!)
            query: Search query (identifier name)
            max_results: Maximum number of results to return
            context_lines: Number of lines of context to show
            include_definitions: Whether to include definition occurrences
            include_references: Whether to include reference occurrences
        
        Returns:
            Dictionary containing search results or error message
        """
        if not os.path.isdir(project_root):
            return {"error": f"Project root directory not found: {project_root}"}
    
        try:
            # Initialize RepoMap with search-specific settings
            repo_map = RepoMap(
                root=project_root,
                token_counter_func=lambda text: count_tokens(text, "gpt-4"),
                file_reader_func=read_text,
                output_handler_funcs={'info': log.info, 'warning': log.warning, 'error': log.error},
                verbose=False,
                exclude_unranked=True
            )
    
            # Find all source files in the project
            all_files = find_src_files(project_root)
            
            # Get all tags (definitions and references) for all files
            all_tags = []
            for file_path in all_files:
                rel_path = str(Path(file_path).relative_to(project_root))
                tags = repo_map.get_tags(file_path, rel_path)
                all_tags.extend(tags)
    
            # Filter tags based on search query and options
            matching_tags = []
            query_lower = query.lower()
            
            for tag in all_tags:
                if query_lower in tag.name.lower():
                    if (tag.kind == "def" and include_definitions) or \
                       (tag.kind == "ref" and include_references):
                        matching_tags.append(tag)
    
            # Sort by relevance (definitions first, then references)
            matching_tags.sort(key=lambda x: (x.kind != "def", x.name.lower().find(query_lower)))
    
            # Limit results
            matching_tags = matching_tags[:max_results]
    
            # Format results with context
            results = []
            for tag in matching_tags:
                file_path = str(Path(project_root) / tag.rel_fname)
                
                # Calculate context range based on context_lines parameter
                start_line = max(1, tag.line - context_lines)
                end_line = tag.line + context_lines
                context_range = list(range(start_line, end_line + 1))
                
                context = repo_map.render_tree(
                    file_path,
                    tag.rel_fname,
                    context_range
                )
                
                if context:
                    results.append({
                        "file": tag.rel_fname,
                        "line": tag.line,
                        "name": tag.name,
                        "kind": tag.kind,
                        "context": context
                    })
    
            return {"results": results}
    
        except Exception as e:
            log.exception(f"Error searching identifiers in project '{project_root}': {e}")
            return {"error": f"Error searching identifiers: {str(e)}"}    
  • The @mcp.tool() decorator registers the search_identifiers function as an MCP tool.
    @mcp.tool()
  • The function signature and docstring define the input schema (parameters) and output format for the tool, used by FastMCP for validation.
    async def search_identifiers(
        project_root: str,
        query: str,
        max_results: int = 50,
        context_lines: int = 2,
        include_definitions: bool = True,
        include_references: bool = True
    ) -> Dict[str, Any]:
        """Search for identifiers in code files. Get back a list of matching identifiers with their file, line number, and context.
           When searching, just use the identifier name without any special characters, prefixes or suffixes. The search is 
           case-insensitive.
    
        Args:
            project_root: Root directory of the project to search.  (must be an absolute path!)
            query: Search query (identifier name)
            max_results: Maximum number of results to return
            context_lines: Number of lines of context to show
            include_definitions: Whether to include definition occurrences
            include_references: Whether to include reference occurrences
        
        Returns:
            Dictionary containing search results or error message
        """
  • Helper function to find all source files in the project directory, used by search_identifiers to discover files to index.
    def find_src_files(directory: str) -> List[str]:
        if not os.path.isdir(directory):
            return [directory] if os.path.isfile(directory) else []
        src_files = []
        for r, d, f_list in os.walk(directory):
            d[:] = [d_name for d_name in d if not d_name.startswith('.') and d_name not in {'node_modules', '__pycache__', 'venv', 'env'}]
            for f in f_list:
                if not f.startswith('.'):
                    src_files.append(os.path.join(r, f))
        return src_files
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses some behavioral traits: search is case-insensitive, query formatting requirements, and that results include file, line number, and context. However, it doesn't mention performance characteristics, error handling, or other operational details like rate limits or authentication needs.

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 appropriately sized and well-structured with clear sections for purpose, usage notes, arguments, and returns. Each sentence adds value, though the formatting could be slightly more front-loaded by moving the 'Args' explanation closer to the beginning.

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

Completeness4/5

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

Given the tool's moderate complexity (6 parameters, no annotations, but with output schema), the description is reasonably complete. It explains the purpose, parameters, and return format. The presence of an output schema means the description doesn't need to detail return values, which it correctly avoids. Some behavioral context could be added, but overall it's adequate.

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

Parameters4/5

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

With 0% schema description coverage, the description compensates well by explaining all 6 parameters in the 'Args' section, adding meaning beyond the bare schema. It clarifies that 'project_root' must be an absolute path and explains what each boolean parameter controls. The description provides essential semantic context that the schema lacks.

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

Purpose5/5

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

The description clearly states the tool searches for identifiers in code files and returns matching identifiers with file, line number, and context. It specifies the resource (identifiers in code files) and verb (search), distinguishing it from the sibling 'repo_map' tool which likely provides a different functionality.

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 some usage guidance about how to format the search query (identifier name without special characters, case-insensitive), but it doesn't specify when to use this tool versus alternatives or mention the sibling 'repo_map' tool. There's no explicit guidance on use cases or exclusions.

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/pdavis68/RepoMapper'

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