Skip to main content
Glama

find_symbol

Locate function, class, variable, and type definitions within project code to quickly find symbol implementations and references.

Instructions

함수 찾아|클래스 어디|변수 위치|find function|where is|locate - Find symbol definitions

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
symbolNameYesName of the symbol to find
projectPathYesProject directory path
symbolTypeNoType of symbol to search for

Implementation Reference

  • Main execution logic for the 'find_symbol' tool. Parses TypeScript files using ts-morph and Python files using PythonParser, finds matching symbols by name and type, collects locations, sorts by exact match, and returns formatted results.
    export async function findSymbol(args: { 
      symbolName: string; 
      projectPath: string; 
      symbolType?: string 
    }): Promise<ToolResult> {
      const { symbolName, projectPath, symbolType = 'all' } = args;
      
      try {
        // Use cached project for performance
        const projectCache = ProjectCache.getInstance();
        const project = projectCache.getOrCreate(projectPath);
    
        const symbols: SymbolInfo[] = [];
    
        // Check for Python files
        const glob = await import('glob');
        const pythonFiles = glob.globSync(path.join(projectPath, '**/*.py'), {
          ignore: ['**/node_modules/**', '**/.git/**', '**/venv/**', '**/__pycache__/**']
        });
    
        // Parse Python files
        for (const pyFile of pythonFiles) {
          try {
            const content = await readFile(pyFile, 'utf-8');
            const pythonSymbols = await PythonParser.findSymbols(content);
    
            for (const pySymbol of pythonSymbols) {
              if (pySymbol.name.includes(symbolName) &&
                  (symbolType === 'all' || symbolType === pySymbol.kind)) {
                symbols.push({
                  name: pySymbol.name,
                  kind: pySymbol.kind,
                  filePath: pyFile,
                  line: pySymbol.line,
                  column: pySymbol.column,
                  preview: pySymbol.docstring?.substring(0, 100) || `${pySymbol.kind} ${pySymbol.name}`
                });
              }
            }
          } catch (error) {
            // Skip files that can't be parsed
            console.error(`Error parsing Python file ${pyFile}:`, error);
          }
        }
    
        // Search through all source files
        for (const sourceFile of project.getSourceFiles()) {
          const filePath = sourceFile.getFilePath();
          
          // Skip node_modules and other irrelevant paths
          if (filePath.includes('node_modules') || filePath.includes('.git')) {
            continue;
          }
          
          // Find matching symbols based on type
          sourceFile.forEachDescendant((node) => {
            const nodeSymbol = extractSymbolInfo(node, symbolName, symbolType);
            if (nodeSymbol) {
              const start = node.getStartLinePos();
              const pos = sourceFile.getLineAndColumnAtPos(start);
              
              symbols.push({
                name: nodeSymbol.name,
                kind: nodeSymbol.kind,
                filePath: filePath,
                line: pos.line,
                column: pos.column,
                preview: node.getText().substring(0, 100)
              });
            }
          });
        }
        
        // Sort by relevance (exact matches first)
        symbols.sort((a, b) => {
          const aExact = a.name === symbolName ? 0 : 1;
          const bExact = b.name === symbolName ? 0 : 1;
          return aExact - bExact;
        });
        
        return {
          content: [{
            type: 'text',
            text: `Found ${symbols.length} symbols:\n${symbols.slice(0, 20).map(s =>
              `${s.name} (${s.kind}) - ${s.filePath}:${s.line}`
            ).join('\n')}`
          }]
        };
      } catch (error) {
        return {
          content: [{ 
            type: 'text', 
            text: `Error finding symbol: ${error instanceof Error ? error.message : 'Unknown error'}` 
          }]
        };
      }
    }
  • ToolDefinition object defining the input schema, description, and annotations for the 'find_symbol' tool.
    export const findSymbolDefinition: ToolDefinition = {
      name: 'find_symbol',
      description: '함수 찾아|클래스 어디|변수 위치|find function|where is|locate - Find symbol definitions',
      inputSchema: {
        type: 'object',
        properties: {
          symbolName: { type: 'string', description: 'Name of the symbol to find' },
          projectPath: { type: 'string', description: 'Project directory path' },
          symbolType: {
            type: 'string',
            enum: ['all', 'function', 'class', 'interface', 'variable', 'type'],
            description: 'Type of symbol to search for'
          }
        },
        required: ['symbolName', 'projectPath']
      },
      annotations: {
        title: 'Find Symbol',
        audience: ['user', 'assistant'],
        readOnlyHint: true,
        destructiveHint: false,
        idempotentHint: true,
        openWorldHint: false
      }
    };
  • src/index.ts:177-181 (registration)
    Registration of the 'find_symbol' handler in the toolHandlers map used for dynamic tool dispatch.
    // Code Analysis
    'find_symbol': findSymbol,
    'find_references': findReferences,
    'analyze_dependency_graph': analyzeDependencyGraph,
  • src/index.ts:110-112 (registration)
    Inclusion of the findSymbolDefinition (schema) in the tools array provided via ListToolsRequest.
    // Code Analysis - Semantic (2)
    findSymbolDefinition,
    findReferencesDefinition,
  • Helper function that inspects TypeScript AST nodes to identify and classify symbols matching the search criteria.
    function extractSymbolInfo(
      node: Node, 
      symbolName: string, 
      symbolType: string
    ): { name: string; kind: string } | null {
      const kind = node.getKind();
      
      // Function declarations and expressions
      if (symbolType === 'all' || symbolType === 'function') {
        if (Node.isFunctionDeclaration(node) || Node.isMethodDeclaration(node)) {
          const name = node.getName();
          if (name && name.includes(symbolName)) {
            return { name, kind: 'function' };
          }
        }
        if (Node.isVariableDeclaration(node)) {
          const name = node.getName();
          const initializer = node.getInitializer();
          if (name && name.includes(symbolName) && 
              (Node.isArrowFunction(initializer) || Node.isFunctionExpression(initializer))) {
            return { name, kind: 'function' };
          }
        }
      }
      
      // Class declarations
      if (symbolType === 'all' || symbolType === 'class') {
        if (Node.isClassDeclaration(node)) {
          const name = node.getName();
          if (name && name.includes(symbolName)) {
            return { name, kind: 'class' };
          }
        }
      }
      
      // Interface declarations
      if (symbolType === 'all' || symbolType === 'interface') {
        if (Node.isInterfaceDeclaration(node)) {
          const name = node.getName();
          if (name && name.includes(symbolName)) {
            return { name, kind: 'interface' };
          }
        }
      }
      
      // Type aliases
      if (symbolType === 'all' || symbolType === 'type') {
        if (Node.isTypeAliasDeclaration(node)) {
          const name = node.getName();
          if (name && name.includes(symbolName)) {
            return { name, kind: 'type' };
          }
        }
      }
      
      // Variables
      if (symbolType === 'all' || symbolType === 'variable') {
        if (Node.isVariableDeclaration(node)) {
          const name = node.getName();
          const initializer = node.getInitializer();
          if (name && name.includes(symbolName) && 
              !Node.isArrowFunction(initializer) && !Node.isFunctionExpression(initializer)) {
            return { name, kind: 'variable' };
          }
        }
      }
      
      return null;
    }

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/su-record/hi-ai'

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