obsidian_replace_in_note
Replace text in a single Obsidian note using literal or regex search. Supports case-sensitive matching and replacing all occurrences at once.
Instructions
Search and replace inside one note. Supports literal or regex matching and replaceAll.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Optional configured vault name. Defaults to the server default vault. | |
| path | Yes | Vault-relative path. Absolute paths and traversal are rejected. | |
| search | Yes | ||
| replace | Yes | ||
| regex | No | ||
| caseSensitive | No | ||
| replaceAll | No |
Implementation Reference
- src/tools.ts:522-546 (registration)Registration of the 'obsidian_replace_in_note' tool with its schema (args validation) and handler function. This is the complete tool definition including the schema and the handler.
"obsidian_replace_in_note", "Search and replace inside one note. Supports literal or regex matching and replaceAll.", { vault: vaultArg, path: pathArg, search: z.string(), replace: z.string(), regex: z.boolean().optional().default(false), caseSensitive: z.boolean().optional().default(false), replaceAll: z.boolean().optional().default(false), }, async (args) => { const read = await vaults.readText(args.path, args.vault); const flags = `${args.replaceAll ? "g" : ""}${args.caseSensitive ? "" : "i"}`; const re = new RegExp(args.regex ? args.search : escapeRegExp(args.search), flags); let count = 0; const next = read.text.replace(re, () => { count += 1; return args.replace; }); if (count === 0) return { path: read.path, replaced: 0 }; await vaults.writeText(read.path, next, args.vault, { overwrite: true }); return { path: read.path, replaced: count }; }, ); - src/tools.ts:533-546 (handler)The handler function for obsidian_replace_in_note — reads the note, builds a RegExp from the search pattern with appropriate flags (global for replaceAll, case-insensitive by default), performs the replacement counting occurrences, writes back if replacements happened, and returns the count.
async (args) => { const read = await vaults.readText(args.path, args.vault); const flags = `${args.replaceAll ? "g" : ""}${args.caseSensitive ? "" : "i"}`; const re = new RegExp(args.regex ? args.search : escapeRegExp(args.search), flags); let count = 0; const next = read.text.replace(re, () => { count += 1; return args.replace; }); if (count === 0) return { path: read.path, replaced: 0 }; await vaults.writeText(read.path, next, args.vault, { overwrite: true }); return { path: read.path, replaced: count }; }, ); - src/tools.ts:524-532 (schema)Input schema for obsidian_replace_in_note: vault (optional), path (required), search string, replace string, regex flag (default false), caseSensitive flag (default false), replaceAll flag (default false).
{ vault: vaultArg, path: pathArg, search: z.string(), replace: z.string(), regex: z.boolean().optional().default(false), caseSensitive: z.boolean().optional().default(false), replaceAll: z.boolean().optional().default(false), }, - src/markdown.ts:268-270 (helper)The escapeRegExp helper function used by the handler to escape the search string for literal (non-regex) mode.
export function escapeRegExp(value: string): string { return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }