edit_file
Replace an exact string that appears exactly once in a file with a new string, ensuring precise single-occurrence replacement.
Instructions
Replace an exact string in a file. The old_string must appear exactly once.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path | |
| old_string | Yes | Exact text to find and replace | |
| new_string | Yes | Text to replace it with | |
| workspace_root | No | Workspace root directory (optional) |
Implementation Reference
- src/index.ts:194-207 (schema)Input schema definition for the edit_file tool specifying path, old_string, new_string, and workspace_root parameters.
{ name: "edit_file", description: "Replace an exact string in a file. The old_string must appear exactly once.", inputSchema: { type: "object", properties: { path: { type: "string", description: "File path" }, old_string: { type: "string", description: "Exact text to find and replace" }, new_string: { type: "string", description: "Text to replace it with" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path", "old_string", "new_string"], }, }, - src/index.ts:166-422 (registration)The TOOLS array where edit_file is registered alongside all other MCP tools.
const TOOLS: Tool[] = [ { name: "read_file", description: "Read the contents of a file. Optionally specify a line range.", inputSchema: { type: "object", properties: { path: { type: "string", description: "File path (absolute or relative to workspace root)" }, start_line: { type: "number", description: "First line to read (1-indexed, inclusive)" }, end_line: { type: "number", description: "Last line to read (1-indexed, inclusive)" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path"], }, }, { name: "write_file", description: "Write or overwrite a file with new content. Creates parent directories automatically.", inputSchema: { type: "object", properties: { path: { type: "string", description: "File path" }, content: { type: "string", description: "Content to write" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path", "content"], }, }, { name: "edit_file", description: "Replace an exact string in a file. The old_string must appear exactly once.", inputSchema: { type: "object", properties: { path: { type: "string", description: "File path" }, old_string: { type: "string", description: "Exact text to find and replace" }, new_string: { type: "string", description: "Text to replace it with" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path", "old_string", "new_string"], }, }, { name: "list_directory", description: "List files and directories at a given path.", inputSchema: { type: "object", properties: { path: { type: "string", description: "Directory path" }, recursive: { type: "boolean", description: "Whether to list recursively (default false)" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path"], }, }, { name: "create_directory", description: "Create a directory (and all parent directories).", inputSchema: { type: "object", properties: { path: { type: "string", description: "Directory path to create" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path"], }, }, { name: "delete_path", description: "Delete a file or directory.", inputSchema: { type: "object", properties: { path: { type: "string", description: "File or directory path to delete" }, recursive: { type: "boolean", description: "Required true to delete non-empty directories" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path"], }, }, { name: "move_path", description: "Move or rename a file or directory.", inputSchema: { type: "object", properties: { source: { type: "string", description: "Source path" }, destination: { type: "string", description: "Destination path" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["source", "destination"], }, }, { name: "search_files", description: "Search for a regex pattern inside files. Returns matching lines with file and line number.", inputSchema: { type: "object", properties: { directory: { type: "string", description: "Directory to search in" }, pattern: { type: "string", description: "Regex pattern to search for" }, file_glob: { type: "string", description: "Glob to filter files (e.g. '*.ts')" }, ignore_case: { type: "boolean", description: "Case-insensitive search" }, max_results: { type: "number", description: "Max results to return (default 100)" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["directory", "pattern"], }, }, { name: "find_files", description: "Find files by name glob pattern (e.g. '*.ts', 'index.*').", inputSchema: { type: "object", properties: { directory: { type: "string", description: "Directory to search in" }, pattern: { type: "string", description: "Glob pattern for filename (e.g. '*.ts')" }, max_results: { type: "number", description: "Max results to return (default 200)" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["directory", "pattern"], }, }, { name: "run_command", description: "Execute a shell command in the given working directory. Returns stdout, stderr, and exit code.", inputSchema: { type: "object", properties: { command: { type: "string", description: "Command to run" }, cwd: { type: "string", description: "Working directory (defaults to workspace root or cwd)" }, timeout_ms: { type: "number", description: "Timeout in milliseconds (default 30000)" }, }, required: ["command"], }, }, { name: "get_workspace_info", description: "Get information about the current workspace: root directory, platform, Node version, git status summary.", inputSchema: { type: "object", properties: { workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, }, }, { name: "get_file_info", description: "Get metadata about a file or directory (size, modification time, type).", inputSchema: { type: "object", properties: { path: { type: "string", description: "File or directory path" }, workspace_root: { type: "string", description: "Workspace root directory (optional)" }, }, required: ["path"], }, }, // ── Cursor bridge tools (require the cursor-mcp-bridge extension running) ── { name: "cursor_status", description: "Check if the Cursor MCP Bridge extension is running and get workspace info.", inputSchema: { type: "object", properties: {} }, }, { name: "cursor_list_commands", description: "List Cursor/VS Code commands available in the IDE. Use filter to narrow results.", inputSchema: { type: "object", properties: { filter: { type: "string", description: "Optional keyword filter (e.g. 'chat', 'model', 'cursor')" }, }, }, }, { name: "cursor_open_chat", description: "Open a new chat, composer, or agent panel in Cursor.", inputSchema: { type: "object", properties: { mode: { type: "string", enum: ["chat", "composer", "agent"], description: "Which panel to open (default: chat)", }, message: { type: "string", description: "Optional initial message to send" }, }, }, }, { name: "cursor_send_message", description: "Open the Cursor chat and send a message (starts a new conversation).", inputSchema: { type: "object", properties: { message: { type: "string", description: "Message to send in the chat" }, }, required: ["message"], }, }, { name: "cursor_get_model", description: "Get the currently configured AI model in Cursor.", inputSchema: { type: "object", properties: {} }, }, { name: "cursor_set_model", description: "Change the active AI model in Cursor (e.g. claude-sonnet-4-5, gpt-4o, gemini-pro).", inputSchema: { type: "object", properties: { model: { type: "string", description: "Model identifier to set" }, }, required: ["model"], }, }, { name: "cursor_open_model_picker", description: "Open the model selector UI in Cursor so the user can pick a model visually.", inputSchema: { type: "object", properties: {} }, }, { name: "cursor_open_file", description: "Open a file in the Cursor editor, optionally jumping to a specific line.", inputSchema: { type: "object", properties: { path: { type: "string", description: "Absolute file path to open" }, line: { type: "number", description: "Line number to jump to (1-indexed)" }, }, required: ["path"], }, }, { name: "cursor_editor_state", description: "Get the current editor state: active file, cursor position, selected text, open editors.", inputSchema: { type: "object", properties: {} }, }, { name: "cursor_diagnostics", description: "Get all errors and warnings (diagnostics) from the IDE's language servers.", inputSchema: { type: "object", properties: {} }, }, { name: "cursor_run_command", description: "Execute any VS Code / Cursor command by its ID. Use cursor_list_commands to discover IDs.", inputSchema: { type: "object", properties: { command: { type: "string", description: "Command ID (e.g. 'workbench.action.reloadWindow')" }, args: { type: "array", description: "Optional arguments to pass to the command" }, }, required: ["command"], }, }, ]; - src/index.ts:451-462 (handler)Handler implementation for edit_file: reads the file, finds the old_string (must appear exactly once), replaces it with new_string, and writes the file back.
case "edit_file": { const filePath = resolveWorkspacePath(a.path as string, a.workspace_root as string | undefined); const original = await readFile(filePath, "utf-8"); const oldStr = a.old_string as string; const idx = original.indexOf(oldStr); if (idx === -1) throw new Error("old_string not found in file"); const lastIdx = original.lastIndexOf(oldStr); if (idx !== lastIdx) throw new Error("old_string appears more than once — be more specific"); const updated = original.slice(0, idx) + (a.new_string as string) + original.slice(idx + oldStr.length); await writeFile(filePath, updated, "utf-8"); return { content: [{ type: "text", text: `Edited: ${filePath}` }] }; }