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.
774 lines • 45.7 kB
TypeScript
/**
* @fileoverview Tool registration barrel. Tools are split into read-only and
* write groups so the entry point can wrap the write set with `disabledTool()`
* when `OBSIDIAN_READ_ONLY=true`. The command-palette pair is exported
* separately so the entry point wraps it with `disabledTool()` when either
* `OBSIDIAN_ENABLE_COMMANDS=false` or `OBSIDIAN_READ_ONLY=true` — keeping this
* module free of eager config reads. `obsidian_search_notes` is exposed as a
* factory (`buildSearchNotesTool`) because its mode enum is conditional on
* Omnisearch reachability, which is only known after the startup probe runs.
* @module mcp-server/tools/definitions/index
*/
export { buildSearchNotesTool } from './obsidian-search-notes.tool.js';
/**
* Read-only tools that don't depend on runtime probes — always registered,
* even with `OBSIDIAN_READ_ONLY=true`. `obsidian_search_notes` is constructed
* separately in the entry point via `buildSearchNotesTool` so its mode enum
* can reflect Omnisearch reachability.
*/
export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
format: import("zod").ZodEnum<{
content: "content";
section: "section";
full: "full";
"document-map": "document-map";
}>;
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
section: import("zod").ZodOptional<import("zod").ZodObject<{
type: import("zod").ZodEnum<{
heading: "heading";
block: "block";
frontmatter: "frontmatter";
}>;
target: import("zod").ZodString;
}, import("zod/v4/core").$strip>>;
includeLinks: import("zod").ZodDefault<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
format: import("zod").ZodLiteral<"content">;
path: import("zod").ZodString;
content: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
format: import("zod").ZodLiteral<"full">;
path: import("zod").ZodString;
content: import("zod").ZodString;
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
tags: import("zod").ZodArray<import("zod").ZodString>;
stat: import("zod").ZodObject<{
ctime: import("zod").ZodNumber;
mtime: import("zod").ZodNumber;
size: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>;
outgoingLinks: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
target: import("zod").ZodString;
type: import("zod").ZodEnum<{
markdown: "markdown";
wikilink: "wikilink";
}>;
}, import("zod/v4/core").$strip>>>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
format: import("zod").ZodLiteral<"document-map">;
path: import("zod").ZodString;
headings: import("zod").ZodArray<import("zod").ZodString>;
blocks: import("zod").ZodArray<import("zod").ZodString>;
frontmatterFields: import("zod").ZodArray<import("zod").ZodString>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
format: import("zod").ZodLiteral<"section">;
path: import("zod").ZodString;
section: import("zod").ZodObject<{
type: import("zod").ZodEnum<{
heading: "heading";
block: "block";
frontmatter: "frontmatter";
}>;
target: import("zod").ZodString;
}, import("zod/v4/core").$strip>;
valueText: import("zod").ZodOptional<import("zod").ZodString>;
valueJson: import("zod").ZodOptional<import("zod").ZodUnknown>;
}, import("zod/v4/core").$strip>], "format">;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "section_required";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "`format` is \"section\" but no `section` locator was provided.";
readonly recovery: "Pass `section: { type, target }` (e.g. `{ type: \"heading\", target: \"Intro\" }`), or use `format: \"full\"` / `\"document-map\"` instead.";
}, {
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The vault path does not resolve to an existing note.";
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
}, {
readonly reason: "ambiguous_path";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
readonly when: "The parent directory contains multiple files whose names differ only in case (case-sensitive filesystems only).";
readonly recovery: "Retry with one of the exact paths listed in `matches` on the error data.";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}, {
readonly reason: "section_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "`format` was `\"section\"` and the named heading, block reference, or frontmatter field does not exist in the resolved note.";
readonly recovery: "Call obsidian_get_note with format \"document-map\" to list available headings, blocks, and frontmatter fields. Nested headings need Parent::Child syntax.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
path: import("zod").ZodOptional<import("zod").ZodString>;
extension: import("zod").ZodOptional<import("zod").ZodString>;
nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
depth: import("zod").ZodDefault<import("zod").ZodNumber>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
entries: import("zod").ZodArray<import("zod").ZodObject<{
path: import("zod").ZodString;
type: import("zod").ZodEnum<{
file: "file";
directory: "directory";
}>;
truncated: import("zod").ZodOptional<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>>;
totals: import("zod").ZodObject<{
entries: import("zod").ZodNumber;
files: import("zod").ZodNumber;
directories: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>;
appliedFilters: import("zod").ZodObject<{
extension: import("zod").ZodOptional<import("zod").ZodString>;
nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
depth: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>;
excluded: import("zod").ZodOptional<import("zod").ZodObject<{
reason: import("zod").ZodLiteral<"entry_cap">;
cap: import("zod").ZodNumber;
hint: import("zod").ZodString;
}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "regex_invalid";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The supplied `nameRegex` is not a valid ECMAScript regex.";
readonly recovery: "Use a valid ECMAScript regex (e.g. `^Project.*\\.md$`), or omit nameRegex to disable filtering.";
}, {
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The supplied `path` is outside OBSIDIAN_READ_PATHS (root listings always pass; specific subdirectories must be readable).";
readonly recovery: "List a directory inside the configured read scope, or omit `path` to list from the vault root. The error data echoes the active scope.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The supplied `path` does not exist in the vault. Sub-directories that disappear mid-walk are silently skipped — only the root path surfaces this error.";
readonly recovery: "List a parent directory to find the correct casing or check the spelling.";
}], {
readonly notice: import("zod").ZodOptional<import("zod").ZodString>;
}> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
tags: import("zod").ZodArray<import("zod").ZodObject<{
name: import("zod").ZodString;
count: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>>;
appliedFilters: import("zod").ZodOptional<import("zod").ZodObject<{
nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "regex_invalid";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The supplied `nameRegex` is not a valid ECMAScript regex.";
readonly recovery: "Use a valid ECMAScript regex (e.g. `^mcp/.*`), or omit nameRegex to disable filtering.";
}, {
readonly reason: "regex_unsafe";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The supplied `nameRegex` is well-formed but exceeds the 256-character limit or contains nested quantifiers known to cause catastrophic backtracking.";
readonly recovery: "Avoid nested quantifiers like `(a+)+` or `(.*)*`. Use a simpler pattern (e.g. `^mcp/.*`), or omit nameRegex to disable filtering.";
}], {
readonly notice: import("zod").ZodOptional<import("zod").ZodString>;
}> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
path: import("zod").ZodString;
failIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
newLeaf: import("zod").ZodDefault<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
opened: import("zod").ZodBoolean;
createdIfMissing: import("zod").ZodBoolean;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "`failIfMissing: true` (default) and the path does not exist in the vault. Pass `failIfMissing: false` to allow Obsidian to create the file on open.";
readonly recovery: "Verify the path with obsidian_list_notes or obsidian_search_notes first — a typo would otherwise materialize as an empty file. If creation is intended, retry with failIfMissing: false.";
}, {
readonly reason: "ambiguous_path";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
readonly when: "The parent directory contains multiple files whose names differ only in case (case-sensitive filesystems only).";
readonly recovery: "Retry with one of the exact paths listed in `matches` on the error data.";
}], undefined>)[];
/** Write tools — wrapped with `disabledTool()` when `OBSIDIAN_READ_ONLY=true`. */
export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
content: import("zod").ZodString;
section: import("zod").ZodOptional<import("zod").ZodObject<{
type: import("zod").ZodEnum<{
heading: "heading";
block: "block";
frontmatter: "frontmatter";
}>;
target: import("zod").ZodString;
}, import("zod/v4/core").$strip>>;
contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
markdown: "markdown";
json: "json";
}>>;
createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
sectionTargeted: import("zod").ZodBoolean;
created: import("zod").ZodBoolean;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Section append targets a path that does not resolve to an existing note (PATCH requires the file to exist).";
readonly recovery: "Verify the path with obsidian_list_notes, or omit `section` to fall back to whole-file append (which creates the note if missing).";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}, {
readonly reason: "section_target_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "`section` was provided but the named heading/block/frontmatter field does not exist in the note.";
readonly recovery: "Call obsidian_get_note with format document-map to discover available targets, or pass createTargetIfMissing: true to bring it into existence.";
}, {
readonly reason: "content_preexists";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Section append where the supplied content already appears at the target — rejected to keep retries idempotent (the default for the section path).";
readonly recovery: "Change the content to something not already present at the target, or use obsidian_patch_note with `patchOptions.applyIfContentPreexists: true` if a duplicate is intended.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
deleted: import("zod").ZodBoolean;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
}, {
readonly reason: "cancelled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.InvalidRequest;
readonly when: "User declined the deletion via interactive elicitation.";
readonly recovery: "Re-run the tool when the user is ready to confirm deletion.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The vault path does not resolve to an existing note.";
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Pass an explicit path target — periodic notes must already exist.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
operation: import("zod").ZodEnum<{
set: "set";
delete: "delete";
get: "get";
}>;
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
key: import("zod").ZodString;
value: import("zod").ZodOptional<import("zod").ZodUnknown>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
operation: import("zod").ZodLiteral<"get">;
path: import("zod").ZodString;
key: import("zod").ZodString;
exists: import("zod").ZodBoolean;
value: import("zod").ZodUnknown;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
operation: import("zod").ZodLiteral<"set">;
path: import("zod").ZodString;
key: import("zod").ZodString;
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
operation: import("zod").ZodLiteral<"delete">;
path: import("zod").ZodString;
key: import("zod").ZodString;
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>], "operation">;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "`get` requires the path to be readable; `set`/`delete` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
readonly recovery: "Use a path inside the configured scope. The error data echoes the active scope.";
}, {
readonly reason: "value_required";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "`operation` is \"set\" but no `value` was supplied.";
readonly recovery: "Pass `value` as any JSON-typed value: string, number, boolean, array, or object (e.g. `\"draft\"`, `42`, `true`, `[\"a\",\"b\"]`).";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The vault path does not resolve to an existing note.";
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
operation: import("zod").ZodEnum<{
list: "list";
add: "add";
remove: "remove";
}>;
tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
location: import("zod").ZodDefault<import("zod").ZodEnum<{
frontmatter: "frontmatter";
inline: "inline";
both: "both";
}>>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
operation: import("zod").ZodLiteral<"list">;
path: import("zod").ZodString;
tags: import("zod").ZodObject<{
frontmatter: import("zod").ZodArray<import("zod").ZodString>;
inline: import("zod").ZodArray<import("zod").ZodString>;
all: import("zod").ZodArray<import("zod").ZodString>;
}, import("zod/v4/core").$strip>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
operation: import("zod").ZodLiteral<"add">;
path: import("zod").ZodString;
applied: import("zod").ZodArray<import("zod").ZodString>;
skipped: import("zod").ZodArray<import("zod").ZodString>;
tags: import("zod").ZodArray<import("zod").ZodString>;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
operation: import("zod").ZodLiteral<"remove">;
path: import("zod").ZodString;
applied: import("zod").ZodArray<import("zod").ZodString>;
skipped: import("zod").ZodArray<import("zod").ZodString>;
tags: import("zod").ZodArray<import("zod").ZodString>;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>], "operation">;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "`list` requires the path to be readable; `add`/`remove` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
readonly recovery: "Use a path inside the configured scope. The error data echoes the active scope.";
}, {
readonly reason: "tags_required";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "`operation` is \"add\" or \"remove\" but `tags` was empty or omitted.";
readonly recovery: "Pass a non-empty `tags` array (without `#`), e.g. `[\"draft\", \"wip\"]`.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The vault path does not resolve to an existing note.";
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
section: import("zod").ZodObject<{
type: import("zod").ZodEnum<{
heading: "heading";
block: "block";
frontmatter: "frontmatter";
}>;
target: import("zod").ZodString;
}, import("zod/v4/core").$strip>;
operation: import("zod").ZodEnum<{
replace: "replace";
append: "append";
prepend: "prepend";
}>;
content: import("zod").ZodString;
contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
markdown: "markdown";
json: "json";
}>>;
patchOptions: import("zod").ZodOptional<import("zod").ZodObject<{
createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
applyIfContentPreexists: import("zod").ZodDefault<import("zod").ZodBoolean>;
trimTargetWhitespace: import("zod").ZodDefault<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
section: import("zod").ZodObject<{
type: import("zod").ZodEnum<{
heading: "heading";
block: "block";
frontmatter: "frontmatter";
}>;
target: import("zod").ZodString;
}, import("zod/v4/core").$strip>;
operation: import("zod").ZodEnum<{
replace: "replace";
append: "append";
prepend: "prepend";
}>;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The vault path does not resolve to an existing note.";
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}, {
readonly reason: "section_target_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The named heading/block/frontmatter field does not exist in the note. Use `obsidian_get_note` with `format: \"document-map\"` to discover available targets.";
readonly recovery: "Call obsidian_get_note with format document-map to discover the available targets.";
}, {
readonly reason: "content_preexists";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The supplied content already appears at the target — the patch was rejected to keep retries idempotent (the default).";
readonly recovery: "Pass `patchOptions.applyIfContentPreexists: true` to force-apply over preexisting content, or change the content to something not already present.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
replacements: import("zod").ZodArray<import("zod").ZodObject<{
search: import("zod").ZodString;
replace: import("zod").ZodString;
useRegex: import("zod").ZodDefault<import("zod").ZodBoolean>;
caseSensitive: import("zod").ZodDefault<import("zod").ZodBoolean>;
wholeWord: import("zod").ZodDefault<import("zod").ZodBoolean>;
flexibleWhitespace: import("zod").ZodDefault<import("zod").ZodBoolean>;
replaceAll: import("zod").ZodDefault<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
totalReplacements: import("zod").ZodNumber;
perReplacement: import("zod").ZodArray<import("zod").ZodObject<{
search: import("zod").ZodString;
count: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>>;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes. (The pre-read also requires the path to be readable.)";
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
}, {
readonly reason: "regex_invalid";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "A `useRegex: true` replacement supplied a `search` pattern that is not a valid ECMAScript regex.";
readonly recovery: "Use a valid ECMAScript regex, or set useRegex to false to match `search` as a literal string.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The vault path does not resolve to an existing note.";
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
type: import("zod").ZodLiteral<"path">;
path: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"active">;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"periodic">;
period: import("zod").ZodEnum<{
daily: "daily";
weekly: "weekly";
monthly: "monthly";
quarterly: "quarterly";
yearly: "yearly";
}>;
date: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>], "type">;
content: import("zod").ZodString;
section: import("zod").ZodOptional<import("zod").ZodObject<{
type: import("zod").ZodEnum<{
heading: "heading";
block: "block";
frontmatter: "frontmatter";
}>;
target: import("zod").ZodString;
}, import("zod/v4/core").$strip>>;
contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
markdown: "markdown";
json: "json";
}>>;
overwrite: import("zod").ZodDefault<import("zod").ZodBoolean>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
path: import("zod").ZodString;
sectionTargeted: import("zod").ZodBoolean;
created: import("zod").ZodBoolean;
previousSizeInBytes: import("zod").ZodNumber;
currentSizeInBytes: import("zod").ZodNumber;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "file_exists";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
readonly when: "Whole-file write was attempted against an existing note and `overwrite` was not set to `true`.";
readonly recovery: "Retry with overwrite true or use obsidian_patch_note for in-place edits.";
}, {
readonly reason: "path_forbidden";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
}, {
readonly reason: "note_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Section replace targets a path that does not resolve to an existing note (PATCH requires the file to exist).";
readonly recovery: "Verify the path with obsidian_list_notes, or omit `section` to fall back to whole-file write (which creates the note when it is absent).";
}, {
readonly reason: "no_active_file";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `active` but no file is currently open in Obsidian.";
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
}, {
readonly reason: "periodic_not_found";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "Target was `periodic` but no matching periodic note exists.";
readonly recovery: "Create the periodic note first or pass an explicit path target.";
}, {
readonly reason: "periodic_disabled";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
}, {
readonly reason: "section_target_missing";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "`section` was provided but the named heading/block/frontmatter field does not exist in the note.";
readonly recovery: "Call obsidian_get_note with format document-map to discover available targets.";
}], undefined>)[];
/** Command-palette tools — opt-in via `OBSIDIAN_ENABLE_COMMANDS=true`; suppressed by `OBSIDIAN_READ_ONLY=true`. */
export declare const commandToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
commandId: import("zod").ZodString;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
commandId: import("zod").ZodString;
executed: import("zod").ZodBoolean;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "command_unknown";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
readonly when: "The supplied `commandId` is not registered in Obsidian. Use `obsidian_list_commands` to discover valid IDs.";
readonly recovery: "Call obsidian_list_commands to discover the registered command IDs.";
}], undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
commands: import("zod").ZodArray<import("zod").ZodObject<{
id: import("zod").ZodString;
name: import("zod").ZodString;
}, import("zod/v4/core").$strip>>;
appliedFilters: import("zod").ZodOptional<import("zod").ZodObject<{
nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>, readonly [{
readonly reason: "regex_invalid";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The supplied `nameRegex` is not a valid ECMAScript regex.";
readonly recovery: "Use a valid ECMAScript regex (e.g. `^Templater`), or omit nameRegex to disable filtering.";
}, {
readonly reason: "regex_unsafe";
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
readonly when: "The supplied `nameRegex` is well-formed but exceeds the 256-character limit or contains nested quantifiers known to cause catastrophic backtracking.";
readonly recovery: "Avoid nested quantifiers like `(a+)+` or `(.*)*`. Use a simpler pattern (e.g. `^Templater`), or omit nameRegex to disable filtering.";
}], undefined>)[];
//# sourceMappingURL=index.d.ts.map