UNPKG

obsidian-mcp-server

Version:

MCP server for Obsidian vaults — read, write, search, and surgically edit notes, tags, and frontmatter via the Local REST API plugin. STDIO or Streamable HTTP.

51 lines 2.73 kB
/** * @fileoverview Vault path resolution helpers. Two layered behaviors: * * 1. **Case-insensitive fallback.** If a path lookup 404s, list the parent * directory and look for a single case-insensitive filename match. If * found, retry against the canonical filesystem path (matches v2.x * behavior). This silently fixes "Readme.md" vs "README.md" on Linux; on * Mac/Windows the OS already case-folds and the fallback is a no-op. * * 2. **"Did you mean" suggestions.** When no case match exists but the parent * directory has near-matches (e.g., extension-stripped variants), re-throw * NotFound enriched with the candidates in the message and * `error.data.suggestions[]`. * * Read/open/delete tools wrap their service calls with `withCaseFallback`. * @module mcp-server/tools/definitions/_shared/suggest-paths */ import type { Context } from '@cyanheads/mcp-ts-core'; import type { ObsidianService } from '../../../../services/obsidian/obsidian-service.js'; import type { NoteTarget } from '../../../../services/obsidian/types.js'; /** * Wrap a service call with case-insensitive path fallback and "did you mean" * enrichment. Non-path targets pass through — their paths are resolved * upstream, so neither layer applies. * * For path targets: * - **Exact match** → returns `{ result, resolvedPath: target.path }`. * - **Single case match** → retries with the canonical path and returns * `{ result, resolvedPath: <canonical> }`. * - **Multiple case matches** → throws `Conflict` with the candidates so the * agent can disambiguate. * - **No case match, extension-stripped near-matches** → throws `NotFound` * enriched with a "did you mean" hint and `suggestions[]`. * - **No matches at all** → re-throws the original NotFound unchanged. * * `resolvedPath` is `undefined` for non-path targets — callers derive the * canonical path from the result itself (typically `NoteJson.path`). */ export declare function withCaseFallback<T>(ctx: Context, svc: ObsidianService, target: NoteTarget, fn: (target: NoteTarget) => Promise<T>): Promise<{ result: T; resolvedPath: string | undefined; }>; /** * List the parent directory of `path` and return up to {@link MAX_SUGGESTIONS} * close-match candidates. Match order: case-insensitive equality first, then * extension-stripped equality. Returns `[]` on listing failure or empty * basename. Used by callers that need suggestions without performing the * underlying operation (e.g., `obsidian_open_in_ui`'s explicit messaging). */ export declare function findSimilarPaths(ctx: Context, svc: ObsidianService, path: string): Promise<string[]>; //# sourceMappingURL=suggest-paths.d.ts.map