Skip to main content
Glama

rename_symbol

Rename TypeScript symbols (variables, functions, classes) across the entire codebase by specifying the root directory, file path, line, old name, and new name for consistent refactoring.

Instructions

Rename a TypeScript symbol (variable, function, class, etc.) across the codebase

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathYesFile path containing the symbol (relative to root)
lineYesLine number (1-based) or string to match in the line
newNameYesNew name for the symbol
oldNameYesCurrent name of the symbol
rootYesRoot directory for resolving relative paths

Implementation Reference

  • Zod input schema defining parameters for the rename_symbol tool: root, relativePath, optional line, textTarget, newName.
    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") .optional(), textTarget: z.string().describe("Symbol to rename"), newName: z.string().describe("New name for the symbol"), });
  • The core tool handler for lsp_rename_symbol (referred to as rename_symbol in docs/filters). Defines the tool with name, description, schema, and execute function that performs the rename via LSP and formats the output showing changed files.
    export function createRenameSymbolTool( client: LSPClient, ): McpToolDef<typeof schema> { return { name: "lsp_rename_symbol", description: "Rename a symbol across the codebase using LSP. Requires exact position or text target in the specified line.", schema, execute: async (args) => { const result = await handleRenameSymbol(args, client); if (result.isErr()) { throw new Error(result.error); } // Format output const { message, changedFiles } = result.value; const output = [message, "", "Changes:"]; for (const file of changedFiles) { const relativePath = path.relative(args.root, file.filePath); output.push(` ${relativePath}:`); for (const change of file.changes) { output.push( ` Line ${change.line}: "${change.oldText}" → "${change.newText}"`, ); } } return output.join("\n"); }, }; }
  • Registration of the rename_symbol tool (as lsp_rename_symbol) within the array of all LSP tools returned by createLSPTools.
    export function createLSPTools(client: LSPClient): McpToolDef<any>[] { return [ createHoverTool(client), createReferencesTool(client), createDefinitionsTool(client), createDiagnosticsTool(client), createRenameSymbolTool(client), createDocumentSymbolsTool(client), createCompletionTool(client), createSignatureHelpTool(client), createFormatDocumentTool(client), createWorkspaceSymbolsTool(client), createCodeActionsTool(client), createCheckCapabilitiesTool(client), createDeleteSymbolTool(client), ];
  • Core helper function that orchestrates the rename operation, dispatching to line-specific or text-search-based rename logic.
    async function handleRenameSymbol( request: RenameSymbolRequest, client: LSPClient, ): Promise<Result<RenameSymbolSuccess, string>> { try { if (request.line !== undefined) { return performRenameWithLine(request, client); } else { return performRenameWithoutLine(request, client); } } catch (error) { return err(error instanceof Error ? error.message : String(error)); } }
  • Key helper implementing the LSP rename at specific position: opens project files, performs LSP rename request, applies WorkspaceEdit changes to files, returns success with changed files details.
    async function performRenameAtPosition( request: RenameSymbolRequest, fileUri: string, fileContent: string, targetLine: number, symbolPosition: number, client: LSPClient, ): Promise<Result<RenameSymbolSuccess, string>> { try { if (!client) { return err("LSP client not available"); } // Open all TypeScript/JavaScript files in the project to ensure LSP knows about them const projectFiles = await findProjectFiles(request.root); for (const file of projectFiles) { if (file !== path.resolve(request.root, request.relativePath)) { try { const content = readFileSync(file, "utf-8"); client.openDocument(`file://${file}`, content); } catch (e) { debug(`[lspRenameSymbol] Failed to open file: ${file}`, e); } } } // Open the target document client.openDocument(fileUri, fileContent); await new Promise<void>((resolve) => setTimeout(resolve, 1000)); const position: Position = { line: targetLine, character: symbolPosition, }; // Optional: Check if rename is possible at this position try { const prepareResult = await client.prepareRename(fileUri, position); if (prepareResult === null) { return err( `Cannot rename symbol at line ${targetLine + 1}, column ${ symbolPosition + 1 }`, ); } } catch { // Some LSP servers don't support prepareRename, continue with rename } // Perform rename let workspaceEdit: WorkspaceEdit | null = null; try { // Use the client's rename method which handles errors properly workspaceEdit = await client.rename(fileUri, position, request.newName); } catch (error: any) { // Check if LSP doesn't support rename (e.g., TypeScript Native Preview) if ( error.code === -32601 || error.message?.includes("Unhandled method") || error.message?.includes("Method not found") ) { return err("LSP server doesn't support rename operation"); } // Re-throw other errors throw error; } if (!workspaceEdit) { // LSP returned null, try TypeScript tool as fallback return err("No changes from LSP rename operation"); } // Debug: Log the workspace edit debug( "[lspRenameSymbol] WorkspaceEdit from LSP:", JSON.stringify(workspaceEdit, null, 2), ); // Apply changes and format result const result = await applyWorkspaceEdit(request.root, workspaceEdit); // Close all opened documents client.closeDocument(fileUri); for (const file of projectFiles) { if (file !== path.resolve(request.root, request.relativePath)) { try { client.closeDocument(`file://${file}`); } catch (e) { // Ignore close errors } } } return ok(result); } catch (error) { return err(error instanceof Error ? error.message : String(error)); } }

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/mizchi/typescript-mcp'

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