obsidian-tc
MCP server for Obsidian — comprehensive tool surface for humans and autonomous agents
Versions
1.13.1latest1.13.01.12.11.11.01.10.0+ show 18 moreshow less
1.9.11.9.01.8.11.8.01.7.01.6.01.5.01.4.01.3.61.3.51.3.41.3.31.3.21.3.11.2.11.0.21.0.10.0.1Tools 170
x read_thing structured bad good __bridge_read_probe read-side bridge probe tool
__bridge_execute_probe execute-side bridge probe tool
give test tool
noop test tool
plur_recall BM25 keyword recall over the global plur engram store (read-only proxy).
plur_recall_hybrid Hybrid BM25 + embedding recall (RRF) over the global plur engram store. `bm25_weight` is forwarded to the plur backend and only shifts ranking when that backend implements weighted hybrid RRF; the bundled local CLI backend applies default RRF and ignores it (audit #15).
plur_similarity_search Cosine similarity search over plur engram embeddings (read-only proxy).
plur_get Fetch a specific plur engram by id (read-only proxy).
create_entity Create a typed memory entity (optionally materialized as a vault .md note). SQLite is the source of truth. Domain: knowledge.
get_entity Read a memory entity by id, by type+name, or by unique name, with its observations and relations. Retired entities are hidden unless include_retired is set (THE-833).
add_observation Append a fact to a memory entity (re-materializing its note when materialized). Domain: knowledge.
link_entities Create a typed relation between two memory entities (idempotent; re-materializes the source's [[links]]). Domain: knowledge.
query_entity_graph Traverse the memory graph from a seed entity (BFS, depth-limited, type/direction filtered). Retired entities are excluded from the seed and the result set unless include_retired is set (THE-833) — traversal still walks THROUGH a retired node to reach its neighbors, only the returned/visible set is filtered. Domain: knowledge.
enqueue_capture Stage content in the SQLite capture queue for later commit to the vault (no vault write at enqueue time).
list_capture_queue List captures in the queue (pending by default; committed:true lists committed), newest first. Each item carries the poison-scan verdict assessed at enqueue time (THE-855) — review poison_assessment before calling commit_capture.
commit_capture Write a queued capture to a vault path and mark it committed (or remove it from the queue). Refuses to overwrite an existing note.
rename_entity Rename a memory entity and/or change its lifecycle status (active/retired). At least one of new_name/status is required. THE-833: this is the reachable path for retiring an entity — get_entity and query_entity_graph filter status:retired out by default. Renaming moves the materialized note (preserving any frontmatter Obsidian or a person added directly to the file) and re-materializes every OTHER materialized entity that has a relation TO this one, so their [[links]] keep resolving under the new name. Does not rewrite free-text mentions of the old name elsewhere in the vault — only entities with a direct graph edge to this one are touched.
unlink_entities Remove a typed relation between two memory entities — the inverse of link_entities. Removes only the named (source, target, relation_type) edge and leaves every other relation intact; re-materializes the source's [[links]]. A no-op (removed: false) when the relation didn't exist.
bulk_create_notes Batch-create notes with per-item results. Each item creates/overwrites/upserts a note (content + optional frontmatter). HITL-floored (bulk) and throttled; best-effort by default (stop_on_first_error opt-in).
delete_entity Delete a memory entity outright — the escape hatch for 'created it by accident', NOT the primary retirement path (use rename_entity's status param to retire instead; that stays reversible, this doesn't). Destructive; requires confirmation. Dependency-aware like `forget`: refuses when the entity has any relation, incoming or outgoing, unless cascade is set — in which case those relations are removed too and every OTHER materialized entity that referenced this one has its note re-materialized so its [[links]] stop dangling. The entity's own note is trashed (recoverable) unless permanent is set.
start_session Begin a workspace memory session: a SQLite row plus an append-only JSONL trace file.
end_session Finalize a workspace session, appending a session_end record to its JSONL trace.
get_session_traces Replay JSONL trace records for one session, or across a started-at date window, with optional tool filtering.
session_bootstrap Triage an opening session message (auto -> lightweight | standard | deep) and preload the matching vault context notes, so any MCP client gets session bootstrap, not only skill-enabled ones. Deep loads the configured deepPaths; standard loads the paths of every domain whose signals appear in the message; lightweight loads nothing. The routing table comes from server config (bootstrap.*); with none configured the tool degrades to lightweight. Read-only.
snapshot_note Capture the current content of a note as a restorable point-in-time snapshot (retained per config.snapshots.retention). Returns the snapshot id and content hash.
list_snapshots List a note's point-in-time snapshots, newest first (id, op, content_hash, size, created_at).
read_snapshot Read the full stored content of a single snapshot by id.
restore_note Restore a note to a prior snapshot's content. Destructive — overwrites the current note (whose current state is itself snapshotted first when snapshots are enabled, so the restore is reversible) and requires confirmation.
read_frontmatter Read a note's parsed YAML frontmatter (null when the note has none). Domain: metadata.
read_property Read a single frontmatter property. Set nested=true to address a dotted path (e.g. meta.author.name) through nested objects.
update_frontmatter Mutate a note's frontmatter (set/remove/merge/replace). `replace` discards all existing metadata and requires confirmation. Optional prev_hash gives compare-and-swap. Set nested=true to address a dotted key path for set/remove (intermediate objects are created as needed).
list_properties Aggregate frontmatter property keys across notes, with usage counts and value types.
find_notes_by_property Find notes whose frontmatter has a key (optionally equal to a value, or containing it when the value is a list). Set verbosity=terse to return path only (dropping the matched value). Set nested=true to match a dotted key path. Domain: metadata.
graph_centrality Structural importance of notes in the persisted link graph (THE-452). metric 'pagerank' answers 'what do many notes point at' (power iteration, damping 0.85); metric 'betweenness' answers the different question 'what sits between otherwise disconnected areas' — a bridge note can score high on betweenness with only two links. ANALYTICS ONLY: these scores are never used for retrieval ranking. Notes outside your read scope are excluded from the graph entirely, not just from the output.
graph_communities Community detection over the persisted link graph (Louvain, THE-452). Partitions notes into clusters that link to each other more than to the rest of the vault. Deterministic: the same vault and seed always yield the same partition. ALWAYS read `meaningful` — a modularity below 0.3 means the partition is not distinguishable from chance, and presenting those clusters as 'your vault's topics' would be inventing structure. ANALYTICS ONLY, never used for retrieval ranking.
graph_path_between Trace how one note connects to another through the persisted link graph (THE-452): the shortest chain of notes joining them, with the edge types behind each hop. Undirected by default, because a reader follows a backlink as readily as a link; directed:true answers the narrower 'can I reach B by following links out of A'. Returns connected:false when no chain exists within your read scope.
vault_health_score Composite vault link-health score (0-100) with a breakdown: orphan count, unresolved-link count, hub density, and cycle count over the readable note graph. Domain: links.
find_link_cycles Detect circular internal-link chains (a -> b -> ... -> a) in the readable note graph. Returns up to `limit` cycles as ordered path lists.
get_link_strength Score the connection strength (0-1) between two notes from the link graph: direct edge, co-citation (shared inbound sources), shared outbound neighbors, and undirected graph distance.
suggest_links Suggest notes to link a given note to, from the link graph (co-citation with the note's inbound sources + 2-hop outbound neighbors), excluding notes it already links to. Graph-based (no embeddings).
audit_provenance Provenance audit: flag claim-bearing notes that lack a 'sources' frontmatter field (the evidence a note's claims rest on), and report coverage of sources/confidence/verified across the readable note set. Read-only. Excludes daily notes, templates, and index files by default; tune scope with include/exclude globs and the field name.
list_tags Aggregate all tags (frontmatter + inline) across notes, with usage counts.
get_note_tags Get a note's tags, split into frontmatter, inline, and the combined set.
add_tag Add a tag to a note's frontmatter `tags` list or inline in the body (idempotent). Domain: metadata.
remove_tag Remove a tag from a note's frontmatter, its body, or both (exact, not hierarchical).
find_notes_by_tag Find notes carrying a tag, hierarchically (a query for `project` matches `project` and `project/sub`).
add_vault Register a new vault at runtime (no restart). Validates the path is an existing directory, adds it to the registry, and indexes it for search. Runtime-only — add it to the config file to persist across restarts.
list_vaults List configured vaults and their cache state. Domain: vault.
get_vault Inspect a single vault's configuration and cache state.
reload_vault Re-read a vault's configuration from disk (does not touch the cache).
reset_vault_cache Drop the SQLite cache for a vault (chunks, embeddings, idempotency keys; optionally the event log). Destructive — requires confirmation.
get_outgoing_links List a note's outgoing links (code-block links excluded), each resolved to a target path.
get_backlinks Find every note that links to the given note, with source line/column.
find_orphans Find notes that nothing else links to (optionally also requiring no outgoing links).
find_unresolved_links Find internal links that do not resolve to any note (dangling links).
rewrite_link Repoint every link to `from_target` at `to_target` across the vault. Defaults to dry_run; a real run requires confirmation.
prune_hub_links Prune unresolved and/or duplicate links from a hub note. Defaults to dry_run; a real run requires confirmation.
bulk_set_property Set one frontmatter property across many notes, with per-item results (prev_value). HITL-floored (bulk) and throttled; best-effort by default (stop_on_first_error opt-in).
bulk_move_notes Batch-move notes and rewrite backlinks across the whole link graph (rewrite phase is all-or-nothing). dry_run (default true) previews predicted backlink updates without touching disk. Set overwrite to clobber existing destinations (each is soft-deleted to .trash, recoverable). HITL-floored (bulk) and throttled.
get_server_config Read the non-secret server config: auth mode, server-global read_only + embeddings provider, throttle limits, observability targets, and a per-vault summary (id) plus a detected-plugins map. Never returns secrets.
inspect_acl Test whether a (vault, path, op, scopes) tuple would be permitted. Shares the live path evaluator (read-only kill switch + per-op whitelist) so it cannot drift from enforcement, then checks the op-family scope grant and the path-required rule-scopes (P1.4: a matching rule's scopes must all be held). Reports the matched path rule, the rule-based effective_scopes, and what denied it. Domain: admin.
inspect_visibility Explain why a tool is or is not offered to a caller: returns listed | hidden | disabled | scope_denied | unregistered per tool, plus the RULE that decided it (which name/tag list matched, which required scopes are missing). Pass `scopes`/`read_only` to evaluate a hypothetical caller the way inspect_acl does, `tool` to ask about one, or `visibility` to filter. Shares the registry's own classifier and config, so it cannot drift from what tools/list does. admin:acl-scoped BY DESIGN: distinguishing hidden from unregistered is exactly the existence oracle the unauthenticated surface refuses to be.
get_metrics Snapshot Prometheus-style metrics as structured JSON: per-(vault,tool,status) invocation counters and rate-limit-hit counters aggregated from the local event_log + live limiter, plus uptime/registered-vault/registered-tool gauges. Optionally filter to one vault. Domain: admin.
generate_uri Build an obsidian:// URI for a target (open/search/new/daily/command/hookmark/advanced). Pure string builder — touches no vault state, requires no scope. `vault_name` is the Obsidian DISPLAY NAME (not a vault id) and is used verbatim.
ocr_attachment Run OCR on a single image or PDF attachment via the Text Extractor bridge. Returns extracted text (cached by the plugin per file+model). Domain: attachments.
ocr_bulk OCR a batch of attachments via the Text Extractor bridge. Resolves and ACL-filters the candidate set server-side; requires confirmation past 20 files.
bundle_folder Aggregate all notes under a folder into a single markdown/XML bundle (Smart Context). ACL-filtered; file-count and byte budgeted with an explicit truncated flag. When truncated, resume with the returned cursor; max_files and max_bytes apply per page, so loop until cursor is absent.
bundle_files Aggregate an explicit list of notes into a single markdown/XML bundle. ACL-filtered; byte budgeted; reports missing_paths for files that do not exist.
makemd_list_spaces Enumerate make.md spaces (its alternative to folders) via the companion bridge.
makemd_query Run a make.md query against a space (filter/sort/paginate) via the companion bridge.
read_metadata_fields Read a note's typed metadata fields via the Metadata Menu plugin: returns each configured field's name, value, type, validity, and source (frontmatter vs inline). Read-only field introspection.
query_datacore Run a Datacore query using its own query language (e.g. `@page and #tag`, `@task and $completed = false`) and return matching pages/blocks with their path, name, tags, types, and frontmatter fields. Datacore is Dataview's successor; use search_dql for classic Dataview DQL.
validate_dql Parse a Dataview DQL query without executing it. Returns the AST or a parse-error location.
eval_dataview_field Evaluate a Dataview field expression against a single note (useful for property derivation).
git_status Working-tree status of the vault's git repo (changed/staged/conflicted), via the Obsidian Git companion bridge. Unavailable under a read whitelist (repo status enumerates every path).
git_diff Unified diff for one vault file (working tree, or the staged copy with staged: true), via the Obsidian Git companion bridge.
git_log Recent commits of the vault's git repo (hash/message/author/date), via the Obsidian Git companion bridge. Unavailable under a read whitelist (log messages enumerate paths).
git_stage Stage vault files for the next commit, via the Obsidian Git companion bridge. Write-family: the readOnly kill switch applies.
git_commit Commit the staged changes of the vault's git repo. Always requires human confirmation (execute:git is a HITL-floor family) — a commit is irreversible-in-effect from the agent's side.
refresh_plugin_capabilities Re-probe the companion plugin for a vault and atomically replace the cached capability snapshot, so installing/enabling a plugin or upgrading the companion takes effect WITHOUT a server restart. Returns what changed (companion state, plugin/version deltas), not a bare ok. Admin-scoped, no HITL.
search_omnisearch Ranked full-text search over the vault via the Omnisearch plugin. Returns scored matches with per-note excerpts and matched words. Complements the built-in search domain with Omnisearch's own ranking.
list_tasks List tasks across the vault (or a root/paths subset) with typed status/priority/tag/due filters. Filesystem-only; needs no plugin.
update_task Modify a task in place by line number (status, dates, priority, tags). Reopening a task completed more than 7 days ago requires confirmation.
tasks_filter Run a Tasks-plugin filter expression (its DSL) via the companion bridge, with optional grouping/sorting. Requires the Tasks plugin; if it is unavailable, use list_tasks for native status/priority/tag/due filtering.
list_commands Enumerate available Obsidian commands (optional substring filter). Uses the companion plugin, falling back to Local REST API's native /commands/ route when the companion is unreachable. Domain: automation.
execute_command Fire an Obsidian command by id. Deny-by-default and triple-gated: requires human confirmation (execute:command is a HITL floor), command execution must be enabled for the vault, and the id must be on the vault allowlist. Falls back to Local REST API's native /commands/{id}/ route when the companion is unreachable. Never silently runnable. Domain: automation.
read_excalidraw Read an Excalidraw drawing's raw elements and/or extracted text. source=plugin (default) proxies the live companion plugin; source=filesystem parses the .excalidraw / .excalidraw.md file on disk (works headlessly, no plugin); source=auto tries the plugin and falls back to the filesystem when it is unavailable (THE-202).
create_excalidraw Create a new Excalidraw note via the companion plugin. Overwriting an existing drawing requires confirmation.
update_excalidraw Add, remove, or update elements in an existing Excalidraw note via the companion plugin.
remotely_save_status Last sync state of the Remotely Save plugin (sync status + last successful sync time) — an independent backup-verification signal, via the companion bridge.
remotely_save_trigger Kick off a Remotely Save sync run (fire-and-poll: check remotely_save_status afterwards), via the companion bridge.
list_quickadd_actions Enumerate configured QuickAdd actions (template/macro/capture/multi) via the companion bridge.
trigger_quickadd Fire a QuickAdd action by name. Always requires human confirmation (execute:quickadd is a HITL floor): actions can create or modify notes broadly and run macros.
list_templates List available Templater templates with parsed metadata (user functions, parameters), via the companion bridge. Domain: automation.
execute_template Run a Templater template and write the expanded output to a target path. Always requires human confirmation (write:templater is a HITL floor) because templates can execute arbitrary user JavaScript. Domain: automation.
resolve_daily_note Resolve the daily note for a date (default today) via the core Daily Notes plugin's configured folder + format. Returns whether it exists and its path — no path guessing. Read-only; does not create.
work_episodes List/inspect the raw experiential episode log (management surface, the first-party list/inspect verb). Shows pending and ineligible state for review; tombstoned rows stay hidden unless include_blocked. Partitioned to the calling principal unless any_caller, which requires the admin:workspace scope (P1.7). Set unstamped_debt to see judgeable work that still carries no verdict — yours, or every principal's when combined with any_caller — pair it with `until` to mean 'older than' — then clear it with work_result. Protocol traffic and the verdict verbs themselves never appear there; they are not work anyone can judge.
work_episode_chain Walk an episode's amendment chain in one call. `prev_id` links each episode to the caller's previous one, and following it hop by hop cost one round trip per link. Returns the chain newest-first starting at `id`. The THE-238 reader contract applies at every hop, not just the first: tombstoned rows never surface, expired rows are excluded, and the walk stays inside the calling principal unless any_caller (admin:workspace, P1.7). The walk STOPS at the first hop that fails those filters rather than skipping over it — a gap in a returned chain would itself disclose that a hidden episode exists.
episode_stats Aggregate activity counts over the experiential episode log WITHOUT returning any episode content. work_search/work_episodes are all-or-nothing: seeing activity patterns otherwise requires admin:workspace, which also grants full row content. This returns counts only, so an operator can answer 'what is this agent doing' without reading what it did. Grouping by caller is not offered — the group_by enum excludes it deliberately. Buckets smaller than min_bucket are withheld and summed into `suppressed`, because a count of 1 in a narrow bucket is equivalent to reading the row.
work_forget Tombstone an experiential episode (the THE-238 control-1 blocklist, surfaced as the first-party forget verb). A forgotten episode never surfaces in work_search again; each successful forget appends a THE-239 hash-chained forget_log row for forensics. Idempotent: a repeat call, foreign, or unknown episode id is a silent no-op (forgotten:false) that appends NO additional log row. P1.7: only your OWN episodes unless you hold admin:workspace — a foreign or unknown id is a silent no-op, not an error.
note_quality_report Read-only note-health report from the note_quality rollup (THE-537): which notes are duplicated, orphaned, stale by edit or by access, contradicted, or tombstoned — with the raw components behind each verdict. quality_score is NULL when there is no usage evidence yet, which means UNMEASURED, not bad. Populated by the offline `obsidian-tc note-quality` pass; computed_at tells you how fresh it is. Never used for ranking.
gap_report Read-only view of the latest gap-detector pass (THE-48/THE-616/THE-644): which of the pass's queries scored below the calibrated coverage floor, with their nearest-hit context. Populated by the offline `obsidian-tc gaps` pass; computed_at tells you how fresh it is, and null means no pass has ever been persisted for this vault. Never recomputes — a fresh reading requires re-running the CLI pass. Nearest-hit paths are filtered to the caller's read ACL (THE-563/564) before being returned.
set_goal Record a STATED goal for a vault — what the user is trying to accomplish, as distinct from a learned preference (a preference is 'you tend to X' and never resolves; a goal is 'you intend to X' and ends in completed/abandoned/expired). Goals are stated by the user and never inferred: nothing in the reflect/extract path can write one. An optional target_date lets the expiry sweep mark it 'expired' rather than leaving stale intent to bias later reads.
list_goals List a vault's stated goals, newest first. Defaults to OPEN goals only — a consumer that forgets to filter should see current intent rather than a graveyard of closed ones. Pass status to narrow to a terminal state, or 'any' for the full history. 'expired' (the deadline sweep's verdict) and 'abandoned' (the user's) are deliberately distinct and must not be counted together.
close_goal Close a stated goal into a terminal state: completed or abandoned. Once-only — a second close reports closed:false rather than silently succeeding, and there is no reopen verb, because a system that quietly reopened a goal the user completed is exactly the low-confidence mutation this plane forbids. 'expired' is not settable here; it is the deadline sweep's verdict alone.
record_retrieval_feedback Report which retrieved chunks actually helped. CALL THIS after you act on a search result: feedback (-1|0|+1) = was this the right chunk to return for that query. Stamp the chunks you genuinely used, not every hit, and stamp -1 when a confidently-returned chunk was wrong — a negative is worth more than silence. This is the only signal separating a chunk that gets RETRIEVED from one that gets USED: it feeds the ACT-R activation recompute, so stamping is what makes later retrieval better, and not stamping leaves ranking blind. Judge the RETRIEVAL, not your task: whether the task went well is a different question this tool deliberately no longer accepts (THE-718). Targets your most recent retrieval event(s) for that chunk (last_n, default 1). Returns `updated`; when that is 0 it also returns `reason` — `session_scope` (you own retrievals for this chunk, none in the current scope) or `no_owned_retrievals` (nothing of yours matches), so a no-op is never silent. You may only stamp retrievals your own caller produced (THE-568); an unidentified caller cannot stamp, and admin:workspace crosses both that and the session scope.
work_result Record how the task you just finished went, as -1 (it failed or produced a bad result), 0 (neutral) or +1 (it worked). The verdict applies to every judgeable tool call in your current session that has no verdict yet, and then a fresh window opens — so calling this once at the end of a session covers the session, and calling it after each task partitions the session into those tasks. Protocol traffic and this verb itself are never judged. Nothing else writes agent_episodes.task_result, and two retrieval behaviours read it: a -1 holds those episodes out of promotion, and the preference extractor only ever learns from episodes carrying a verdict.
work_search Search the experiential work-memory (agent_episodes) — what the agent actually did. MEMORY semantics with the THE-238 reader contract enforced: only evaluator-approved (eligible) episodes by default, tombstoned/expired rows never surface, results are partitioned to the calling principal, and a trust floor (default 0.3) excludes high-risk content. include_pending opts into not-yet-evaluated episodes (still trust-floored); any_caller crosses the agent partition and requires the admin:workspace scope (P1.7: the partition is an authorization boundary, not a free filter). `semantic` (THE-642, opt-in) fuses a cosine-similarity channel over `summary` alongside the lexical match via Reciprocal Rank Fusion, so a paraphrased query can find an episode the lexical LIKE match misses — lexical stays the exact-match failsafe for names/dates/ids, and the SAME reader-contract filters above apply to both channels identically (the fused pool is never wider than what lexical alone could already see). Degrades silently to lexical-only when no `query`, no embedding provider is configured, or the provider errors.
list_attachments List attachment files in the vault (filtered by extension, read-ACL aware), with cursor pagination. Optionally count referencing notes per file.
get_attachment Read an attachment's bytes (base64) plus MIME type and size. Fails with invalid_input when the file exceeds max_bytes. Domain: attachments.
move_attachment Move/rename an attachment and repoint note links to it (link style preserved). Crossing a folder boundary or overwriting requires confirmation.
delete_attachment Delete an attachment (to the vault's .trash mirror, or permanently). Destructive — requires confirmation. Reports notes that still reference it.
list_kanban_boards List Kanban board notes in the vault (frontmatter kanban-plugin: board), with column and card counts.
read_kanban_board Parse a Kanban board note into its columns and cards (text + checked state). Domain: structured.
add_kanban_card Add a card to a Kanban column (by name). Appends `- [ ] text` (or `- [x]` when checked) under the column heading, preserving the rest of the board.
move_kanban_card Move a card (matched by text) from one Kanban column to another, preserving its original line (checkbox state, inline metadata).
get_periodic_note Get the periodic note for a period + date (no creation). Resolves the path from the vault's daily/periodic config or Obsidian defaults. Domain: workspace.
create_periodic_note Create the periodic note for a period + date using the configured (or overridden) template. Fails if it already exists. Set expand_template=true to expand the template through Templater (requires write:templater; degrades to a verbatim copy when the companion/plugin is unavailable).
find_or_create_periodic_note Get the periodic note for a period + date, creating it (empty/template) if absent. With expand_template=true a newly created note is expanded through Templater when available (requires write:templater).
append_to_periodic_note Append content to a period's note (creating it if needed), optionally under a heading. idempotency_key is accepted (enforcement lands with the policy layer).
list_periodic_notes Enumerate existing periodic notes in a date range (probes the configured format/folder). Defaults to a recent window when from/to are omitted.
format_table Reformat a GFM markdown table in a note: realign columns to a uniform width, honoring the delimiter row's alignment. Addressed by 0-based table_index within the note. Domain: structured.
insert_table_row Insert a data row into a GFM table. `values` are cell strings (padded/truncated to the column count); `at` is the 0-based data-row position (default: append).
insert_table_column Insert a column into a GFM table: a header plus per-row values (default empty) and an alignment. `at` is the 0-based column position (default: append).
sort_table_by_column Sort a GFM table's data rows by a column (index or header name), ascending or descending, optionally numeric.
read_base Read a .base file's structure (source, views, formulas). Domain: structured.
create_base Create a new .base file from a base definition. Overwriting an existing base requires confirmation.
update_base Patch a .base file's source/filters/properties/views/formulas. Unknown keys are preserved. Changing `source` (deprecated alias) or the note-set-defining top-level `filters` requires confirmation.
query_base Execute a base view and return resolved rows. Filters/formulas may use obsidian-tc's JSONLogic model OR the real Obsidian Bases expression DSL (a documented subset, THE-281); constructs outside the subset — and trees mixing both models — are refused with unsupported_base_filter.
list_workspaces List saved workspace names and the active workspace (.obsidian/workspaces.json).
open_workspace Mark a saved workspace active and return its stored layout. Fails if the workspace does not exist.
save_workspace Save a workspace layout under a name (optionally making it active). Overwriting an existing workspace requires confirmation.
read_canvas Parse a .canvas file into its nodes and edges (JSONCanvas spec).
create_canvas Create a new .canvas with optional initial nodes/edges. Overwriting an existing canvas requires confirmation. Domain: structured.
update_canvas Patch a .canvas: add/remove/update nodes and edges by id. Unknown fields are preserved. Removing more than 10 nodes requires confirmation.
query_canvas Find nodes matching criteria across one or more .canvas files (defaults to all canvases under the vault root).
list_bookmarks List the vault's bookmarks tree (.obsidian/bookmarks.json), preserving groups and unknown fields. Domain: workspace.
add_bookmark Add a bookmark (optionally into a named group, created if absent). A duplicate is a no-op unless allow_duplicate is set. Domain: workspace.
remove_bookmark Remove every bookmark matching the criteria (recursively, or within a named group). Returns the number removed.
search_text Literal text search across vault notes (BM25-ranked). Supports case_sensitive and whole_word; scoped to an optional root folder.
search_regex Regular-expression search across vault notes. Each match returns line/col + the matched text; capped per file. Pattern length is bounded, patterns with nested quantifiers are rejected, and execution is time-budgeted (governor.regexTimeoutMs) to prevent catastrophic backtracking; flags may only be i, m, s, u.
search_semantic Dense-vector retrieval over the chunk store (run index_vault first). Returns the top-k chunks by cosine similarity. verbosity=terse drops chunk content/metadata, returning path/score only.
search_jsonlogic Filter notes with a JSONLogic expression over frontmatter + { path, content }. Returns matching note paths.
search_dql Run a Dataview DQL query via the companion plugin bridge. Returns headers/rows and the matched note paths. Requires the Dataview bridge; reports plugin_missing when it is not configured.
search_vault Unified search dispatch. mode=auto routes a string query text->semantic (fallback on zero hits) and an object query to jsonlogic; or force text/regex/semantic/jsonlogic/dql. Set verbosity=terse to compact each hit to path/score/snippet.
index_vault Chunk and embed the vault (or a folder) into the search index. Incremental: chunks whose content hash is unchanged are skipped; removed chunks are pruned.
delete_note Delete a note (to the vault's .trash mirror, or permanently). Destructive — requires confirmation. restore_note reads its undo from a snapshot, which is captured only when the server's snapshots.enabled config is on; the default \"trusted-local\" posture leaves it on, so a deleted note has a restore_note path back unless snapshots have been explicitly disabled.
read_note Read a note's raw content, parsed frontmatter, body, content hash, and stat. With anchor (same shape as patch_note's: a heading section, a block reference, or the frontmatter preamble), also returns section: the resolved span's text (including its heading/block-id marker line), 1-based start_line/end_line relative to the raw file, and heading_level for a heading anchor. content_hash stays the whole-note hash so it round-trips into patch_note's prev_hash unchanged.
read_notes Batch-read notes. Returns successful notes and a per-path error list (partial).
write_note Create, overwrite, or upsert a note. Optional prev_hash gives compare-and-swap; overwriting a non-empty note requires confirmation. Set provenance: "agent_synthesis" when the content is a derived/inferred conclusion an agent produced (not directly stated in any single source) rather than authored/copied text — this routes the content through a poison scan before the write lands (rejected outright on high risk) and surfaces the assessment in the result; also add source: agent-synthesis to the note\'s own frontmatter by convention.
append_note Append content to a note (optionally creating it), preserving existing bytes. Set provenance: "agent_synthesis" when the appended content is a derived/inferred conclusion an agent produced rather than authored/copied text — this routes the appended content through a poison scan before the write lands (rejected outright on high risk) and surfaces the assessment in the result; also add source: agent-synthesis to the note\'s own frontmatter by convention.
patch_note Insert or replace content (append/prepend/replace/replace_text) relative to an anchor: a heading section, a block reference (anchor:{type:\"block\",block_id}), or the note preamble above the first heading (anchor:{type:\"frontmatter\"}). Frontmatter is preserved. A heading anchor matching more than one line (or a block id on more than one line) is refused rather than silently bound to the first match. On a heading anchor, replace preserves the anchor heading line itself; if content's first non-blank line repeats it (same level and text), that line is dropped so the two calling conventions do not double the heading. replace_text takes old_string/new_string instead of content and substitutes an exact match scoped to the resolved anchor's section — 0 or 2+ matches is refused (with the count for 2+); confirm_replace is ignored for it. A replace on a heading anchor that would discard more than 20 lines AND over half of the note's body (e.g. the note's only H1, which no lower-or-equal heading bounds) is refused unless confirm_replace is set. Snapshots (restore_note's undo) are captured only when the server's snapshots.enabled config is on; the default \"trusted-local\" posture leaves it on, so such a write is rollback-able via restore_note unless snapshots have been explicitly disabled.
list_notes List notes under a folder (read-ACL filtered), with cursor pagination.
note_exists Check whether a path exists in the vault and whether it is a file or folder.
move_note Move/rename a note and update backlinks. Crossing a folder boundary OR overwriting an existing destination requires confirmation; an overwritten destination is soft-deleted to .trash (recoverable).
copy_note Copy a note to a new path (backlinks are not rewritten for copies).
knowledge_get_critical List the critical-severity docs in a vendor / external-docs corpus: the breaking changes, security issues, and production gotchas to read before starting work. A tight metadata pre-filter over frontmatter severity == 'critical', not a search. Optionally narrow by `source` (the vendor or tool the doc is about). Gated on read:docs so it stays isolated from the private vault.
explain_answer Explain what an answer actually used: walks retrieval -> chunk -> citation -> episode for one session or time window and reports each link with how well it is known. Distinguishes a retrieval the citation pass never judged from one it judged and rejected, and a chunk whose note no longer exists from one that was never used. Read-only; reports nothing about paths the caller cannot read.
vault_context Composite budgeted context in ONE call (the Honcho-style context() primitive): graph-reranked chunks packed to a token budget and grouped by note, recent synthesis patterns touching the query, open contradictions on the packed notes, and applicable past lessons (decision/lesson/postmortem chunks relevant to the query) — with source metadata and packing stats. include_work adds eligible work-memory episodes (the THE-229 reader contract; explicit opt-in, never default). Omit query for session bootstrap: the queued thread is read from the memory folder's _next-session.md signal note, so every session opens with its applicable lessons (push, not pull).
reflect The reflect verb (retain/recall/reflect): recall over the vault, then a gateway synthesis pass — one on-demand, query-scoped operation returning a grounded answer with source provenance. mode 'challenge' runs the adversarial red-team over the decision-bearing recall instead (the knowledge_challenge core). persist: true writes the answer as a derived note under the memory folder's reflections/ with source_model + chunk provenance (requires write:notes). Degrades gracefully: without the inference gateway, recall still returns sources with available: false. The sleep-time half (episode-eligibility evaluator + preference profile) runs via the `obsidian-tc reflect` CLI command.
vault_graph_search Cross-domain / multi-hop semantic search with wikilink graph expansion (GraphRAG). Seeds by vector similarity, expands through the links_to graph (vault_edges), and fuses by RRF. Run index_vault first so the edge graph is populated. Returns chunks tagged seed|expansion with hop + via_edge. Optional `vaults[]` federates the same query across additional vaults (max 8), fusing per-vault ranked lists by RRF; each result is tagged with its source vault.
knowledge_search Semantic + keyword search over a vendor / external-docs corpus (a reserved read-only docs vault), with wikilink graph expansion and RRF fusion. The docs-scoped analogue of vault_graph_search: bind `vault` to the docs corpus id. Returns source-attributed chunks tagged seed|expansion. Gated on read:docs so it stays isolated from the private vault.
diagnose_retrieval Explain why a specific note was or was not returned for a query. Re-runs the retrieval pipeline with per-stage tracing and reports, for that one note, where it was present, its score and rank where a stage produces them, and the first stage that dropped it. Read-only and non-mutating; reports nothing about paths the caller cannot read.
list_contradictions List open contradictions (judge_verdict: 'contradiction' | 'tension') touching any of the given notes — the same detector output vault_context/reflect/knowledge_challenge surface indirectly, exposed directly for standalone inspection. Read-only.
knowledge_challenge Red-team a proposal against your documented decision history. Retrieves decision-bearing chunks (02-projects, 04-writing/Published, 09-reference/system-reviews, 09-reference/syntheses) and asks the inference gateway to flag DIRECT_CONTRADICTION / PATTERN_REPEAT / REVERSAL / HIDDEN_DEPENDENCY. Requires the gateway; reports unavailable when it is not configured.
Permissions 5
network medium filesystem low shell high database medium env_vars low