MCP Connector. An MCP server that runs inside Obsidian

Is this plugin open source? Yes
Is this plugin completely free? Yes
Is this plugin vibe-coded beyond the author’s ability to comprehend how it works? No
Community Directory: MCP Connector


The MCP spec picked up a new revision on 2026-07-28: stateless request/response, no protocol sessions, no session header. MCP Connector serves it. It also still serves the 2025-11-25 line, on the same port, URL and token, because that is what shipping clients negotiate today. Both eras sit on one endpoint and nothing you have configured needs to change.

What that buys you now: rename a note in your Prompts folder and a listening client is told to re-read the list, for real. Promote a tool from one client and the others hear about it. On the old revision the plugin now says it cannot send those notifications, which is the honest answer for a POST-only transport. That retraction is why the release was 2.0.0 and not 1.1.0. The official server-stateless conformance suite reports 26 of 28.

On the tool count, before anyone asks. There are 52, and advertising all of them costs your client about 10K tokens of schema per session, which is real money for tools you may never call. So it is a ceiling, not a default you are stuck with. Set a token to Core and its client sees 13 tools plus 3 meta-tools. Set it to Adaptive and it starts there, then promotes a tool once you have called it three times. Whatever stays dark is one call away: calling it returns an error naming the way to switch it on, rather than “Unknown tool”. The setting lives on the token, so Claude Code can hold the full set while another client stays on Core.

The rest, briefly… the server runs inside Obsidian on loopback, and semantic search runs on your machine with no API key.

Two rough edges worth knowing before you install. Claude Desktop refuses to follow an obsidian:// link out of a tool result, so a search hit shows the note’s path instead of opening it. On Windows, mcp-remote hangs on connect, so use the Python bridge in the repo.

Install from Community plugins, search for MCP Connector. Obsidian 1.7.2 or newer.

Repo and issues: GitHub - istefox/obsidian-mcp-connector: Add integrations like semantic search and custom Templater prompts to Claude or any MCP client. · GitHub

I will post future updates in this thread.

Update, since the last post: three releases, 2.2.0 through 2.3.0.

2.2.0. Folder exclusion is now real access control, not just a search filter. Before this, excluding a folder from search_vault_smart still left it fully readable through get_vault_file, list_vault_files, and everything else. A discussion here pointed out directly that therapy notes and financial details deserve better than “the assistant probably won’t search for them.” A new Settings → MCP Connector → Hidden folders list now reaches the whole tool surface: a hidden folder’s files are unreachable for reads, writes, listings, the link graph, tag counts, and prompt discovery, and they behave exactly as if they did not exist. There is no distinguishable “access denied,” since a denial that reads differently from “not found” would itself confirm the folder is there. Three tools reach vault content by a path this can’t filter (execute_obsidian_command, execute_dataview_query, execute_template), so the plugin disables all three outright while any folder is hidden. Full design in ADR-0020.

2.3.0. OpenAI Codex can now connect as an MCP client, contributed by @Neonsy. Codex doesn’t manage one MCP process per task the way Claude does, so this adds an opt-in shared local broker: a single process every enabled vault registers with, that Codex talks to on one stable port. It forwards each authorized request to the right vault’s own server using its current port and token, so rotating a token or restarting Obsidian never requires touching Codex’s config. Settings gives you two explicit options: copy a ready-to-paste config entry, or preview and approve a one-time install into your Codex config. Off by default per vault.

2.2.1 and 2.2.2 were housekeeping: patched 13 dependency vulnerabilities (none with a known exploit path against this plugin, patched proactively) and cleaned up a handful of TypeScript patterns the community review flagged. No functional change.

Full changelog: obsidian-mcp-connector/CHANGELOG.md at main · istefox/obsidian-mcp-connector · GitHub.
I’ll keep posting updates in this thread.

Quick follow-up: 2.3.1, a same-day patch on top of 2.3.0.

The community plugin review flagged a batch of TypeScript warnings in the new Codex broker code from 2.3.0. All cleaned up now: unnecessary escaped quotes and non-null assertions, bare setTimeout/clearTimeout instead of window.setTimeout/window.clearTimeout (needed for correct behavior in an Obsidian popout window), and unsafe JSON.parse results now typed and narrowed properly.

One of these was a genuine, if narrow, correctness fix: a lock-cleanup step could throw and mask the real error a caller was trying to report. It now logs the cleanup failure instead of hiding the original error behind it. No user-visible behavior change otherwise.

Update: 2.3.2, a security fix. If you use folder exclusion, please update.

If you rely on Settings → MCP Connector → Hidden folders, this one matters. A community member testing the feature found that search_vault in Dataview query mode (the tool’s default) could still read files inside a folder you’d hidden. The 2.2.0 folder-exclusion feature already disabled three tools that reach vault content in ways no path filter can cover: execute_obsidian_command, execute_dataview_query, execute_template. search_vault’s Dataview mode uses that same route around the filter, but it was missing from that disabled set, so it stayed active. Its JsonLogic mode was never affected.

Fixed the same day it was reported, by adding search_vault to the disabled set. This bug has been present since 2.2.0, so it affects every version between 2.2.0 and 2.3.1 if you had folder exclusion turned on and used search_vault.

Release: Release 2.3.2 · istefox/obsidian-mcp-connector · GitHub
Issue: search_vault bypasses the folder-exclusion security boundary (dataview mode) · Issue #514 · istefox/obsidian-mcp-connector · GitHub
Fix: fix(mcp-tools): close search_vault folder-exclusion bypass by istefox · Pull Request #515 · istefox/obsidian-mcp-connector · GitHub

Thanks to the reporter for testing this thoroughly instead of taking the settings dialog at its word.

Update: 2.4.0. create_vault_file can no longer silently overwrite a note with a partial rewrite.

A user nearly lost an 18KB note twice: an assistant meant to add a backlink or a date, but sent only that addition as the entire new content of create_vault_file. The note became a four-line stub with no warning. patch_vault_file already guarded against this with expectedContent. create_vault_file never did.

It now takes an optional expectedContent: the whole current content of the file, as the assistant last read it. If it no longer matches, the write is refused instead of quietly replacing the file. A call that omits it, or a path that doesn’t exist yet, behaves exactly as before. create_vault_binary_file gets the equivalent guard as a plain overwrite: true confirmation, since binary bytes have no meaningful diff to compare.

Both are also covered by Settings → MCP Connector → MCP Tools → “Require a write precondition”, the same switch patch_vault_file’s replace mode already required. If you had that switch on, this changes behavior for these two tools: overwriting an existing file through either one now requires the guard.

Also fixed: create_vault_binary_file never held the vault write lock, so two concurrent calls to the same new path could both pass the exists check, and one write could silently overwrite the other. I verified the fix against a real running instance, not just a unit test: two truly concurrent calls to the same new path, one wins, the other is correctly refused, no corrupted bytes.

Full reasoning: ADR-0022 obsidian-mcp-connector/docs/architecture/ADR-0022-write-preconditions-create-tools.md at main · istefox/obsidian-mcp-connector · GitHub
Release: Release 2.4.0 · istefox/obsidian-mcp-connector · GitHub
Issue: [FEATURE] create_vault_file could use a precondition guard, like patch_vault_file's expectedContent · Issue #517 · istefox/obsidian-mcp-connector · GitHub

Thanks to @aardvarkpaul for reporting this and testing the fix end to end before it shipped.

## [2.5.0] — 2026-09-06 — Token usage optimization

2.5.0 is out. It doesn’t add a new tool or a new capability you’ll go looking for. It makes the ones you already have cheaper to use, in the literal sense: fewer tokens spent, so more of your model’s context budget is left for the actual conversation.

Here’s the problem this release goes after. Every time an MCP client (Claude Desktop, Claude Code, whatever you’re using) connects to the plugin, it asks for the full list of tools and their descriptions before it can do anything. That list gets pulled into the model’s context and stays there for the rest of the session. You pay for it once, but you pay for it in full, whether you end up calling three tools or none. On top of that, some of the tools that read from your vault were returning more data per call than anything downstream actually used.

Two places got trimmed.

The tool list itself. A brand new MCP token (the credential a client uses to connect) now starts on a slimmer “adaptive” profile instead of getting every tool description up front. It sees a core set of about 18 tools instead of the full 52, and can activate anything else on demand the moment it actually needs it, through activate_tool. If you’ve already got a working setup, nothing changes for you: this only affects tokens created from now on. The server also now sends a short block of shared instructions at handshake time (things like “paths are vault-relative,” “line numbers start at 0”) instead of repeating those same conventions inside dozens of individual tool descriptions.

Search results. search_vault_simple was returning two things nobody was reading: character offsets for where a match starts and ends inside a line, and, when a note linked out via Dataview, the full link object instead of just the path string. Both are gone now. It also caps how many matches it returns per file, five by default, and tells you when a file had more than that (moreMatches: true), so you know the list was cut rather than that the file only had five matches. Measured on a real vault, a typical search response dropped from around 12 KB down to under 4 KB.

There’s also a small correctness fix bundled in. A bug in how tool schemas get generated was wrapping some boolean parameters, like search_and_replace’s dry_run flag, in a schema shape that some MCP clients apparently choked on intermittently. That’s fixed now. If you’d been running into dry_run getting rejected for no obvious reason, this might be why.

Nothing here is a breaking change. If you don’t touch your token settings, behavior is identical to what you had, just lighter. The full technical writeup, including the exact numbers, is in the changelog and the linked ADR if you want the details.

Thank you! And sorry for the wall of text, but this optimization needed a detailed explanation!

MCP Connector 2.5.1 through 2.6.0: link resolution fixes and a migration path to the lighter tool profile.


2.5.1 fixed a case where find_broken_links and get_outgoing_links wrongly flagged a same-document heading link, [[#Heading]], as broken. The link resolver both tools call returns no match for a linkpath with an empty file portion, which is exactly what [[#Heading]] produces, even though Obsidian itself resolves that shape as “this document” without trouble. A note with several internal navigation links could show every one of them as broken. Reported by @rneilsen.

2.5.2 shipped two fixes. First, the same two link-checking tools missed the opposite case: a cross-file link with a heading or block subpath, [[Note#Heading]] or [[Note#^block]], was treated as resolved just because it started with #, and the full linktext, subpath included, went unvalidated into Obsidian’s own path lookup. Both tools now validate the subpath for real, through Obsidian’s resolveSubpath.

Second, and more serious: five tools that write to a specific section by heading, patch_active_file, patch_vault_file, append_to_periodic_note, get_vault_file_partial, and get_note_outline, each ran its own hand-rolled heading matcher, and the three had drifted apart. One of them trusted a stale cache entry as long as the leaf heading text still matched, even after that heading moved to a different parent section. A write aimed at a nested heading could land under the wrong parent with no error. All five now share one resolver. Matching is case-insensitive everywhere except rename_heading, which stays case-sensitive on purpose. An ambiguous target is now always a hard error instead of a guess, and a cache hit is trusted only once it’s confirmed against a fresh read of the file. get_note_outline’s anchor field changed too: it now returns the actual heading text instead of a slug that never matched Obsidian’s own link format.

2.6.0 adds a migration path. 2.5.0 gave new MCP tokens a lighter default: instead of loading all roughly 52 tools up front, a new token starts with a smaller core set and activates the rest on demand. That only applied to tokens created after 2.5.0 shipped. This release lets you move an existing token onto the same profile, from Settings, Access Control.

It’s a per-token toggle, not an automatic switch. It stays disabled with a “Ready in N days” countdown until the token has 14 days of observed usage to base the migration on, and before you confirm anything it shows exactly which tools would go inactive. Confirming pre-loads the “promoted” list from what the client has actually been calling, so nothing it regularly uses goes dark, and shows a notice with the deactivated count and a pointer to activate_tool for anything you need back. A client connected on the newer 2026-07-28 protocol gets a live tool-list update; the older stateless transport has no channel for that, so the in-app notice is what you get.

Turning the toggle back off reverts to the full tool list immediately, no confirmation needed, and nothing is lost. Usage history carries over the round trip..