obsidian-mcp-resilient-bridge
Provides resilient access to an Obsidian vault by bridging to the Obsidian MCP plugin, exposing vault tools and resources to the MCP client and automatically reconnecting when Obsidian is closed or restarted.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@obsidian-mcp-resilient-bridgesearch my vault for notes tagged #meeting and summarize the key action items"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
obsidian-mcp-resilient-bridge
A persistent MCP bridge that keeps Claude Code connected to your Obsidian vault even when Obsidian is closed, restarted, or wasn't running yet when the session started.
Problem
The standard way to connect Claude Code to Obsidian is npx mcp-remote pointed at http://localhost:22360, the local server the "Claude Code MCP" Obsidian plugin exposes. This works, but it's fragile in a specific way:
mcp-remoteconnects to that upstream server exactly once, at the moment Claude Code starts the session.If Obsidian is closed at that moment, or if Obsidian is closed or restarted at any point during the session, that connection attempt fails or the existing connection drops.
Claude Code does not reconnect a failed or dropped MCP server transport on its own. The only way to get the connection back is a full restart of the Claude Code session.
In practice: open Obsidian a few seconds after starting Claude Code, or let it crash, update, or close mid-session, and your Obsidian tools are gone until you restart the whole session.
Related MCP server: obsidian-mcp-server
Solution
index.mjs is a small persistent Node.js process, built on @modelcontextprotocol/sdk, that sits between Claude Code and the Obsidian plugin and never dies because of Obsidian:
Downstream side (toward Claude Code): an MCP
Serveron aStdioServerTransport. This side is intentionally bulletproof - stdout is a pure JSON-RPC channel to Claude Code, and the process trapsuncaughtException/unhandledRejectionso nothing on the Obsidian side can ever crash it or close the stdio pipe.Upstream side (toward Obsidian): an MCP
Clienton anSSEClientTransportpointed at the Obsidian plugin's local server. This side runs its own infinite reconnect loop: on failure or disconnect, wait 3 seconds and try again, forever, for as long as the bridge process is alive.While Obsidian is unreachable, tool calls from Claude Code don't crash or hang - they return a normal MCP tool result with a polite "Obsidian isn't running right now, reconnecting automatically" error, so Claude just sees a tool error and can retry a moment later instead of losing the whole MCP connection.
Because the bridge itself never disconnects from Claude Code, Claude Code only needs to start it once per session. Obsidian can be closed, reopened, or restarted any number of times after that, and the bridge silently reconnects in the background within a few seconds.
One case this alone doesn't fully cover: Claude Code asks the bridge for its tool list exactly once, at the very start of the session, and never asks again for the rest of that session - even after the bridge later sends a "tools changed" notification. So if Obsidian isn't open yet at the moment the session starts, that first request has nothing to report. To soften this, the bridge gives that one first request a short grace period (OBSIDIAN_MCP_STARTUP_GRACE_MS, see below): instead of answering empty immediately, it waits and keeps retrying the connection in the background, and answers with the real tool list the moment Obsidian shows up within that window. Open Obsidian while the window is still running and you're covered with no restart. If the window runs out first, you still need one session restart - this is a known, intentional Claude Code limitation (it doesn't refresh a session's MCP tool list on the fly), not something a bridge process can work around from the outside.
What's in this repo
index.mjs,package.json- the resilient bridge itself. Written from scratch for this repo, MIT licensed.obsidian-plugin/- an included copy of the "Claude Code MCP" Obsidian plugin (idclaude-code-mcp) by iansinnott, original repo obsidian-claude-code-mcp, 0BSD license. This is the plugin that actually runs inside Obsidian and exposes your vault as MCP tools onhttp://localhost:22360. It's bundled here as-is (unmodifiedmain.js,manifest.json,styles.css) so that a clone of this one repo is everything you need, with no extra repo to find or trust. Seeobsidian-plugin/LICENSEand the Credits section below for attribution.
If you're an AI agent setting this up for someone
Follow these steps in order. Steps 1, 2, 3 and 5 you can do yourself. Step 4 is the one thing you can't do - it's a GUI click only the human can make.
Clone this repository into a permanent folder (not a temp directory - the config in step 5 will point at this exact path for the life of the setup):
git clone https://github.com/nekko4044-lgtm/obsidian-mcp-resilient-bridge.git cd obsidian-mcp-resilient-bridgeInstall dependencies:
npm installInstall the bundled plugin into the human's vault. If you don't already know the vault path, ask the human for it. Then copy the contents of
obsidian-plugin/into<vault>/.obsidian/plugins/claude-code-mcp/, for example:mkdir -p "<vault>/.obsidian/plugins/claude-code-mcp" cp obsidian-plugin/main.js obsidian-plugin/manifest.json obsidian-plugin/styles.css "<vault>/.obsidian/plugins/claude-code-mcp/"Ask the human to enable the plugin manually. In Obsidian: Settings → Community plugins → find "Claude Code MCP" → toggle it on. This is a GUI action you cannot perform on their behalf.
Add or update the
obsidianentry undermcpServersin~/.claude.jsonand~/.claude/settings.json, using the absolute path to theindex.mjsyou cloned in step 1:"obsidian": { "type": "stdio", "command": "node", "args": ["/ABSOLUTE/PATH/TO/CLONE/index.mjs"] }Tell the human to restart their Claude Code session once. MCP server configuration is only read at session start, so this one restart is required. After that, they should not need to restart Claude Code again just because Obsidian was closed, reopened, or restarted mid-session - the bridge handles that on its own from now on. The one scenario that can still need a restart is Obsidian not being open yet when a new session starts: the bridge waits up to
OBSIDIAN_MCP_STARTUP_GRACE_MS(10 seconds by default, see Limitations below) for Obsidian to appear before giving up for that session - open Obsidian within that window and no restart is needed, otherwise one restart is.
Manual setup instructions for humans
If you don't have an AI agent handling this for you, the same steps by hand:
Clone this repo somewhere permanent (not
Downloadsor a temp folder):git clone https://github.com/nekko4044-lgtm/obsidian-mcp-resilient-bridge.git cd obsidian-mcp-resilient-bridge npm installCopy the plugin into your vault. Replace
<vault>with the full path to your Obsidian vault:mkdir -p "<vault>/.obsidian/plugins/claude-code-mcp" cp obsidian-plugin/main.js obsidian-plugin/manifest.json obsidian-plugin/styles.css "<vault>/.obsidian/plugins/claude-code-mcp/"In Obsidian, open Settings → Community plugins, and enable "Claude Code MCP". You may need to reload plugins or restart Obsidian first for it to show up in the list.
Open
~/.claude.jsonand~/.claude/settings.json, find themcpServerssection (or add one), and add or replace theobsidianentry with:"obsidian": { "type": "stdio", "command": "node", "args": ["/full/path/to/obsidian-mcp-resilient-bridge/index.mjs"] }Use the actual full path to
index.mjsfrom step 1, not the placeholder above.Quit and restart your Claude Code session. This is the only restart you should need for closing or reopening Obsidian during a session. The one case that can still need a restart is starting a new Claude Code session while Obsidian isn't open yet - the bridge waits up to
OBSIDIAN_MCP_STARTUP_GRACE_MS(10 seconds by default) for Obsidian to appear before that session gives up; open Obsidian within that window and you're fine, otherwise restart the session once Obsidian is running. See Limitations.
How it works
Architecturally, index.mjs is a single Node process wiring together two independent MCP connections:
Claude Code <--stdio (JSON-RPC)--> [ this bridge ] <--SSE--> Obsidian plugin (localhost:22360)On startup, the bridge connects its
StdioServerTransportto Claude Code immediately and unconditionally. This side is expected to stay connected for the entire Claude Code session.It then starts a single background loop (
maintainUpstreamConnection) that is the only place allowed to initiate an upstream connection attempt, so there's never more than one connect attempt in flight. On any disconnect or failed attempt, it waitsRECONNECT_DELAY_MS(3000ms) and tries again, indefinitely.All downstream MCP requests (
tools/list,tools/call,resources/list,resources/read,prompts/list,prompts/get, etc.) check the live upstream connection state before forwarding. If upstream isn't connected, list-type requests degrade to empty results, and call/read/get-type requests return a clear error instead of hanging or throwing.When the upstream reconnects successfully, the bridge sends a
notifications/tools/list_changednotification downstream so Claude Code knows to refresh its view of available tools.The very first
tools/list,resources/listandprompts/listrequest of the process each get a one-time startup grace period: if the upstream isn't connected yet when that first request arrives, the bridge holds the response open (retrying the connection in the background on its normal 3-second cycle) for up toOBSIDIAN_MCP_STARTUP_GRACE_MSbefore answering. If Obsidian connects within that window, the real list goes back instead of an empty one. If not, it falls back to the empty-list response and behaves exactly as before for the rest of the session - every later call of the same kind answers instantly from current state, no grace period applied again. See Limitations for why this only helps, not fully solves, one specific scenario.All logging goes to
stderronly -stdoutis reserved exclusively for the JSON-RPC protocol with Claude Code, since writing anything else there would corrupt the stdio transport.The upstream URL can be overridden with the
OBSIDIAN_MCP_URLenvironment variable if your Obsidian plugin is configured to listen somewhere other than the defaulthttp://localhost:22360/sse.
Limitations
Claude Code reads a session's MCP tool list exactly once, at session startup, and does not refresh it later - even when the bridge sends notifications/tools/list_changed after Obsidian reconnects. This is a known, currently-not-planned limitation of Claude Code itself, not something fixable from inside an MCP server process. It splits into two very different cases:
Scenario | Outcome |
Obsidian is open at session start, then closes/reopens/restarts mid-session | Fully solved. The bridge transport to Claude Code never drops; tool calls degrade to a friendly error while Obsidian is unreachable and recover automatically once it's back. No restart, ever. |
Obsidian is not yet open at the moment a new Claude Code session starts | Softened, not solved. The bridge holds the session's first |
To make the grace window longer (e.g. if you're often slow to open Obsidian after starting a session), set OBSIDIAN_MCP_STARTUP_GRACE_MS (milliseconds) on the bridge process. The easiest way is via claude mcp add's -e/--env flag when you first register the server:
claude mcp add obsidian -e OBSIDIAN_MCP_STARTUP_GRACE_MS=20000 -- node /full/path/to/obsidian-mcp-resilient-bridge/index.mjsOr, if you already have an obsidian entry under mcpServers in ~/.claude.json / ~/.claude/settings.json, add an env object to it directly:
"obsidian": {
"type": "stdio",
"command": "node",
"args": ["/full/path/to/obsidian-mcp-resilient-bridge/index.mjs"],
"env": {
"OBSIDIAN_MCP_STARTUP_GRACE_MS": "20000"
}
}Keep it reasonably conservative - it delays how long the very first tools/list response can take when Obsidian isn't up yet, and an excessively long value risks running into whatever timeout Claude Code itself applies to that startup request. The 10-second default is chosen to stay safely under that without knowing its exact value; set OBSIDIAN_MCP_STARTUP_GRACE_MS=0 to disable the grace period entirely and go back to always answering instantly.
License
The bridge itself (index.mjs, package.json, everything in the repo root) is MIT licensed - see LICENSE.
obsidian-plugin/ is a separate, included copy of a third-party project and is licensed under 0BSD - see obsidian-plugin/LICENSE. It is not covered by the root MIT license.
Credits
obsidian-plugin/ bundles a copy of the "Claude Code MCP" Obsidian plugin by iansinnott (original repo: obsidian-claude-code-mcp, 0BSD license), included here unmodified so the whole setup works from a single clone. All credit for making Obsidian speak MCP in the first place goes to that project - this repository just makes the Claude Code side of the connection resilient.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Share context and questions between Claude instances — VS Code, claude.ai web, and mobile.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude Code and Claude Desktop to interact with Obsidian vaults through MCP protocol. Supports file operations, workspace context access, and dual transport (WebSocket and HTTP/SSE) for AI-powered assistance with your notes.352BSD Zero Clause
- AlicenseNot gradedqualityDmaintenanceConnects Claude.ai to your local Obsidian vault for full CRUD access, search, and daily note creation via the Model Context Protocol.57 npm14MIT
- FlicenseNot gradedqualityCmaintenanceEnables Obsidian vault to act as an MCP server for Claude and as an MCP client to external servers like MCP ANA PJe, allowing seamless interaction between notes and legal case systems.-
- AlicenseAqualityCmaintenanceA local MCP connector that lets Claude read, write and search any Obsidian vault directly from disk.20MIT