Skip to main content
Glama

extract_function

Extract selected code into a new function to improve code structure and maintainability through refactoring.

Instructions

Extract selected code into a new function

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fileYesFile containing the code to extract
startLineYesStart line of code to extract
startCharacterNoStart character position
endLineYesEnd line of code to extract
endCharacterNoEnd character position
functionNameYesName for the new function
languageNoProgramming languagetypescript

Implementation Reference

  • Main execution logic for the 'extract_function' MCP tool. Opens the file in LSP, requests code actions with 'refactor.extract.function' context, applies the first available workspace edit to perform the extraction.
    export async function extractFunction(args: ExtractFunctionArgs, clientManager: LSPClientManager) { const { file, startLine, startCharacter = 0, endLine, endCharacter = 0, functionName: _functionName, language = 'typescript', } = args; const workspaceRoot = findWorkspaceRoot(file); try { const client = await clientManager.getOrCreateLSPClient(language, workspaceRoot); // Open the file const content = await fs.readFile(file, 'utf-8'); await clientManager.sendLSPNotification(client, 'textDocument/didOpen', { textDocument: { uri: `file://${file}`, languageId: language, version: 1, text: content, }, }); // Request LSP code actions for extract function const codeActions = await clientManager.sendLSPRequest(client, 'textDocument/codeAction', { textDocument: { uri: `file://${file}` }, range: { start: { line: startLine - 1, character: startCharacter }, end: { line: endLine - 1, character: endCharacter }, }, context: { diagnostics: [], only: ['refactor.extract.function'], }, }); const actions = Array.isArray(codeActions) ? codeActions : []; if (actions.length === 0) { return { content: [ { type: 'text', text: `No extract function refactoring available for the selected range in ${file}. This could be because the range does not contain extractable code or the language server doesn't support this refactoring.`, }, ], }; } // Apply the first extract function action const action = actions[0]; if (!action.edit) { return { content: [ { type: 'text', text: `Extract function code action does not contain workspace edit. The language server may not be configured properly for refactoring operations.`, }, ], }; } const { applyWorkspaceEdit } = await import('../lsp/utils.js'); await applyWorkspaceEdit(action.edit); return { content: [ { type: 'text', text: `Successfully extracted function from lines ${startLine}-${endLine} in ${file}`, }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Failed to extract function: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } }
  • src/server.ts:102-142 (registration)
    Registration of the 'extract_function' tool in the MCP server's listTools handler, including name, description, and input schema.
    { name: 'extract_function', description: 'Extract selected code into a new function', inputSchema: { type: 'object', properties: { file: { type: 'string', description: 'File containing the code to extract', }, startLine: { type: 'number', description: 'Start line of code to extract', }, startCharacter: { type: 'number', description: 'Start character position', default: 0, }, endLine: { type: 'number', description: 'End line of code to extract', }, endCharacter: { type: 'number', description: 'End character position', default: 0, }, functionName: { type: 'string', description: 'Name for the new function', }, language: { type: 'string', description: 'Programming language', default: 'typescript', }, }, required: ['file', 'startLine', 'endLine', 'functionName'], }, },
  • src/server.ts:216-217 (registration)
    Dispatch handler in the CallToolRequestSchema that invokes the extractFunction handler for the 'extract_function' tool.
    case 'extract_function': return await extractFunction(args as unknown as ExtractFunctionArgs, this.clientManager);
  • TypeScript interface defining the input arguments for the extract_function tool handler.
    export interface ExtractFunctionArgs { file: string; startLine: number; startCharacter?: number; endLine: number; endCharacter?: number; functionName: string; language?: string; }
  • Utility function used by the handler to apply the LSP workspace edit resulting from the extract function refactoring.
    export async function applyWorkspaceEdit(edit: LSPWorkspaceEdit): Promise<void> { if (edit.changes) { for (const [uri, changes] of Object.entries(edit.changes)) { const filePath = uri.replace('file://', ''); const content = await fs.readFile(filePath, 'utf-8'); const lines = content.split('\n'); // Apply changes in reverse order to maintain line numbers const sortedChanges = changes.sort((a, b) => b.range.start.line - a.range.start.line); for (const change of sortedChanges) { const startLine = change.range.start.line; const endLine = change.range.end.line; const newText = change.newText; lines.splice(startLine, endLine - startLine + 1, ...newText.split('\n')); } await fs.writeFile(filePath, lines.join('\n')); } } }

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/sminnee/lsp-mcp'

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