obsidian_batch
Execute multiple note operations—read, write, move, delete, and more—in a single batch call. Stop on error option ensures data integrity.
Instructions
Execute multiple filesystem note operations in one call. Operations are best-effort unless stopOnError is true.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Optional configured vault name. Defaults to the server default vault. | |
| operations | Yes | ||
| stopOnError | No |
Implementation Reference
- src/tools.ts:673-723 (registration)Registration of the 'obsidian_batch' tool with its schema (operations array supporting read/write/append/replace/frontmatter/move/delete) and inline handler function. The handler loops over operations and dispatches to vault methods.
tool( "obsidian_batch", "Execute multiple filesystem note operations in one call. Operations are best-effort unless stopOnError is true.", { vault: vaultArg, operations: z.array(z.object({ op: z.enum(["read", "write", "append", "replace", "frontmatter", "move", "delete"]), path: z.string().optional(), to: z.string().optional(), content: z.string().optional(), search: z.string().optional(), replace: z.string().optional(), frontmatter: z.record(z.unknown()).optional(), overwrite: z.boolean().optional(), confirmation: z.string().optional(), })).min(1).max(200), stopOnError: z.boolean().optional().default(false), }, async (args) => { const results = []; for (const operation of args.operations) { try { if (!operation.path) throw new Error("path is required"); if (operation.op === "read") { results.push({ ok: true, op: operation.op, note: await vaults.readText(operation.path, args.vault) }); } else if (operation.op === "write") { results.push({ ok: true, op: operation.op, ...(await vaults.writeText(vaults.notePath(operation.path!), operation.content ?? "", args.vault, { overwrite: operation.overwrite })) }); } else if (operation.op === "append") { results.push({ ok: true, op: operation.op, ...(await vaults.appendText(vaults.notePath(operation.path!), operation.content ?? "", args.vault, { create: true })) }); } else if (operation.op === "replace") { const read = await vaults.readText(operation.path!, args.vault); const next = read.text.replace(new RegExp(escapeRegExp(operation.search ?? ""), "g"), operation.replace ?? ""); await vaults.writeText(read.path, next, args.vault, { overwrite: true }); results.push({ ok: true, op: operation.op, path: read.path }); } else if (operation.op === "frontmatter") { const read = await vaults.readText(operation.path!, args.vault); await vaults.writeText(read.path, updateFrontmatter(read.text, operation.frontmatter ?? {}, "merge"), args.vault, { overwrite: true }); results.push({ ok: true, op: operation.op, path: read.path }); } else if (operation.op === "move") { results.push({ ok: true, op: operation.op, ...(await vaults.move(vaults.notePath(operation.path!), vaults.notePath(operation.to ?? ""), args.vault, { overwrite: operation.overwrite })) }); } else if (operation.op === "delete") { results.push({ ok: true, op: operation.op, ...(await vaults.trash(vaults.notePath(operation.path!), args.vault, { confirmation: operation.confirmation })) }); } } catch (error) { results.push({ ok: false, op: operation.op, path: operation.path, error: error instanceof Error ? error.message : String(error) }); if (args.stopOnError) break; } } return { results }; }, ); - src/tools.ts:673-690 (schema)Input schema for obsidian_batch: operations array (min 1, max 200 items) each with op type enum, path, to, content, search, replace, frontmatter, overwrite, confirmation fields; plus stopOnError flag.
tool( "obsidian_batch", "Execute multiple filesystem note operations in one call. Operations are best-effort unless stopOnError is true.", { vault: vaultArg, operations: z.array(z.object({ op: z.enum(["read", "write", "append", "replace", "frontmatter", "move", "delete"]), path: z.string().optional(), to: z.string().optional(), content: z.string().optional(), search: z.string().optional(), replace: z.string().optional(), frontmatter: z.record(z.unknown()).optional(), overwrite: z.boolean().optional(), confirmation: z.string().optional(), })).min(1).max(200), stopOnError: z.boolean().optional().default(false), },