obsidian-tcBLOCK
Obsidian Turbocharged — governed, agent-ready Obsidian MCP server. 163 tools across 31 domains, multi-vault native, pluggable embeddings. TypeScript + Rust. AGPL-3.0-only.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Obsidian Turbocharged — governed, agent-ready vault access over MCP.
[](https://www.gnu.org/licenses/agpl-3.0)
What it is
obsidian-tc is a governed, agent-ready Model Context Protocol server for Obsidian vaults, for humans and agents alike. Instead of raw filesystem access to years of notes, every tool call runs through one pipeline — auth, folder ACLs, a read-only kill switch, HITL confirmation on destructive ops, and an audit log. It also adds fused retrieval (full-text, vector, graph) and a memory tier — episodes, decay, forgetting — living inside your vault under that same ACL. A full tool surface across every domain (all visible by default; a smaller set with opt-in profile: "core"), via a 3-tool discovery facade plus the standard search/fetch pair, listed in the tool catalog. Pitch: docs/WHY.md.
60-second start
No install:
npx obsidian-tc /path/to/vault
Every note tool and lexical search work immediately. Semantic search defaults to a bundled embedder — see When NOT to use for which install methods it reaches.
For multi-vault, auth, or ACLs, use a config file:
npm install -g obsidian-tc obsidian-tc ./obsidian-tc.config.json # Node >= 24 or Bun >= 1.1
Also ships as a Docker image, .mcpb bundle, and standalone binaries. More: docs/QUICKSTART.md.
When NOT to use obsidian-tc
Honest guidance — this is a heavier product than most:
- Smallest possible footprint, read-only access, or no MCP at all. A single trusted human
over one vault, a read-only wrapper, or the Ob
ae1e9d4020d0OBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add obsidian-tc -- npx -y [email protected]
Exposed tools (128)
102 read · 20 write · 6 destructive. Blast radius: 6 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
aborts_in_precheck | read | d |
append_note | read | Append content to the END of a note (optionally creating it with create_if_missing: true), preserving existing bytes. It takes no anchor: to add under a specific heading, or anywhere other than the end, use patch_note instead. Set provenance: |
array_or_object | read | a union that admits an array |
bad_out | read | commits then violates its output schema |
big | read | overflows the governor |
big_keyed | write | big keyed write |
big_keyed2 | write | big keyed write with a side effect |
block_until_signal | read | test-only: resolves once ctx.signal aborts or a safety timeout fires |
boom | read | d |
call_capability | write | Invoke a capability by name with its arguments. Routes into the same authorization, ACL, HITL, idempotency, and rate-limit pipeline as a direct tool call, so every safety gate applies and the target |
clash_tool | read | the flat one |
commit_wiki_page | write | Apply a wiki changeset in one step: a new page (path, frontmatter, the body you wrote) plus patches to existing pages that link them to it, from draft_wiki_page. The page must be inside the vault |
concept | read | An idea or term |
copy_note | read | Copy a note to a new path (backlinks are not rewritten for copies). |
count_items | read | test-only |
danger | read | destructive |
danger_write | write | test-only destructive tool |
decompose_and_research | read | Answer a compound question by decomposing it into facets, retrieving per facet, and synthesizing with citations and open questions. |
delete_note | destructive | Delete a note (to the vault |
describe_capability | read | Return the full input schema, required scopes, and safety hints (read-only / destructive) for a single capability by name. |
destroy | destructive | x |
double_gate | read | test-only dispatch-gated tool whose handler ALSO calls requireConfirmation |
draft_wiki_page | read | Plan a new wiki page WITHOUT writing anything: the step between find_existing_page and commit_wiki_page. Give a topic (and optionally a page |
drifter | read | returns a number where its schema promises a string |
dup_tool | read | x |
fast | read | d |
find_capability | read | Search this server |
find_connections | read | Find and explain how notes relate to a topic or note. |
fixture_tool | read | Does a thing with <angle> brackets | and a pipe. |
flaky | read | throws before any effect |
guarded | read | destructive with a precheck that always rejects |
honest | read | matches its schema |
keyed | write | keyed write |
knowledge_get_critical | read | 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 == |
knowledge_search | read | 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 |
kv_put | write | keyed write |
limit | read | How many recent notes to review (default 20) |
list_contradictions | read | List open contradictions (judge_verdict: |
list_notes | read | List notes under a folder (read-ACL filtered), with cursor pagination. response_format=concise returns {vault, notes: [{path}], next_cursor}, without size, mtime, folder and total_returned. |
live_target | read | target chosen by live state |
max_variants | read | How many additional phrasings to fan out over (1-8, default 4) |
mismatch_tool | read | test-only tool whose handler hashes a fresh nonce every call, on purpose |
move_note | write | 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). |
needs_write | write | test-only tool requiring a write scope |
nested_test_tool | read | test-only tool with a nested strict object |
net_index | read | stands in for index_vault: long, and sends content to an external provider |
no_vault_echo | read | takes no vault at all |
noop | read | test-only |
note_exists | read | Check whether a path exists in the vault and whether it is a file or folder. |
note_mutate | destructive | read or delete a note, by action |
object_union | read | all-object union keeps the fold |
observe | read | d |
ok_tool | read | no-op precheck |
optional_vault_echo | read | vault is already optional |
other | read | other keyed |
oversized_echo_parity | read | returns a payload over the configured ceiling |
patch_note | write | Anchored edit. |
path | read | Vault-relative path to the note (e.g. projects/foo.md) |
peek | read | reports whether the signal was installed |
ping | read | d |
plain | read | d |
plain_object | read | constrained output |
plain_string_vault_echo | read | a |
plain_write | write | no resolvePolicy at all |
probe | read | test-only: reports the session the context carries |
probe_batch | write | test-only multi-note write |
probe_hash | read | test-only |
probe_idem | read | test-only |
probe_noop | read | test-only |
probe_plain | read | test-only |
probe_read | read | test-only |
probe_retrieval | read | test-only: logs one retrieval hit under whatever session the context carries |
probe_skipped_patch | write | test-only partial batch |
probe_w | read | test-only |
probe_write | write | test-only write |
proxy_array | read | unconstrained output; the backend returned an array |
proxy_scalar | read | unconstrained output; the backend returned a primitive |
purge | destructive | destructive |
question | read | The compound or multi-facet question to research against the vault |
read | read | x |
read_it | read | reads a declared path |
read_note | read | Read a note. |
read_notes | read | Batch-read notes. Returns successful notes and a per-path error list (partial). The response is held under the server |
read_probe | read | test-only |
read_resources | read | Batch resources/read: read many obsidian-tc://<vault>/<path> note resource URIs in one call. Returns one result per URI in request order: {ok: true, uri, mimeType, text} (identical to a single resources/read) or {ok: false, uri, error} for a malformed or unsupported URI, another vault |
read_thing | read | scoped read |
recent_changes_digest | read | Summarize what changed in the vault recently. |
reflect | read | 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 |
renamed_mutator | read | mutates, gated by acl.readOnly |
renamed_vault_echo | read | echoes vault_id |
renamed_write | write | declares pathAcl(write); handler never calls enforcePathAcl itself |
rendezvous | read | test-only: completes only once |
reset_vault_cache | destructive | Drop cache. |
rollback_fault | read | fails inside a transaction whose ROLLBACK then also fails |
rr_write | write | test-only mutating tool |
scope_free_probe | read | test-only, declares no scopes (like server_health) |
scope_parity_probe | read | THE-514 parity probe — requires read:notes like resources/read does |
scoped | read | requires a scope the caller lacks |
search_and_read | read | Search a vault and return the top-k full notes in one call, instead of a search followed by read_notes. Ranking is vault_graph_search |
seq_step | read | ordinary keyed tool |
shared_tool | read | same text |
signals_then_succeeds | read | signals, then returns normally so #13 |
slow | read | d |
slow_step | read | signals, then awaits so a second dispatch can overlap it |
slow_thing | read | test-only task-augmentable tool |
slow_tool | read | test tool needing several event-loop turns |
sneaky | destructive | declares read, resolves delete |
summarize_note | read | Summarize a single vault note. |
synthetic_write | write | test-only: declares pathAcl(write) but its handler never calls enforcePathAcl |
t | read | x |
titled | read | titled desc |
topic | read | A topic, question, or note path to explore connections for |
touch_active | read | test tool whose target is resolved at dispatch |
two_step | read | commits effect #1, signals, then fails on later work |
txn_step | read | signals inside its own transaction, which then rolls back |
unserializable | read | commits then returns a BigInt payload |
vault_echo | read | echoes the vault arg |
vault_echo_parity | read | echoes the vault arg |
vault_graph_search | read | 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 |
walker | read | reports three steps |
wbulk | read | bulk key |
whoami | read | test-only: echoes the caller context it was dispatched with |
wide_test_tool | read | test-only tool with four required fields |
wopts | write | write options key |
write_note | write | writes |
writer | write | test-only: needs write:notes, to see a narrowed grant refuse a real call |
x | read | a | b\nc |
y | read | a\\|b |
Trust audit
BLOCKgrade F · trust 29/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (11 observation(s))
- Network
- declared (5 observation(s))
- Shell
- declared (9 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
exec(sql: string) {exec(sql: string): void;
exec(sql: string): void;
const out = parseOut(await exec(argv));
"Current mechanism (per-agent JSON, ~/.aws/amazonq/cli-agents/<agent>.json) — add to that",
"Legacy mechanism (~/.aws/amazonq/mcp.json) — only read if the agent's own JSON sets",
const BIDI_OVERRIDE = /[--]/;
const INVISIBLE_CONTROLS = /[---]/gu;
homoglyph (fullwidth "ignore") and interleaved-invisible ("ignore ... instructions")const EXFIL = [
/\b(?:send|forward|post|upload|exfiltrate)\s+(?:this|that|it|the\s+\w+)\s+to\s+\S+/i,
if (EXFIL.some((p) => p.test(scan))) signals.push("exfil");if (signals.includes("override") || signals.includes("exfil")) risk = "high";{ sel: (q) => q.baseline.ndcg_at_10, label: "ΔnDCG@10 " },{ sel: (q) => q.baseline.recall_at_10, label: "Δrecall@10" },{ sel: (q) => q.baseline.mrr_at_10, label: "ΔMRR@10 " },if (primary) process.stdout.write(`\n ${describePower(primary.deltas, "power ΔnDCG@10 ")}\n`);{ sel: (q) => q.graph.ndcg_at_10, label: "ΔnDCG@10 " },const ZERO_WIDTH = /[-]/;
const INVISIBLE_CONTROLS = /[---]/gu;
out = out.split(s).join(`${s[0]}${s.slice(1)}`);{ rec_txt: "Access key: AKIAABCDEFGHIJKLMNOP", score: 0.95 },expect(aws?.text).toContain("AKIAABCDEFGHIJKLMNOP"); // adapter maps raw text; redaction is ingestAmbient's jobexpect(awsRow?.content).not.toContain("AKIAABCDEFGHIJKLMNOP");const secret = "AKIAABCDEFGHIJKLMNOP"; // AKIA + 16 chars: matches the AWS-key pattern exactly
Gates applied: no_behavioural_pass.
ae1e9d4020d0full audit observations/trust-audit/mcp-server/the-40-thieves__obsidian-tc.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | ae1e9d4020d0 | BLOCK | F | 29 | first audit |
Questions
What is the obsidian-tc MCP server?
Obsidian Turbocharged — governed, agent-ready Obsidian MCP server. 163 tools across 31 domains, multi-vault native, pluggable embeddings. TypeScript + Rust. AGPL-3.0-only.
What tools does obsidian-tc expose?
128 in total: 102 read-only, 20 that write, and 6 that can delete or overwrite (delete_note, destroy, note_mutate, purge, reset_vault_cache). Every one is listed on this page with its risk.
Is obsidian-tc safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (29/100) and found 9 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 6 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does obsidian-tc need?
It reads BGE_AUTH_TOKEN, CRAWL4AI_API_TOKEN, DOCGEN_LLM_KEY, LANGEXTRACT_API_KEY, LINEAR_API_KEY, LITELLM_AGENT_KEY, MY_GATEWAY_KEY, MY_TS_KEY, OBSIDIAN_TC_AS_SETUP_TOKEN, OBSIDIAN_TC_GATEWAY_TOKEN, OBSIDIAN_TC_JWT_SECRET and OBSIDIAN_TC_LIVE_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does obsidian-tc run?
It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @the-40-thieves/obsidian-tc-shared at 1.32.0.
How current is this page?
The grade is for one exact copy of the source (ae1e9d4020d0), read on 2026-10-11. The repository is watched and re-audited when it changes.