find_references
Locate all references to a TypeScript/JavaScript symbol in your codebase by specifying the root directory, file path, line number, and symbol name.
Instructions
Find all references to a TypeScript/JavaScript symbol across the codebase
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | File path containing the symbol (relative to root) | |
| line | Yes | Line number (1-based) or string to match in the line | |
| root | Yes | Root directory for resolving relative paths | |
| symbolName | Yes | Name of the symbol to find references for |
Implementation Reference
- src/tools/lsp/references.ts:191-211 (handler)Main handler function that executes the LSP references tool logic, formats output, and handles errors.execute: async (args: z.infer<typeof schema>) => { const result = await findReferencesWithLSP(args, client); if (result.isOk()) { const messages = [result.value.message]; if (result.value.references.length > 0) { messages.push( result.value.references .map( (ref) => `\n${ref.relativePath}:${ref.line}:${ref.column}\n${ref.preview}`, ) .join("\n"), ); } return messages.join("\n\n"); } else { throw new Error(result.error); } },
- src/tools/lsp/references.ts:23-36 (schema)Zod schema defining input parameters for the find references tool.const schema = z.object({ root: z.string().describe("Root directory for resolving relative paths"), relativePath: z .string() .describe("File path containing the symbol (relative to root)"), line: z .union([z.number(), z.string()]) .describe("Line number (1-based) or string to match in the line"), column: z .number() .optional() .describe("Character position in the line (0-based)"), symbolName: z.string().describe("Name of the symbol to find references for"), });
- src/tools/lsp/createLspTools.ts:29-29 (registration)Registration of the references tool in the createLSPTools factory function.createReferencesTool(client),
- src/tools/lsp/references.ts:56-171 (helper)Core helper function that performs LSP findReferences operation, validates input, reads files, processes locations.async function findReferencesWithLSP( request: FindReferencesRequest, client: LSPClient, ): Promise<Result<FindReferencesSuccess, string>> { try { if (!client) { return err("LSP client not available"); } // Read file content with metadata let fileContent: string; let fileUri: string; try { const result = readFileWithMetadata(request.root, request.relativePath); fileContent = result.fileContent; fileUri = result.fileUri; } catch (error) { const context: ErrorContext = { operation: "find references", filePath: request.relativePath, language: "lsp", }; return err(formatError(error, context)); } // Validate line and symbol let targetLine: number; let symbolPosition: number; try { const result = validateLineAndSymbol( fileContent, request.line, request.symbolName, request.relativePath, ); targetLine = result.lineIndex; symbolPosition = result.symbolIndex; } catch (error) { const context: ErrorContext = { operation: "symbol validation", filePath: request.relativePath, symbolName: request.symbolName, details: { line: request.line }, }; return err(formatError(error, context)); } // Open document in LSP client.openDocument(fileUri, fileContent); // Give LSP server time to process the document await new Promise<void>((resolve) => setTimeout(resolve, 1000)); // Find references const locations = await client.findReferences(fileUri, { line: targetLine, character: symbolPosition, }); // Convert LSP locations to our Reference format const references: Reference[] = []; for (const location of locations) { const refPath = location.uri?.replace("file://", "") || ""; let refContent: string; try { refContent = readFileSync(refPath, "utf-8"); } catch (error) { // Skip references in files we can't read continue; } const refLines = refContent.split("\n"); // Get the text at the reference location const startLine = location.range.start.line; const startCol = location.range.start.character; const endCol = location.range.end.character; const refLineText = refLines[startLine] || ""; const text = refLineText.substring(startCol, endCol); // Create preview with context const prevLine = startLine > 0 ? refLines[startLine - 1] : ""; const nextLine = startLine < refLines.length - 1 ? refLines[startLine + 1] : ""; const preview = [ prevLine && `${startLine}: ${prevLine}`, `${startLine + 1}: ${refLineText}`, nextLine && `${startLine + 2}: ${nextLine}`, ] .filter(Boolean) .join("\n"); references.push({ relativePath: path.relative(request.root, refPath), line: startLine + 1, // Convert to 1-based column: startCol + 1, // Convert to 1-based text, preview, }); } return ok({ message: `Found ${references.length} reference${ references.length === 1 ? "" : "s" } to "${request.symbolName}"`, references, }); } catch (error) { const context: ErrorContext = { operation: "find references", filePath: request.relativePath, symbolName: request.symbolName, language: "lsp", }; return err(formatError(error, context)); } }
- src/utils/toolFilters.ts:36-36 (registration)Capability-based filtering for the find_references tool, disabling if no referencesProvider.if (name === "find_references" && !capabilities.referencesProvider) {