List unresolved links
obsidian_list_unresolvedIdentify wikilinks linking to missing notes in your Obsidian vault. This tool scans for broken links and lists unresolved targets to help maintain note integrity.
Instructions
Finds wikilinks that point to non-existent notes.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Vault name to target. Optional — defaults to the most recently focused vault. |
Implementation Reference
- src/tools.ts:7-14 (schema)Input schema for the tool — accepts optional 'vault' argument to target a specific vault.
const VaultArg = { vault: z .string() .optional() .describe( "Vault name to target. Optional — defaults to the most recently focused vault.", ), }; - src/tools.ts:631-638 (registration)Registration of the 'obsidian_list_unresolved' tool with name, title, description, input schema, annotations, and handler.
{ name: "obsidian_list_unresolved", title: "List unresolved links", description: "Finds wikilinks that point to non-existent notes.", inputSchema: { ...VaultArg }, annotations: { readOnlyHint: true, openWorldHint: false }, handler: async ({ vault }) => runJson("unresolved", { vault }), }, - src/tools.ts:637-637 (handler)Handler that calls runJson('unresolved', {vault}) to execute the 'unresolved' command via the Obsidian CLI.
handler: async ({ vault }) => runJson("unresolved", { vault }), - src/tools.ts:82-97 (helper)Helper function runJson that invokes runObsidian with the given command and returns structured JSON output.
async function runJson( command: string, opts: Parameters<typeof runObsidian>[1] = {}, ): Promise<McpToolResult> { try { const result = await runObsidian(command, { ...opts, format: opts.format ?? "json" }); const parsed = parseJsonOrText(result.stdout); const text = typeof parsed === "string" ? parsed : JSON.stringify(parsed, null, 2); return textResult(text || "(no output)", parsed); } catch (err) { return errorResult(err); } } - src/exec.ts:64-100 (helper)Core exec helper runObsidian that builds and shells out to the 'obsidian' CLI binary with the given command.
export async function runObsidian( command: string, opts: RunOptions = {}, ): Promise<RunResult> { const bin = process.env.OBSIDIAN_CLI ?? "obsidian"; const args = buildArgs(command, opts); const cmdline = [bin, ...args].map(shellQuote).join(" "); try { const { stdout, stderr } = await exec(cmdline, { maxBuffer: 64 * 1024 * 1024, windowsHide: true, }); return { stdout, stderr, exitCode: 0, command: cmdline }; } catch (err: unknown) { const e = err as NodeJS.ErrnoException & { stdout?: string; stderr?: string; code?: number | string; }; const result: RunResult = { stdout: e.stdout ?? "", stderr: e.stderr ?? e.message ?? "", exitCode: typeof e.code === "number" ? e.code : 1, command: cmdline, }; if (e.code === "ENOENT") { throw new ObsidianCliError( `Obsidian CLI binary not found ('${bin}'). ` + `Make sure Obsidian is running and the CLI is registered ` + `(Settings → General → Command line interface → Register CLI). ` + `Override with the OBSIDIAN_CLI env var if the binary lives elsewhere.`, result, ); } throw new ObsidianCliError( `obsidian CLI exited with code ${result.exitCode}: ${result.stderr.trim() || result.stdout.trim()}`,