obsidian-mcp-router
Routes AI tool calls to multiple Obsidian vaults (local or remote) via the Local REST API plugin, enabling operations such as reading/writing vault files, searching, managing frontmatter, executing templates, and cross-vault fan-out searches.
Click on "Install 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-routersearch all vaults for 'project notes'"
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-router
đŹđ§ English version below â đ«đ· version française
An MCP server that routes Claude tool calls to multiple Obsidian vaults â local or remote â over the Local REST API plugin.
Instead of registering one MCP per vault (one process, one port, one API key), this router exposes a single MCP that knows about every vault you've configured. Each tool takes a vault parameter (or uses your default), and the router fans out the HTTPS call to the right Obsidian instance.
Why
If you keep more than one Obsidian vault â local or remote, in any combination â you don't want to register a separate MCP server per vault and switch context every time. This router is one process that knows about all of them and routes each tool call to the right one based on a vault parameter.
What you get:
One MCP entry in
~/.claude.json(user scope) â all vaults visible from any Claude Desktop/Code session.Local + remote vaults, treated identically. Drop the URL + API key into the config; the router doesn't care where the vault actually runs.
Cross-vault search: pass
vault: "*"to thesearchtool to fan-out across every vault in parallel.
Related MCP server: obsidian-mcp
Capabilities
Tool surface | Coverage |
Vault discovery |
|
Reads |
|
Writes |
|
File management |
|
Templater |
|
Router state |
|
Conversion (v0.11+) |
|
Web/page metadata |
|
Context & graph |
|
Cross-vault | every tool accepts |
Semantic search (search_smart) and Templater execution (execute_template) require the obsidian-mcp-router-bridge plugin to be installed in each target vault â it registers the matching /search/smart and /templates/execute routes on Local REST API. The conversion tools require Python 3.10+ on PATH so the postinstall can install markitdown[all] into a local .venv â see the Conversion tools â runtime dependencies section below. Everything else works against the standard Local REST API endpoints alone.
Deployment modes
The router runs in two modes, controlled entirely by environment variables â no code change, no separate binary:
Local mode (default, v0.8.x compatible)
No env vars set. Single binary, stdio MCP transport, registered once in ~/.claude.json user scope. The router sees every vault listed in ~/.claude/obsidian-mcp-router/config.json. This is what you get when you follow the install steps below â it's how the project has worked since day one.
Multi-tenant mode (v0.9.0+, opt-in)
Three independent env vars turn the router into a scoped instance â useful when you run multiple copies behind a hub (MCPHub, mcpo, a custom proxy) and want each instance to expose a different subset of vaults to a different user.
Env var | What it does | Default when unset |
| Whitelist of vault names this instance sees. Comma-separated, spaces tolerated. Vaults outside the list are moved to | All vaults visible |
| A vault defined entirely in an env var (JSON) â editable from the MCPHub dashboard. A 3rd config source merged after | (none) |
| Disable write tools. The 8 write tools ( | Write tools enabled |
| Audit log: every successful write call appends a line | No audit log |
The three vars compose freely: an instance can be scoped to one vault (ALLOWED_VAULTS=karine) AND read-only (READONLY=true) AND attribute writes (USER_ID=karine-guest). Setting none = v0.8.x behavior exactly.
Concrete deployment example (MCPHub mcp_settings.json entry):
"obsidian-router-roland": {
"command": "obsidian-mcp-router",
"env": {
"OBSIDIAN_ROUTER_ALLOWED_VAULTS": "roland,tribu,projects",
"OBSIDIAN_ROUTER_USER_ID": "roland"
}
}See wiki/obsidian-mcp-router sur Dedibox et MCPHub/ in the opsidian-mcp-router et bridge meta vault for the complete multi-tenant deployment recipe (bundle .mcpb, MCPHub Keys with Access Scope, NPM front, Self-hosted LiveSync, etc.).
Slash commands & skills (Claude Code plugin)
The repo doubles as a Claude Code plugin marketplace that exposes 38 slash commands under the /obsidian-router:* namespace. Type /obsidian-router: in Claude Code â the autocomplete shows everything. Every slash command also auto-triggers on natural-language phrasing (EN + FR) so you rarely have to remember the exact name â just describe what you want.
đ Quick reference PDF (router overview + setup + config + every slash command with NL trigger phrases) â English · Français. 5 pages, accessible font sizes for printing or screen reference.
đ§ 14 MCP wrappers â one per core vault tool
discover/ (2)
Command | Effect | Trigger phrasings |
| List every configured vault (local + remote) with online/offline/latency, default-vault, lock state | "list my vaults", "are my vaults online" / "liste mes vaults", "mes vaults sont-ils en ligne" |
| List files and subdirectories of a vault path | "list files in Sessions", "what's in " / "liste les fichiers de Sessions", "qu'est-ce qu'il y a dans " |
read/ (4)
Command | Effect | Trigger phrasings |
| Read a file in full (markdown + frontmatter + meta) | "show me X", "open the file X" / "montre-moi X", "ouvre le fichier X" |
| Plain-text (substring) search with surrounding context | "find in my vault", "grep for X" / "trouve dans mon vault", "grep " |
| Semantic search via Smart Connections (cosine scores + breadcrumbs) | "find notes about X", "semantic search for X" / "trouve mes notes sur X", "recherche sémantique sur X" |
| Read frontmatter (whole object or one key, types preserved) | "what's the status of X", "show me the metadata of X" / "quel est le statut de X", "montre les méta de X" |
write/ (5)
Command | Effect | Trigger phrasings |
| PUT â create a new file or replace an existing one | "create a note X", "save this as X.md" / "crĂ©e une note X", "enregistre ça comme X.md" |
| POST â append to an existing file (auto-creates if missing) | "append to my journal", "add a line to X" / "ajoute Ă X", "rajoute Ă la fin de X" |
| Surgical PATCH on heading / block / frontmatter | "edit the X section in Y", "replace the content under X" / "édite la section X dans Y", "remplace le contenu sous X" |
| Set/replace a single frontmatter key | "set status to closed on X", "tag this with X" / "passe le statut de X à closed", "tag ça avec X" |
| Apply multiple frontmatter updates in sequence | "on X set status=closed outcome=tp1" / "sur X mets status=closed outcome=tp1" |
manage/ (2)
Command | Effect | Trigger phrasings |
| Move or rename a file (GET â PUT â DELETE) | "rename X to Y", "move X into " / "renomme X en Y", "dĂ©place X dans " |
| Delete a file (with two-step confirm guard) | "delete X" (preview), "yes confirm=true" (proceed) / "supprime X" puis "oui confirm=true" |
template/ (1)
Command | Effect | Trigger phrasings |
| Execute a Templater template (preview or save) | "render Templates/X.md with arg1=v1", "run the daily template" / "rends Templates/X.md avec arg1=v1", "exécute le template daily" |
đ 3 router-state commands (lock + auto-enrichment)
Command | Effect | Trigger phrasings |
| Restrict the router to a single vault for the session (volatile or | "lock to tradingview", "I only want to work on tradingview", "isolate to tradingview permanently" / "verrouille sur tradingview", "je ne veux travailler que sur tradingview", "verrouille sur tradingview de maniĂšre permanente" |
| Lift the lock and restore multi-vault routing ( | "unlock vaults", "give me back access to all vaults" / "déverrouille les vaults", "je veux pouvoir avoir accÚs à tous les vaults" |
| Set the wiki auto-enrichment mode ( | "switch to Hybrid mode", "save everything automatically" (â FullAuto), "stop auto-saving" (â off) / "passe en mode Hybrid", "sauve tout automatiquement", "arrĂȘte de sauver auto" |
See Lock mode (single-vault isolation) and the auto-enrichment callout below for the full designs and concrete use cases.
đ©ș 6 conversational helpers
Command | Effect | Trigger phrasings |
| Bootstrap the router on a fresh machine (clone, npm link, register MCP) | "install the router", "bootstrap obsidian-mcp-router on this machine" / "installe le router", "setup obsidian-mcp-router sur cette machine" |
| Interactive wizard to attach a vault to a workspace (default), bootstrap a standalone vault, or register a remote vault. Provisions plugins + scaffolds wiki + binds | "set up Obsidian for this project", "attach a vault to this workspace", "connect my remote vault" / "configure Obsidian pour ce projet", "attache un vault Ă ce workspace", "connecte mon vault distant" |
| Health-check every vault with per-issue fix hints | "diagnose the router", "are my vaults reachable" / "diagnostique le router", "mes vaults sont-ils accessibles" |
| Propagate the reference vault's plugins/snippets/docs to one or more vaults (interactive picker) | "sync the template to all vaults", "push reference plugins to X" / "synchronise le template vers tous les vaults", "pousse les plugins de référence vers X" |
| Audit click-to-open readiness across vaults (bridge â„0.2.0, REST API â„4.0.0, insecure HTTP, live | "audit bridge readiness", "is click-to-open ready" / "audite la disponibilitĂ© du bridge", "le click-to-open est-il prĂȘt" |
| Install / remove / status / propagate CLAUDE.md conventions (source-type, bilingual, heading-hierarchy, ...) across vaults | "install source-type convention on X", "list conventions" / "installe la convention source-type sur X", "liste les conventions" |
đ 15 knowledge-management commands (Karpathy-style LLM-wiki)
A small workflow on top of the router for an LLM-maintained, structured markdown knowledge base where pages reference each other and grow with use.
Command | Effect | Trigger phrasings |
| Scaffold | "set up a wiki", "scaffold a knowledge base" / "scaffold un wiki", "crée une base de connaissances" |
| Ingest a source (URL/file/text) â entity & concept pages + cross-refs | "ingest this URL", "absorb this article" / "ingĂšre cette URL", "absorbe cet article" |
| Three-tier RAG (hot.md â index.md â drill into pages), wiki-only (no web) | "based on my notes, ...", "what does my wiki say about X" / "d'aprĂšs mes notes, ...", "que dit mon wiki sur X" |
| Health check (orphans, dead wikilinks, index drift, frontmatter gaps) | "lint the wiki", "audit my wiki" / "lint le wiki", "audit mon wiki" |
| Idempotent rollup of log entries under | "fold the log", "roll up recent activity" / "compacte le journal", "résume l'activité wiki de cette semaine" |
| File the current conversation as a typed wiki note (session/answer/decision/ADR/...) | "save this", "file this conversation" / "sauvegarde ça", "archive cette conversation" |
| Autonomous webâsynthâfile loop bounded by a research program | "research X on the web", "go investigate X online" / "fais une recherche web sur X", "investigue X en ligne" |
| Create/edit Obsidian | "create a canvas for X", "add to my canvas" / "crée un canvas pour X", "ajoute à mon canvas" |
| Strip noise from webpages (ads, nav, footers) before ingestion | "defuddle ", "clean this page" / "nettoie cette page", "extrais la version lisible de " |
| Create/edit Obsidian | "create a base for X", "task tracker base" / "crée une base pour X", "base task tracker" |
| Build a typed knowledge-graph JSON from the vault (Understand-Anything schema; feeds the native graph viewer) | "build the wiki graph", "generate the knowledge graph" / "construis le graphe du wiki", "génÚre le knowledge graph" |
| Generate an ordered pedagogical reading tour from the vault's link topology | "give me a tour of this vault", "where do I start" / "fais-moi un tour du vault", "par oĂč je commence" |
| Export the vault as a portable single file ( | "export the wiki as llms.txt", "make a portable export" / "exporte le wiki en llms.txt", "fais un export portable" |
| Regenerate the per-page digest sidecars (concepts/claims/keywords) used by | "refresh the digests", "rebuild page digests" / "rafraßchis les digests", "régénÚre les digests de page" |
| Identify the current family member in a shared vault and lock routing per-member | "who is speaking", "it's Karine" / "qui parle", "c'est Karine" |
Plus one Obsidian-specific reference skill (no slash command â knowledge surfaced when other skills run): obsidian-markdown (Obsidian Flavored Markdown reference for wikilinks, embeds, callouts, properties, etc.). Note that obsidian-bases is BOTH a reference skill AND has its own slash command above â other skills consult it when they need to generate .base files, and you can also invoke it directly.
Two parallel sub-agents for batch work:
wiki-ingestagent â fan out one source per agent, parallelwiki-lintagent â read-only diagnostic in a separate context
Hooks â 9 cross-platform Node hooks, auto-wired into ~/.claude/settings.json at vault bootstrap since v0.18.2 (opt out with setup-vault.mjs --no-hooks):
session-auto-journalâ auto-journals each Claude session underwiki-meta/Sessions/+ a 2-line recap towiki-meta/log.md(self-healing reconciliation)hot-cache-loadâ loadswiki-meta/hot.mdinto context at SessionStart / PostCompacthot-cache-update-promptâ deterministic guard: blocks the turn (exit 2) untilwiki-meta/hot.mdis refreshed when this session wrote awiki/note (per-vault, transcript-scoped; opt-outOBSIDIAN_ROUTER_NO_HOT_CACHE_GUARD)wiki-autocommitâ auto-commitswiki/,wiki-meta/,.raw/,.vault-meta/to git after writeswiki-query-first-nudgeâ nudges Claude to check the vault before answering (+ injects PATH RESOLUTION RULES)vault-link-linterâ catches broken/phantom vault links before they reach youdoc-propagation-checkerâ flags docs drifting from shipped codevault-doc-startup-checkâ surfaces vault & doc health at session startcheck-router-updateâ 24h GitHub version check
The hooks ship in hooks/; setup-vault.mjs wires them automatically at bootstrap.
đ Auto-enrichment (v0.8.2, Phase 1) â Claude proactively suggests wiki saves at three natural moments: validation (you say "OK" / "valide" â inline pin), result obtained (commit pushed, tests green â digest of candidates), and topic switch (mandatory checkpoint before Claude responds to the new topic). Domain-agnostic: works for development, personal life, research, family planning, anything.
Four modes (/obsidian-router:auto-mode <Mode> to switch, --persist to write to .env):
Mode | Behavior | Best for |
| Propose, always confirm | Discovering the feature · long mixed-importance sessions · vaults where false positives would hurt · the calibration period (1-2 weeks) before trusting auto-save |
| Auto-save type-safe items (facts, URLs, preferences); ask on high-stakes (decisions, ADRs, rules, techniques) | Power-user sweet spot after calibration · active dev with frequent URL ingestion · research where citations pile up but conclusions need vetting |
| Auto-save everything; audit log in | High-trust sessions · personal journal / family chronicle · long unsupervised flows (autoresearch, batch ingestion) · solo brain-dumps where the wiki IS the conversation log |
| No auto-suggestions; manual | Debugging sessions you don't want polluting the wiki · sensitive conversations · default for legal/medical/financial vaults · control-freak preference |
Placement â the consigne ships in the vault CLAUDE.md template, but is also configurable as Claude Desktop Project instructions (elegant pattern: a "Trading Journal" project always saves to tradingview, a "Personal" project to personal). See docs/auto-enrichment.md for the four placement channels (vault CLAUDE.md, Project instructions, Memory, global CLAUDE.md), the activation rules, and concrete copy-paste boilerplates per channel.
Install steps are in the Install section below.
Prerequisites
Plugin (per vault) | Required for | Where to get it |
Local REST API | All tools | Community plugins â "Local REST API" by Adam Coddington |
MCP Router Bridge |
| Install from |
Smart Connections |
| Community plugins â "Smart Connections" â the embeddings backend |
Templater |
| Community plugins â "Templater" by SilentVoid13 |
You also need:
Node.js â„ 20.18.1 (required by
undici@7)At least one vault provisioned in
~/.claude/obsidian-mcp-router/config.json. If you've never set this up, runnpm run setup-vault -- "<vault-path>"from a clone of this repo, or invokescripts/setup-vault.mjsdirectly â it'll bootstrap the config interactively. Schema reference:examples/config.example.json.A reference vault registered with the router. It holds the canonical plugin set + config that
setup-vault.mjsclones into every new vault. Fast path:node scripts/setup-vault.mjs --bootstrap-reference <path>scaffolds it from the shipped skeleton (templates/reference-vault-skeleton/) and auto-downloads the bridge plugin. Full procedure (manual + troubleshooting):docs/reference-vault-setup.md.
CSS snippets are cloned automatically. Since v0.10.1, every
setup-vault.mjsinvocation also copies<referenceVault>/.obsidian/snippets/*.cssinto the target vault and merges the basenames into<target>/.obsidian/appearance.jsonenabledCssSnippets. The shipped skeleton shipsno-task-strikethrough.css(kills Obsidian's defaulttext-decoration: line-throughon- [x]items, aligned with theroadmap-discipline§2bis convention). Opt-out per vault in Settings â Appearance â CSS snippets. To push a snippet (or plugin) update to ALL configured vaults at once:node scripts/setup-vault.mjs --sync-all(idempotent; add--forceto re-clone existing files).
Install
đ Reference vault required for
setup-vault.mjsâ to bootstrap new vaults via the script (which most users will want), you first need a one-time-configured reference vault holding the canonical plugin set. Easiest path:node scripts/setup-vault.mjs --bootstrap-reference <path>(scaffolds the skeleton + downloads bridge plugin in one command, then guides you through installing the marketplace plugins via Obsidian). Full doc with troubleshooting:docs/reference-vault-setup.md.
Two pieces to install: the MCP server (the router itself, exposes the 35 tools to Claude) and the plugin (exposes /obsidian-router:* slash commands).
Step 1 â Install the MCP server
git clone https://github.com/tboome33/obsidian-mcp-router.git
cd obsidian-mcp-router
npm install
npm link # makes the `obsidian-mcp-router` binary available globallyRegister it in ~/.claude.json (user scope) as obsidian-router:
{
"mcpServers": {
"obsidian-router": {
"type": "stdio",
"command": "obsidian-mcp-router"
}
}
}The router reads ~/.claude/obsidian-mcp-router/config.json on start (the same file that setup-vault.mjs maintains) and exposes every vault automatically.
Step 2 â Install the plugin
Register the marketplace globally in ~/.claude/settings.json:
{
"extraKnownMarketplaces": {
"obsidian-mcp-router-marketplace": {
"source": {
"source": "github",
"repo": "tboome33/obsidian-mcp-router"
}
}
}
}Then enable the plugin per-workspace, NOT globally. The plugin loads ~38 slash commands and ~39 skills (~10k context tokens per session) â you only want that overhead on workspaces that actually use Obsidian. For each vault directory and each app workspace that consumes the router, drop a .claude/settings.json file at the workspace root:
{
"enabledPlugins": {
"obsidian-router@obsidian-mcp-router-marketplace": true
}
}For vaults bootstrapped via setup-vault.mjs, this file is cloned automatically from .template/.claude/settings.json â you don't have to write it by hand. For non-vault workspaces (dev repos that work with vault content), copy the snippet above into <workspace>/.claude/settings.json.
Restart Claude Code. From a workspace with the plugin enabled, type /obsidian-router: â the 38 slash commands should appear. From a workspace without, the namespace stays clean.
Why not enable it globally? If you put
enabledPluginsin~/.claude/settings.jsoninstead of per-workspace, the plugin loads in EVERY Claude Code session â random scripts, debug sessions, unrelated repos â paying ~10k tokens for commands those sessions will never use. Project-scope keeps the budget tight.
Bump the skill-listing budget (recommended). The router contributes ~39 skills to Claude Code's skill listing. On a default install (
skillListingBudgetFraction: 0.01, i.e. 1% of the context window), this often pushes the listing past the budget â descriptions are truncated, and natural-language triggering for/save,/wiki,/autoresearchetc. silently breaks. Recommended: raise to0.05in~/.claude/settings.json(~6k extra tokens per session). The diagnostic message "Skill listing will be truncated â N descriptions dropped" at session start is the symptom this fixes.{ "skillListingBudgetFraction": 0.05 }The bundled
meta-setupskill detects an under-budgeted setup and offers to apply this change interactively.
You can also use the bundled meta-setup skill to walk through both steps interactively: just ask Claude "set up the obsidian-mcp-router on this machine".
Staying up to date
The plugin ships a SessionStart hook (hooks/check-router-update.mjs, since v0.10.3) that checks GitHub once per 24 hours and surfaces a notice if a newer version is available. The notice tells Claude to relay it on its first response of the session, so you find out without having to remember to check.
If /plugin update obsidian-router@obsidian-mcp-router-marketplace is available in your Claude Code environment, that's the one-liner upgrade path. If it isn't (some environments don't expose the /plugin slash command), see docs/how-to-update.md for the 5-step manual filesystem equivalent (bash + PowerShell recipes).
Opt-out â set either of these env vars and the check is skipped:
OBSIDIAN_ROUTER_NO_UPDATE_CHECK=true(any truthy value)OBSIDIAN_ROUTER_USER_ID=<slug>(multi-tenant deployments â assumes the sysadmin manages updates centrally)
The check is a single GET to raw.githubusercontent.com. No payload, no telemetry â source is hooks/check-router-update.mjs.
CLI flags
obsidian-mcp-router --version
obsidian-mcp-router --help
obsidian-mcp-router --config /custom/path/config.json
obsidian-mcp-router --no-watch # disable hot-reload of the config fileBy default, the router watches the config file and reloads automatically when it changes â useful when paired with setup-vault.mjs adding new vaults, or with the future Obsidian Cloudflare Tunnel plugin auto-writing tunnel URLs into remoteVaults.
Building your own macros on top (advanced)
The 38 plugin commands above are domain-agnostic on purpose â they work for any vault. If you want macros that chain multiple tools or bake in your vault's conventions (daily notes, capture inbox, weekly rollups, etc.), build them as your own slash commands in ~/.claude/commands/<name>.md â not as PRs on this repo. The router stays neutral; the macros are yours.
See docs/building-commands.md for the pattern and three illustrative starting-point examples.
Disabling a vault temporarily
To hide a vault from list_vaults without removing it from the config, either:
{
// Global blacklist (works for both local and remote vaults, by name):
"disabledVaults": ["template", "experimental-vps"],
// Or per-remote-vault flag (only for entries in remoteVaults):
"remoteVaults": [
{ "name": "qnap", "baseUrl": "...", "apiKey": "...", "enabled": false }
]
}Disabled vaults appear in the boot log as (N disabled: ...) for visibility, but they don't show up in list_vaults and aren't pingable.
Default vault resolution
When a tool call omits the vault argument (e.g., read-search "trading risk"), the router has to pick one. The same call can resolve to different vaults depending on which workspace you launch Claude from.
Resolution cascade, highest priority first:
OBSIDIAN_ROUTER_DEFAULT_VAULTenv var â explicit per-process override. Set this in your project's.envto force a specific default regardless of cwd.VAULT_PATHenv var â auto-detection. IfVAULT_PATHmatches a path registered in yourportRegistry, that vault becomes the default.setup-vault.mjswrites this into every bootstrapped vault's.env, so opening Claude Code in a vault directory "just works" with that vault as default.config.defaultVaultâ explicit global default in~/.claude/obsidian-mcp-router/config.json.First healthy local vault â historical fallback.
First active vault of any type â last resort.
The router auto-loads .env from the cwd at startup, so steps 1 and 2 work without any other tooling. Existing env vars in the parent process win over .env.
Three concrete cases
Case 1 â your project IS a vault (the common case).
cd C:\VAULTS\TradingView\
claude.env (written by setup-vault.mjs when you bootstrapped the vault) contains:
VAULT_PATH=C:\VAULTS\TradingView
OBSIDIAN_API_KEY=...
OBSIDIAN_BASE_URL=https://127.0.0.1:27125Auto-detection (step 2) matches VAULT_PATH against your portRegistry â default = tradingview. No config needed. Tools that omit vault operate on tradingview.
Case 2 â your project is NOT a vault, but works with one.
cd C:\Code\my-app\
claudeThis isn't a vault directory, so VAULT_PATH isn't set. Without intervention, the router falls back to config.defaultVault (probably tradingview). If you want this project to default to a different vault â say recherche for note-taking â add to C:\Code\my-app\.env:
OBSIDIAN_ROUTER_DEFAULT_VAULT=rechercheStep 1 wins â default = recherche for this project only.
Case 3 â your project IS a vault, but you want a different default.
You opened Claude Code in C:\VAULTS\.template\ because you're documenting it, but you want vault tool calls without explicit vault= to operate on tradingview instead of template. Add to C:\VAULTS\.template\.env:
OBSIDIAN_ROUTER_DEFAULT_VAULT=tradingviewStep 1 overrides the auto-detection of step 2.
Verifying which default the router picked
Call list_vaults â the result has a defaultVault field showing which name resolved.
# from any project, in Claude Code:
"list my vaults"If the defaultVault is wrong for what you expected, check (in order): your project's .env, the parent process's env, and ~/.claude/obsidian-mcp-router/config.json's defaultVault field.
Override didn't take effect?
If you set OBSIDIAN_ROUTER_DEFAULT_VAULT="something" and the router can't find that name in the active set (typo, vault disabled, vault removed), the cascade falls through to step 2/3/4/5 AND emits a one-line warning to stderr:
[registry] OBSIDIAN_ROUTER_DEFAULT_VAULT="recherchee" does not match any active vault â falling through to other resolution tiers. Active vaults: template, tradingview.Lock mode (single-vault isolation)
By default the router is in multi-vault mode: any tool call can target any registered vault via the vault parameter, and vault: "*" fans out across all of them. This is the right default for power users who want one MCP entry to rule them all.
For situations where you want the opposite â one vault for the whole session, with the router refusing every cross-vault drift â use lock mode.
When lock mode is useful
Safety: working on a sensitive vault (legal docs, client data) and you want a structural barrier against accidental writes elsewhere.
User routing on a shared install: a single Claude Code installation shared between several people. Each user locks to their personal vault at session start; nobody's notes leak into anyone else's.
Focus: long ingestion or autoresearch session on one wiki â lock prevents the assistant from "helpfully" filing anything in a sibling vault.
How to lock / unlock
Three ways to lock:
MCP tool directly (Claude calls it for you):
lock_vault({ vault: "tradingview" }) # volatile (this session) lock_vault({ vault: "tradingview", persist: true }) # writes .env so it survives restartSlash command (or natural language â auto-trigger):
/obsidian-router:lock tradingviewâ volatile/obsidian-router:lock tradingview --persistâ persistentNatural language: "I only want to work on tradingview", "lock to tradingview permanently"
Environment variable at startup:
OBSIDIAN_ROUTER_LOCKED=tradingviewin the workspace's
.env. The router reads it on boot. Permanent until removed.
To unlock:
unlock_vaults()â in-memory onlyunlock_vaults({ persist: true })â also removesOBSIDIAN_ROUTER_LOCKEDfrom<cwd>/.env/obsidian-router:unlockor "give me back access to all vaults"
Caveat â persist refused at home directory.
lock_vault({ persist: true })refuses when the current working directory IS your home directory (%USERPROFILE%on Windows,$HOMEelsewhere). That's almost always a mistake â Claude Code was launched from~rather than a project folder, and creating~/.envwould surprise you. The in-memory lock still applies for the session. To make the lock survive a restart in this case: either re-runlock_vaultfrom a real project directory, or setOBSIDIAN_ROUTER_LOCKED=<vault>in your shell profile (~/.bashrc,~/.zshrc, or PowerShell$PROFILE).
What happens while locked
Operation | Behavior |
Tool call with | â proceeds normally |
Tool call without explicit | â resolves to the locked vault (overrides the default cascade) |
Tool call with | â throws |
Tool call with | â throws |
| â
always works. Response includes new field |
Three concrete cases
Case 1 â quick volatile lock during a session.
You're about to ingest 30 articles into your recherche wiki and don't want any drift to other vaults:
"lock to recherche"
Router locks. All wiki-ingest calls go to recherche. After the session ends or Claude Code restarts, the lock is gone (since you didn't persist).
Case 2 â permanent lock for a shared install.
You and other users share the same Claude Code install. Donald wants every Claude session he opens to default to (and stay locked on) the donald vault, no matter what config.defaultVault says.
In ~/.bashrc / PowerShell profile, OR in the .env of his usual project:
OBSIDIAN_ROUTER_LOCKED=donaldOr, equivalently, run once:
"lock to donald and persist this"
The slash command writes OBSIDIAN_ROUTER_LOCKED=donald to <cwd>/.env. From now on, opening Claude in this workspace, the router boots already locked. Other users (Mitch, Bernie...) on different workspaces have their own .env with their own lock value.
Case 3 â switching the lock target.
You're locked to recherche. You want to switch the lock to tradingview:
"lock to tradingview"
lock_vault overrides the previous lock atomically. No need to unlock first.
Verifying the lock state
"list my vaults"The response now contains lockedTo:
{
"defaultVault": "tradingview",
"lockedTo": "tradingview", // â non-null = locked
"vaults": [...],
"disabled": [...]
}When lockedTo is null, the router is in normal multi-vault mode.
VAULT_* env-var config (dashboard-editable)
Besides the config.json file below, a vault can be defined entirely in an environment variable â one per vault â so it's editable straight from the MCPHub server's Environment Variables UI (no SSH + file edit). This is a 3rd config source, merged after portRegistry + remoteVaults; a VAULT_* entry overrides any same-name vault. It's opt-in: with no VAULT_* set, the router behaves exactly as before.
VAULT_<NAME> = <vault config as JSON>Required: name, baseUrl, apiKey (the bare token â the router adds Authorization: Bearer itself). Optional: description, tlsInsecure, timeoutMs (default 10000). (There is no per-vault wireguard flag â WireGuard is enforced deployment-wide; see below. A leftover wireguard key is ignored.)
The three connection modes (all selected purely by baseUrl):
# 1. WireGuard tunnel (sensitive/medical â encrypted). Selected purely by the
# 10.8.0.x baseUrl; WG can be enforced deployment-wide (OBSIDIAN_ROUTER_ENFORCE_WG_OR_LOOPBACK).
VAULT_DEDIBOX={"name":"dedibox","baseUrl":"http://10.8.0.10:27161","apiKey":"<token>","timeoutMs":15000}
# 2. LAN / co-located (non-sensitive) â plain HTTP on the local network.
VAULT_NOTES={"name":"notes","baseUrl":"http://192.168.0.10:27124","apiKey":"<token>"}
# 3. Remote behind TLS (e.g. nginx + Let's Encrypt).
VAULT_REMOTE={"name":"remote","baseUrl":"https://vault.example.com","apiKey":"<token>","tlsInsecure":false}Defensive parsing: a malformed entry is skipped with a clear stderr warning naming the faulty key (one bad var never crashes the others). On a JSON-parse failure neither the raw value nor the parser message is logged (both can echo the apiKey). The reserved VAULT_PATH env var is ignored by the scan.
Ephemeral view links (optional view-agent provider) â set OBSIDIAN_ROUTER_VIEW_AGENT_URL (plus an optional shared secret OBSIDIAN_ROUTER_VIEW_AGENT_TOKEN, sent as X-View-Token) to plug a view-link provider into the router. Every note write then carries a ready-to-click viewLink to the vault's live Obsidian GUI navigated to that note (â„ 0.29.0, deterministic server-side injection), the get_view_link tool appears (â„ 0.28.0 â it is hidden from ListTools while the URL is unset, so unconfigured routers carry zero dead surface), and open_in_obsidian returns the link for remote-container vaults (â„ 0.30.0). The router depends only on a small HTTP contract â GET /view?vault=<name>¬e=<path> â {"url": "<browser-ready link>"} â not on any particular infrastructure: see the reference provider implementation + the normative contract at obsidian-mcp-router-view-agent (config-driven, stdlib-only Python, ephemeral cloudflared quick tunnels).
Smart links (optional resolver) â set OBSIDIAN_ROUTER_SMART_LINK_URL (resolver base URL) and OBSIDIAN_ROUTER_SMART_LINK_SECRET (HMAC secret) to emit stable signed smart links instead of agent-fetched view links: note writes and open_in_obsidian on remote vaults then carry viewLink = <resolver>/o/<signed-token> with viewLinkKind: "smart" â a pure HMAC computation, zero network call (a write can never be slowed by a down agent), and the link stays valid in chat history (30-day token TTL). The link resolves on the device that clicks it (local Obsidian mirror probe â obsidian:// deep link â streamed-GUI fallback). Provider priority when both are configured: smart link â view-agent â none; get_view_link keeps talking to the view-agent directly. Configuring smart links signals a remote deployment â do not set OBSIDIAN_ROUTER_SMART_LINK_* on a purely local router, or open_in_obsidian will hand back a link (opened:false, delivered:"link") instead of navigating your local Obsidian. The resolver reference implementation + contracts live in the private saas repo (obsidian-mcp-router-saas).
Deployment-wide transport guard â set OBSIDIAN_ROUTER_ENFORCE_WG_OR_LOOPBACK=true (typically on a multi-tenant MCPHub instance) to make the router refuse to start if any served vault's baseUrl host is neither loopback (127.0.0.1/::1/localhost) nor inside the 10.8.0.0/24 WireGuard mesh. This is a boot-time config check on the configured baseUrls â it does not require the WireGuard tunnel to be up, and loopback passes (so it is not "WireGuard-only"). Fail-closed â a vault can never be silently served over an exposed link; the check runs after the OBSIDIAN_ROUTER_ALLOWED_VAULTS whitelist. Opt-in; unset = no enforcement (local mode unchanged). This replaces the former per-vault wireguard flag. (Renamed from OBSIDIAN_ROUTER_REQUIRE_WIREGUARD in v0.27.0 â that name wrongly implied "WG must be up"; the old name still works as a deprecated alias.)
Generating a host deployment (gen-obsidian-deploy)
To run a vault as a linuxserver/obsidian (Selkies) container on a host (e.g. a server) â serving LiveSync, the Local REST API, and a browser-tab GUI from one plain-markdown /config â use the generator instead of hand-writing the JSON above:
node scripts/gen-obsidian-deploy.mjs --name tribu --rest-port 27145 --mode wg --wg-host 10.8.0.1It prints a docker-compose service, an nginx reverse-proxy block (with a self-healing resolver-variable proxy_pass), and the VAULT_* line â the latter is round-trip-tested against this router's parseEnvVaults, so it can't drift. Modes: wg (WireGuard-only, for sensitive/medical), lan, public (HTTPS+bearer; refused for --sensitive vaults). Pass --tls-insecure to emit tlsInsecure: true (an https baseUrl behind a self-signed / internal-CA cert). Secrets default to placeholders â never invented. See deploy/dedibox-obsidian/ for the full runbook (incl. LiveSync Setup-URI onboarding).
Config
The router reads the existing config maintained by scripts/setup-vault.mjs, and adds three optional fields on top:
{
// --- written by setup-vault.mjs (don't edit by hand) ---
"referenceVault": "C:\\VAULTS\\.template",
"portStart": 27124,
"portRegistry": {
"C:\\VAULTS\\.template": 27124,
"C:\\VAULTS\\TradingView": 27125
},
// --- router-specific (optional, edit freely) ---
"vaultNames": {
"C:\\VAULTS\\.template": "template",
"C:\\VAULTS\\TradingView": "tradingview"
},
"remoteVaults": [
{
"name": "qnap",
"baseUrl": "https://192.168.0.11:27125",
"apiKey": "...",
"tlsInsecure": true
}
],
"defaultVault": "tradingview"
}See examples/config.example.json for a complete example with comments, docs/remote-vaults.md for the full guide on adding remote vaults, and docs/cloudflare-tunnel.md for the recipe to expose a vault over a Cloudflare Tunnel with optional Cloudflare Access auth (service tokens supported via the extraHeaders field).
Tools exposed
Tool | Description |
| Catalogue of all configured vaults with online status + latency. Always call this first. |
| List files in a directory of a specific vault. |
| Read full file content (markdown + frontmatter). |
| Plain-text (substring) search. Pass |
| Semantic (meaning-based) search via Smart Connections embeddings. Returns ranked chunks with cosine scores and breadcrumbs. Requires |
| Create a new file or replace the entire content of an existing one. Pass |
| Append content at the end of a file. Auto-creates the file unless |
| Surgical edit by |
| Permanently delete a file. Requires explicit |
| Execute a Templater template, optionally writing the rendered result to a new file. Arguments are exposed in the template via |
| Move or rename a file. Implemented as GET source â PUT destination â DELETE source. Pass |
| Read frontmatter (whole object or one key). Returns parsed values â numbers, booleans, arrays preserved. |
| Set/replace one frontmatter property. Type preserved (string/number/bool/null/array/object). |
| Apply multiple frontmatter updates in sequence (non-atomic â see ROADMAP for atomic alternative). |
| Restrict the router to a single vault for the session (single-vault isolation). See the Lock mode section. |
| Switch the wiki auto-enrichment mode between |
| Convert a local file to markdown via the bundled |
| Convert a remote URL to markdown via |
| Bundle a git repository (file tree + source code) into a single markdown document via |
| Deterministic page-metadata extractor (JSON-LD + OpenGraph + meta tags + title) â feeds non-fabricated frontmatter for ingestion. |
| Heuristic-scored |
| Download a page's images into the vault (image preservation during web ingestion). |
| Build a ready-to-paste click-to-open markdown link ( |
| Open a note in the running Obsidian (and raise its window) by calling the bridge |
| Return a structured JSON context envelope for a query (primaryPages / semanticChunks / graphNeighbors / citations) so non-Claude agents can consume the vault programmatically. |
| Assemble the vault into a typed knowledge-graph JSON (Understand-Anything schema: 21 node / 35 edge types). Writes |
| Generate a deterministic, ordered pedagogical reading tour from the knowledge-graph link topology. Read-only. |
More tools (CLI flags, hot config reload, skills) are on the roadmap â see ROADMAP.md.
Conversion tools â runtime dependencies
The *_to_markdown family is a JS/ESM port of zcaceres/markdownify-mcp (MIT) â see NOTICE for the full credit. The actual file â markdown conversion is performed by Microsoft's markitdown Python CLI:
Python 3.10+ is required. The router's npm postinstall script (
scripts/install-markitdown.mjs) auto-detects Python onPATH, creates a local.venvat the repo root, and installsmarkitdown[all]>=0.1.5. If Python is missing, the postinstall prints a warning and exits cleanly â the rest of the router still works.Skip the postinstall with
OBSIDIAN_ROUTER_SKIP_MARKITDOWN=1ornpm install --ignore-scripts. Re-run manually any time withnpm run install-markitdown.To use a system-wide install instead of the bundled venv:
pipx install "markitdown[all]"and setMARKITDOWN_PATH=/abs/path/to/markitdown.git_repo_to_markdownusesrepomix(Node, bundled as a normal npm dependency â no extra setup).
Optional sandbox env vars:
Variable | Purpose |
| Absolute path to the |
| Absolute path to the |
|
|
| Legacy single-directory alias for |
| Set to |
Usage examples
Once the router is registered in Claude, you'd typically prompt Claude in natural language and let it pick the right tool. The shapes below show the JSON arguments each tool accepts â handy when authoring custom workflows or when reviewing what Claude actually called.
Discovery â start every session here
// list_vaults â no args. Returns every vault with online/latency/missingApiKey.
{}// list_files â explore a directory.
{ "vault": "tradingview", "directory": "Sessions" }
// Or list root if you omit directory:
{ "vault": "tradingview" }Read
// get_file â full markdown content + frontmatter as text.
{ "vault": "tradingview", "path": "Sessions/2026-04-29.md" }// search â substring match, with surrounding context.
{ "vault": "tradingview", "query": "AL2SI", "contextLength": 80 }
// Cross-vault fan-out:
{ "vault": "*", "query": "money management" }// search_smart â semantic similarity (Smart Connections embeddings).
// Returns chunks with cosine scores and breadcrumbs.
{
"vault": "tradingview",
"query": "rules for breakeven and trailing stop",
"folders": ["Formations", "Indicators"],
"excludeFolders": [".trash"],
"limit": 10
}
// Cross-vault semantic fan-out:
{ "vault": "*", "query": "what did I learn this week?" }Write
// write_file â create or replace.
{
"vault": "tradingview",
"path": "Trades/2026-05-02 - GLE Long.md",
"content": "---\nstatus: open\nticker: GLE\n---\n\n# GLE Long\n\nEntry: ..."
}
// Refuse to overwrite if file exists:
{ "vault": "tradingview", "path": "...", "content": "...", "ifNew": true }// append_to_file â useful for journals/logs.
{
"vault": "tradingview",
"path": "Sessions/2026-05-02.md",
"content": "\n## 14:32 â TSLA breakout invalidĂ©\n\nStop touchĂ© Ă 178.40\n"
}// patch_file â surgical edit, no full rewrite.
// Insert under a heading (use full heading path with :: delimiter):
{
"vault": "tradingview",
"path": "Sessions/2026-05-02.md",
"operation": "append",
"targetType": "heading",
"target": "Session 2026-05-02::Trades du jour",
"content": "- TSLA: stopped out -1.2%\n"
}
// Update a single frontmatter key:
{
"vault": "tradingview",
"path": "Trades/2026-05-02 - GLE Long.md",
"operation": "replace",
"targetType": "frontmatter",
"target": "status",
"content": "closed"
}
// Replace a block by id:
{
"vault": "tradingview",
"path": "Indicators/ATP/notes.md",
"operation": "replace",
"targetType": "block",
"target": "atp-config",
"content": "Updated config for v2.3"
}// delete_file â guarded. confirm: true is mandatory.
{ "vault": "tradingview", "path": "_scratch/old.md", "confirm": true }Templater
// execute_template â render and optionally save.
// Template file must exist in the vault. Args are accessible inside the
// template via tp.mcpTools.prompt("key") â note: directly under tp,
// NOT under tp.user.
{
"vault": "tradingview",
"name": "Templates/Trade.md",
"arguments": {
"ticker": "AAPL",
"direction": "long",
"entry": "175.20",
"stop": "172.50"
},
"createFile": true,
"targetPath": "Trades/2026-05-02 - AAPL Long.md"
}
// Render only (preview), don't save:
{
"vault": "tradingview",
"name": "Templates/Trade.md",
"arguments": { "ticker": "AAPL" }
}TLS
The Local REST API plugin generates a self-signed certificate by default. For localhost vaults, set tlsInsecure: true (the default for vaults loaded from portRegistry). For remote vaults behind a real TLS cert (e.g., a reverse proxy with Let's Encrypt), set tlsInsecure: false.
License
Apache 2.0 â see LICENSE and NOTICE. No usage restrictions.
đ«đ· Version française
Serveur MCP qui aiguille les appels d'outils Claude vers plusieurs vaults Obsidian â locaux ou distants â via le plugin Local REST API.
Au lieu d'enregistrer un MCP par vault (un process, un port, une clé API), ce router expose un seul MCP qui connaßt tous les vaults que tu as configurés. Chaque outil prend un paramÚtre vault (ou utilise ton vault par défaut), et le router fait suivre l'appel HTTPS vers la bonne instance Obsidian.
Pourquoi
Si tu maintiens plusieurs vaults Obsidian â locaux ou distants, dans n'importe quelle combinaison â tu ne veux pas enregistrer un serveur MCP par vault et changer de contexte Ă chaque fois. Ce router est un seul process qui les connaĂźt tous et route chaque appel d'outil vers le bon en fonction d'un paramĂštre vault.
Ce que tu obtiens :
Une seule entrée MCP dans
~/.claude.json(user scope) â tous les vaults sont visibles depuis n'importe quelle session Claude Desktop ou Code.Vaults locaux et distants traitĂ©s Ă l'identique. Pose l'URL + la clĂ© API dans le config ; le router se moque d'oĂč le vault tourne rĂ©ellement.
Recherche cross-vault : passe
vault: "*"Ă l'outilsearchpour lancer la recherche sur tous les vaults en parallĂšle.
Capacités
Surface d'outils | Couverture |
Découverte |
|
Lectures |
|
Ăcritures |
|
Gestion de fichiers |
|
Templater |
|
Ătat du router |
|
Conversion (v0.11+) |
|
Métadonnées web/page |
|
Contexte & graphe |
|
Cross-vault | tous les outils acceptent |
La recherche sĂ©mantique (search_smart) et l'exĂ©cution Templater (execute_template) nĂ©cessitent que le plugin obsidian-mcp-router-bridge soit installĂ© dans chaque vault cible â il enregistre les routes correspondantes /search/smart et /templates/execute sur Local REST API. Tout le reste fonctionne contre les endpoints standards de Local REST API seuls.
Slash commands & skills (plugin Claude Code)
Le repo est aussi un marketplace de plugin Claude Code qui expose 38 slash commands sous le namespace /obsidian-router:*. Tape /obsidian-router: dans Claude Code â l'autocomplete montre tout. Chaque slash command s'auto-dĂ©clenche aussi sur du langage naturel (EN + FR), donc tu n'as quasiment jamais Ă retenir le nom exact â dĂ©cris simplement ce que tu veux.
đ PDF de rĂ©fĂ©rence rapide (vue d'ensemble du router + setup + config + chaque slash command avec phrases dĂ©clencheuses en langage naturel) â Français · English. 5 pages, fontes lisibles pour impression ou consultation Ă©cran.
đ§ 14 wrappers MCP â un par outil de base du vault
discover/ (2)
Commande | Effet | Phrases déclencheuses |
| Liste tous les vaults configurés (local + remote) avec online/offline/latence, vault par défaut, état du lock | "liste mes vaults", "mes vaults sont-ils en ligne" / "list my vaults", "are my vaults online" |
| Liste fichiers et sous-dossiers d'un chemin de vault | "liste les fichiers de Sessions", "qu'est-ce qu'il y a dans " / "list files in Sessions", "what's in " |
read/ (4)
Commande | Effet | Phrases déclencheuses |
| Lit un fichier en intégralité (markdown + frontmatter + meta) | "montre-moi X", "ouvre le fichier X" / "show me X", "open the file X" |
| Recherche keyword full-text (substring) avec contexte | "trouve dans mon vault", "grep " / "find in my vault", "grep for X" |
| Recherche sémantique via Smart Connections (cosine + breadcrumbs) | "trouve mes notes sur X", "recherche sémantique sur X" / "find notes about X", "semantic search for X" |
| Lit le frontmatter (objet entier ou une clé, types préservés) | "quel est le statut de X", "montre les méta de X" / "what's the status of X", "show me the metadata of X" |
write/ (5)
Commande | Effet | Phrases déclencheuses |
| PUT â crĂ©e ou remplace un fichier | "crĂ©e une note X", "enregistre ça comme X.md" / "create a note X", "save this as X.md" |
| POST â append Ă un fichier (auto-crĂ©ation si absent) | "ajoute Ă X", "rajoute Ă la fin de X" / "append to my journal", "add a line to X" |
| PATCH chirurgical sur heading / block / frontmatter | "édite la section X dans Y", "remplace le contenu sous X" / "edit the X section in Y", "replace the content under X" |
| Set/remplace une seule clé du frontmatter | "passe le statut de X à closed", "tag ça avec X" / "set status to closed on X", "tag this with X" |
| Applique plusieurs updates de frontmatter en séquence | "sur X mets status=closed outcome=tp1" / "on X set status=closed outcome=tp1" |
manage/ (2)
Commande | Effet | Phrases déclencheuses |
| DĂ©place ou renomme un fichier (GET â PUT â DELETE) | "renomme X en Y", "dĂ©place X dans " / "rename X to Y", "move X into " |
| Supprime un fichier (avec garde confirm en deux étapes) | "supprime X" (preview), "oui confirm=true" (proceed) / "delete X" puis "yes confirm=true" |
template/ (1)
Commande | Effet | Phrases déclencheuses |
| Exécute un template Templater (preview ou save) | "rends Templates/X.md avec arg1=v1", "exécute le template daily" / "render Templates/X.md with arg1=v1", "run the daily template" |
đ 3 commandes d'Ă©tat du router (lock + auto-enrichissement)
Commande | Effet | Phrases déclencheuses |
| Restreint le router Ă un seul vault pour la session (volatile ou | "verrouille sur tradingview", "je ne veux travailler que sur tradingview", "verrouille sur tradingview de maniĂšre permanente" / "lock to tradingview", "I only want to work on tradingview", "isolate to tradingview permanently" |
| LÚve le lock et restaure le routing multi-vault ( | "déverrouille les vaults", "je veux pouvoir avoir accÚs à tous les vaults" / "unlock vaults", "give me back access to all vaults" |
| Set le mode d'auto-enrichissement wiki ( | "passe en mode Hybrid", "sauve tout automatiquement" (â FullAuto), "arrĂȘte de sauver auto" (â off) / "switch to Hybrid mode", "save everything automatically", "stop auto-saving" |
Voir Mode lock (isolation mono-vault) et le callout auto-enrichissement plus bas pour les designs complets et cas d'usage concrets.
đ©ș 6 helpers conversationnels
Commande | Effet | Phrases déclencheuses |
| Bootstrap du router sur une machine neuve (clone, npm link, registration MCP) | "installe le router", "setup obsidian-mcp-router sur cette machine" / "install the router", "bootstrap obsidian-mcp-router on this machine" |
| Wizard interactif pour attacher un vault Ă un workspace (cas courant), bootstrapper un vault standalone, ou enregistrer un vault distant. Provisionne plugins + scaffolde wiki + lie | "configure Obsidian pour ce projet", "attache un vault Ă ce workspace", "connecte mon vault distant" / "set up Obsidian for this project", "attach a vault to this workspace", "connect my remote vault" |
| Health-check de chaque vault avec hints de fix par catégorie d'erreur | "diagnostique le router", "mes vaults sont-ils accessibles" / "diagnose the router", "are my vaults reachable" |
| Propage les plugins/snippets/docs du vault de référence vers un ou plusieurs vaults (picker interactif) | "synchronise le template vers tous les vaults", "pousse les plugins de référence vers X" / "sync the template to all vaults", "push reference plugins to X" |
| Audite la disponibilitĂ© du click-to-open sur les vaults (bridge â„0.2.0, REST API â„4.0.0, HTTP insecure, probe live | "audite la disponibilitĂ© du bridge", "le click-to-open est-il prĂȘt" / "audit bridge readiness", "is click-to-open ready" |
| Installe / retire / statut / propage les conventions CLAUDE.md (source-type, bilingual, heading-hierarchy, ...) sur les vaults | "installe la convention source-type sur X", "liste les conventions" / "install source-type convention on X", "list conventions" |
đ 15 commandes de gestion de connaissances (LLM-wiki façon Karpathy)
Un petit workflow par-dessus le router pour une base de connaissances en markdown structurĂ©, maintenue par le LLM, oĂč les pages se rĂ©fĂ©rencent entre elles et croissent avec l'usage.
Commande | Effet | Phrases déclencheuses |
| Scaffold | "scaffold un wiki", "crée une base de connaissances" / "set up a wiki", "scaffold a knowledge base" |
| Ingestion d'une source (URL/fichier/texte) â pages entitĂ© & concept + cross-refs | "ingĂšre cette URL", "absorbe cet article" / "ingest this URL", "absorb this article" |
| RAG en 3 tiers (hot.md â index.md â drill), wiki-only (sans web) | "d'aprĂšs mes notes, ...", "que dit mon wiki sur X" / "based on my notes, ...", "what does my wiki say about X" |
| Health check (orphelins, wikilinks morts, dérive d'index, frontmatter manquant) | "lint le wiki", "audit mon wiki" / "lint the wiki", "audit my wiki" |
| Rollup idempotent des entrées du log dans | "compacte le journal", "résume l'activité wiki de cette semaine" / "fold the log", "roll up recent activity" |
| File la conversation courante comme note typée (session/answer/decision/ADR/...) | "sauvegarde ça", "archive cette conversation" / "save this", "file this conversation" |
| Boucle webâsynthĂšseâfile autonome bornĂ©e par un programme de recherche | "fais une recherche web sur X", "investigue X en ligne" / "research X on the web", "go investigate X online" |
| Crée/édite des fichiers | "crée un canvas pour X", "ajoute à mon canvas" / "create a canvas for X", "add to my canvas" |
| Strip le bruit des pages web (pubs, nav, footers) avant ingestion | "nettoie cette page", "extrais la version lisible de " / "defuddle ", "clean this page" |
| Crée/édite des fichiers | "crée une base pour X", "base task tracker" / "create a base for X", "task tracker base" |
| Construit un knowledge-graph JSON typé depuis le vault (schéma Understand-Anything ; alimente le viewer graphe natif) | "construis le graphe du wiki", "génÚre le knowledge graph" / "build the wiki graph", "generate the knowledge graph" |
| GĂ©nĂšre un parcours de lecture pĂ©dagogique ordonnĂ© depuis la topologie de liens du vault | "fais-moi un tour du vault", "par oĂč je commence" / "give me a tour of this vault", "where do I start" |
| Exporte le vault en fichier unique portable ( | "exporte le wiki en llms.txt", "fais un export portable" / "export the wiki as llms.txt", "make a portable export" |
| RégénÚre les digests sidecar par page (concepts/claims/keywords) utilisés par | "rafraßchis les digests", "régénÚre les digests de page" / "refresh the digests", "rebuild page digests" |
| Identifie le membre de la famille courant dans un vault partagé et lock le routing par membre | "qui parle", "c'est Karine" / "who is speaking", "it's Karine" |
Plus un skill de rĂ©fĂ©rence Obsidian (sans slash command â surfacĂ© quand d'autres skills tournent) : obsidian-markdown (rĂ©fĂ©rence du Obsidian Flavored Markdown : wikilinks, embeds, callouts, properties, etc.). Note : obsidian-bases est Ă LA FOIS un skill de rĂ©fĂ©rence ET a sa propre slash command (la ligne au-dessus) â d'autres skills le consultent quand ils ont besoin de gĂ©nĂ©rer des fichiers .base, et tu peux aussi l'invoquer directement.
Deux sub-agents parallĂšles pour les batches :
agent
wiki-ingestâ fan-out un agent par source, en parallĂšleagent
wiki-lintâ diagnostic read-only dans un contexte isolĂ©
Hooks â 9 hooks Node cross-platform, auto-cĂąblĂ©s dans ~/.claude/settings.json au bootstrap du vault depuis v0.18.2 (opt-out via setup-vault.mjs --no-hooks) :
session-auto-journalâ journalise automatiquement chaque session Claude souswiki-meta/Sessions/+ un rĂ©cap 2 lignes danswiki-meta/log.md(rĂ©conciliation auto-rĂ©paratrice)hot-cache-loadâ chargewiki-meta/hot.mddans le contexte au SessionStart / PostCompacthot-cache-update-promptâ garde dĂ©terministe : bloque le tour (exit 2) tant quewiki-meta/hot.mdn'est pas rafraĂźchi quand la session a Ă©crit une notewiki/(par vault, scopĂ© au transcript ; opt-outOBSIDIAN_ROUTER_NO_HOT_CACHE_GUARD)wiki-autocommitâ auto-commitwiki/,wiki-meta/,.raw/,.vault-meta/sur git aprĂšs les Ă©critureswiki-query-first-nudgeâ rappelle Ă Claude de consulter le vault avant de rĂ©pondre (+ injecte les PATH RESOLUTION RULES)vault-link-linterâ attrape les liens vault cassĂ©s/fantĂŽmes avant qu'ils ne t'atteignentdoc-propagation-checkerâ signale les docs qui dĂ©rivent du code shippĂ©vault-doc-startup-checkâ surface la santĂ© vault & docs au dĂ©marrage de sessioncheck-router-updateâ check de version GitHub toutes les 24h
Les hooks vivent dans hooks/ ; setup-vault.mjs les cĂąble automatiquement au bootstrap.
đ Auto-enrichissement (v0.8.2, Phase 1) â Claude propose proactivement de saver dans le wiki Ă trois moments naturels : validation (tu dis "OK" / "valide" â pin inline), rĂ©sultat obtenu (commit pushĂ©, tests verts â digest de candidats), et changement de sujet (checkpoint obligatoire avant que Claude rĂ©ponde au nouveau sujet). Agnostique du domaine : marche pour le dev, la vie perso, la recherche, la planification familiale, n'importe quoi.
Quatre modes (/obsidian-router:auto-mode <Mode> pour switcher, --persist pour écrire dans .env) :
Mode | Comportement | Pour quel usage |
| Propose, confirme toujours | DĂ©couverte de la feature · sessions longues Ă importance mixte · vaults oĂč les faux positifs coĂ»tent cher Ă nettoyer · pĂ©riode de calibration (1-2 semaines) avant de faire confiance Ă l'auto-save |
| Auto-save les items type-safe (facts, URLs, prĂ©fĂ©rences) ; ask sur les high-stakes (dĂ©cisions, ADRs, rĂšgles, techniques) | Sweet spot power-user aprĂšs calibration · dev actif avec ingestion d'URLs frĂ©quente · recherche oĂč les citations s'empilent mais les conclusions doivent ĂȘtre vettĂ©es |
| Auto-save tout ; audit log dans | Sessions Ă haute confiance en Claude · journal perso / chronique familiale · flows longs non supervisĂ©s (autoresearch, ingestion en batch) · brain-dumps solo oĂč le wiki EST le log de conversation |
| Pas de suggestions auto ; seul | Sessions de debug que tu ne veux pas polluer dans le wiki · conversations sensibles · défaut pour les vaults légal/médical/financier · préférence control-freak |
Placement â la consigne est shipped dans le CLAUDE.md template du vault, mais aussi configurable en instructions de Project Claude Desktop (pattern Ă©lĂ©gant : un Project "Journal Trading" sauve toujours dans tradingview, un Project "Personnel" dans personal). Voir docs/auto-enrichment.md pour les quatre canaux de placement (CLAUDE.md du vault, instructions de Project, Memory, CLAUDE.md global), les rĂšgles d'activation, et des boilerplates copy-paste par canal.
Ătapes d'install dans la section Installation ci-dessous.
Prérequis
Plugin (par vault) | Requis pour | OĂč l'obtenir |
Local REST API | Tous les outils | Community plugins â "Local REST API" par Adam Coddington |
MCP Router Bridge |
| Ă installer depuis |
Smart Connections |
| Community plugins â "Smart Connections" â moteur d'embeddings |
Templater |
| Community plugins â "Templater" par SilentVoid13 |
Il te faut aussi :
Node.js â„ 20.18.1 (required by
undici@7)Au moins un vault provisionné dans
~/.claude/obsidian-mcp-router/config.json. Si tu n'as jamais fait ce setup, lancenpm run setup-vault -- "<vault-path>"depuis un clone de ce repo, ou invoquescripts/setup-vault.mjsdirectement â il bootstrappe la config interactivement. RĂ©fĂ©rence du schĂ©ma :examples/config.example.json.Un vault de rĂ©fĂ©rence enregistrĂ© auprĂšs du router. Il contient le set canonique de plugins + config que
setup-vault.mjsclone dans chaque nouveau vault. Voie rapide :node scripts/setup-vault.mjs --bootstrap-reference <path>scaffolde depuis le skeleton livré (templates/reference-vault-skeleton/) et télécharge automatiquement le bridge plugin. Procédure complÚte (manuelle + troubleshooting) :docs/reference-vault-setup.md(en anglais).
Les snippets CSS sont clonés automatiquement. Depuis v0.10.1, chaque invocation de
setup-vault.mjscopie aussi<referenceVault>/.obsidian/snippets/*.cssdans le vault target et merge les basenames dans<target>/.obsidian/appearance.jsonenabledCssSnippets. Le skeleton shipno-task-strikethrough.css(dĂ©sactive letext-decoration: line-throughpar dĂ©faut d'Obsidian sur les items- [x], alignĂ© sur la conventionroadmap-discipline§2bis). Opt-out par vault dans Settings â Appearance â CSS snippets. Pour pousser une mise Ă jour de snippet (ou plugin) Ă TOUS les vaults configurĂ©s d'un coup :node scripts/setup-vault.mjs --sync-all(idempotent ; ajoute--forcepour re-cloner les fichiers existants).
Installation
đ Vault de rĂ©fĂ©rence requis pour
setup-vault.mjsâ pour bootstrapper de nouveaux vaults via le script (ce que la plupart des utilisateurs voudront), il faut d'abord un vault de rĂ©fĂ©rence configurĂ© une seule fois qui contient le set canonique de plugins. Voie la plus rapide :node scripts/setup-vault.mjs --bootstrap-reference <path>(scaffolde le skeleton + tĂ©lĂ©charge le bridge plugin en une commande, puis te guide pour installer les plugins marketplace via Obsidian). Doc complĂšte avec troubleshooting :docs/reference-vault-setup.md(en anglais).
Deux composants Ă installer : le MCP server (le router lui-mĂȘme, expose les 35 outils Ă Claude) et le plugin (expose les slash commands /obsidian-router:*).
Ătape 1 â Installer le MCP server
git clone https://github.com/tboome33/obsidian-mcp-router.git
cd obsidian-mcp-router
npm install
npm link # rend le binaire `obsidian-mcp-router` accessible globalementEnregistre-le dans ~/.claude.json (user scope) sous le nom obsidian-router :
{
"mcpServers": {
"obsidian-router": {
"type": "stdio",
"command": "obsidian-mcp-router"
}
}
}Le router lit ~/.claude/obsidian-mcp-router/config.json au dĂ©marrage (le mĂȘme fichier maintenu par setup-vault.mjs) et expose tous les vaults automatiquement.
Ătape 2 â Installer le plugin
Enregistre le marketplace globalement dans ~/.claude/settings.json :
{
"extraKnownMarketplaces": {
"obsidian-mcp-router-marketplace": {
"source": {
"source": "github",
"repo": "tboome33/obsidian-mcp-router"
}
}
}
}Puis active le plugin par workspace, PAS globalement. Le plugin charge ~38 slash commands et ~39 skills (~10k tokens de contexte par session) â tu ne veux ça que sur les workspaces qui font effectivement de l'Obsidian. Pour chaque dossier de vault et chaque workspace d'app qui consomme le router, ajoute un .claude/settings.json Ă la racine du workspace :
{
"enabledPlugins": {
"obsidian-router@obsidian-mcp-router-marketplace": true
}
}Pour les vaults bootstrappĂ©s via setup-vault.mjs, ce fichier est clonĂ© automatiquement depuis .template/.claude/settings.json â pas Ă Ă©crire Ă la main. Pour les workspaces hors-vault (repos de code qui travaillent avec le contenu d'un vault), copie le snippet ci-dessus dans <workspace>/.claude/settings.json.
RedĂ©marre Claude Code. Depuis un workspace oĂč le plugin est activĂ©, tape /obsidian-router: â les 38 slash commands doivent apparaĂźtre. Depuis un workspace sans, le namespace reste vide.
Pourquoi pas en global ? Si tu mets
enabledPluginsdans~/.claude/settings.jsonau lieu de per-workspace, le plugin se charge dans CHAQUE session Claude Code â scripts random, sessions de debug, repos sans rapport â payant ~10k tokens pour des commandes que ces sessions n'utiliseront jamais. Le project-scope garde le budget serrĂ©.
Augmenter le budget de la skill-listing (recommandé). Le router ajoute ~39 skills à la liste exposée à Claude Code. Sur une instance par défaut (
skillListingBudgetFraction: 0.01, soit 1% de la fenĂȘtre de contexte), ça pousse souvent la liste au-delĂ du budget â les descriptions sont tronquĂ©es et le triggering en langage naturel pour/save,/wiki,/autoresearchetc. casse silencieusement. RecommandĂ© : passer Ă0.05dans~/.claude/settings.json(~6k tokens supplĂ©mentaires par session). Le message "Skill listing will be truncated â N descriptions dropped" au dĂ©marrage de session est le symptĂŽme que ce rĂ©glage corrige.{ "skillListingBudgetFraction": 0.05 }Le skill
meta-setupdétecte un budget sous-dimensionné et propose d'appliquer ce changement interactivement.
Tu peux aussi utiliser le skill meta-setup du plugin pour qu'il te guide à travers les deux étapes : demande à Claude "setup le obsidian-mcp-router sur cette machine".
Rester Ă jour
Le plugin ship un hook SessionStart (hooks/check-router-update.mjs, depuis v0.10.3) qui check GitHub une fois par 24h et Ă©met une notice si une nouvelle version est disponible. La notice demande Ă Claude de la relayer sur sa premiĂšre rĂ©ponse de la session â tu es au courant sans avoir besoin de penser Ă check.
Si /plugin update obsidian-router@obsidian-mcp-router-marketplace est disponible dans ton environnement Claude Code, c'est le path one-liner. Sinon (certains environnements n'exposent pas le slash command /plugin), voir docs/how-to-update.md pour l'équivalent filesystem manuel en 5 étapes (recettes bash + PowerShell).
Opt-out â dĂ©finis une de ces env vars et le check est skippĂ© :
OBSIDIAN_ROUTER_NO_UPDATE_CHECK=true(any truthy value)OBSIDIAN_ROUTER_USER_ID=<slug>(dĂ©ploiements multi-tenant â assume que le sysadmin gĂšre les updates centralement)
Le check est un seul GET sur raw.githubusercontent.com. Pas de payload, pas de tĂ©lĂ©mĂ©trie â source dans hooks/check-router-update.mjs.
Flags CLI
obsidian-mcp-router --version
obsidian-mcp-router --help
obsidian-mcp-router --config /chemin/perso/config.json
obsidian-mcp-router --no-watch # dĂ©sactive le hot-reload du fichier de configPar dĂ©faut, le router surveille le fichier de config et le recharge automatiquement Ă chaque modification â utile quand setup-vault.mjs ajoute de nouveaux vaults, ou quand le futur plugin Obsidian Cloudflare Tunnel Ă©crit automatiquement des URLs de tunnel dans remoteVaults.
Construire tes propres macros par-dessus (avancé)
Les 38 commandes du plugin sont agnostiques du domaine. Si tu veux des macros qui enchaĂźnent plusieurs outils ou intĂšgrent les conventions de ton vault (daily notes, capture inbox, rollups hebdoâŠ), construis-les sĂ©parĂ©ment comme slash commands dans ~/.claude/commands/<name>.md â pas en PR sur ce repo. Le routeur reste neutre, les macros restent Ă toi.
Voir docs/building-commands.md pour le pattern et trois exemples illustratifs.
Désactiver un vault temporairement
Pour cacher un vault de list_vaults sans le retirer de la config, deux options :
{
// Blacklist globale (fonctionne pour les vaults locaux ET distants, par nom) :
"disabledVaults": ["template", "vps-experimental"],
// Ou flag par-remote-vault (uniquement dans remoteVaults) :
"remoteVaults": [
{ "name": "qnap", "baseUrl": "...", "apiKey": "...", "enabled": false }
]
}Les vaults désactivés apparaissent dans le log de démarrage (N disabled: ...) pour visibilité, mais n'apparaissent pas dans list_vaults et ne sont pas pingés.
Résolution du vault par défaut
Quand un appel d'outil omet l'argument vault (ex: read-search "gestion du risque"), le router doit en choisir un. Le mĂȘme appel peut rĂ©soudre vers des vaults diffĂ©rents selon le dossier depuis lequel tu lances Claude.
Cascade de résolution, par ordre de priorité décroissant :
Variable d'env
OBSIDIAN_ROUTER_DEFAULT_VAULTâ override explicite par process. Ă mettre dans le.envde ton projet pour forcer un default spĂ©cifique indĂ©pendamment du cwd.Variable d'env
VAULT_PATHâ auto-dĂ©tection. SiVAULT_PATHcorrespond Ă un chemin enregistrĂ© dansportRegistry, ce vault devient le default.setup-vault.mjsĂ©crit cette variable dans le.envde chaque vault qu'il bootstrap, donc lancer Claude Code dans le dossier d'un vault « ça marche tout seul » avec ce vault en default.config.defaultVaultâ default global explicite dans~/.claude/obsidian-mcp-router/config.json.Premier vault local en bonne santĂ© â fallback historique.
Premier vault actif quel que soit le type â dernier recours.
Le router charge automatiquement le .env du cwd au démarrage, donc les étapes 1 et 2 fonctionnent sans outillage supplémentaire. Les variables d'env déjà présentes dans le process parent gagnent sur le .env.
Trois cas concrets
Cas 1 â ton projet EST un vault (le cas le plus commun).
cd C:\VAULTS\TradingView\
claudeLe .env (écrit par setup-vault.mjs lors du bootstrap) contient :
VAULT_PATH=C:\VAULTS\TradingView
OBSIDIAN_API_KEY=...
OBSIDIAN_BASE_URL=https://127.0.0.1:27125L'auto-dĂ©tection (Ă©tape 2) matche VAULT_PATH contre ton portRegistry â default = tradingview. Aucune config nĂ©cessaire. Les outils qui omettent vault opĂšrent sur tradingview.
Cas 2 â ton projet n'est PAS un vault, mais il bosse avec un.
cd C:\Code\mon-app\
claudeCe dossier n'est pas un vault, donc VAULT_PATH n'est pas dĂ©fini. Sans intervention, le router retombe sur config.defaultVault (probablement tradingview). Si tu veux que ce projet utilise un autre vault par dĂ©faut â disons recherche pour la prise de notes â ajoute dans C:\Code\mon-app\.env :
OBSIDIAN_ROUTER_DEFAULT_VAULT=rechercheL'Ă©tape 1 gagne â default = recherche pour ce projet uniquement.
Cas 3 â ton projet EST un vault, mais tu veux un autre default.
Tu as ouvert Claude Code dans C:\VAULTS\.template\ parce que tu documentes ce vault, mais tu veux que les appels d'outils sans vault= explicite tapent sur tradingview plutĂŽt que template. Ajoute dans C:\VAULTS\.template\.env :
OBSIDIAN_ROUTER_DEFAULT_VAULT=tradingviewL'étape 1 override l'auto-détection de l'étape 2.
Vérifier quel default le router a choisi
Appelle list_vaults â le rĂ©sultat a un champ defaultVault qui indique le nom rĂ©solu.
# depuis n'importe quel projet dans Claude Code :
"liste mes vaults"Si le defaultVault n'est pas celui que tu attendais, vérifie dans l'ordre : le .env de ton projet, les variables d'env du process parent, et le champ defaultVault dans ~/.claude/obsidian-mcp-router/config.json.
Override qui n'a pas pris ?
Si tu mets OBSIDIAN_ROUTER_DEFAULT_VAULT="quelque-chose" et que le router ne trouve pas ce nom dans l'ensemble actif (faute de frappe, vault désactivé, vault supprimé), la cascade retombe sur les étapes 2/3/4/5 ET écrit un avertissement d'une ligne sur stderr :
[registry] OBSIDIAN_ROUTER_DEFAULT_VAULT="recherchee" does not match any active vault â falling through to other resolution tiers. Active vaults: template, tradingview.Mode lock (isolation mono-vault)
Par défaut le router est en mode multi-vault : chaque appel d'outil peut cibler n'importe quel vault enregistré via le paramÚtre vault, et vault: "*" fait du fan-out sur tous. C'est le bon défaut quand tu veux qu'une seule entrée MCP serve tout le monde.
Pour les situations oĂč tu veux l'inverse â un seul vault pour toute la session, le router refusant tout dĂ©bordement â utilise le mode lock.
Quand le mode lock est utile
Sécurité : tu travailles sur un vault sensible (documents juridiques, données client) et tu veux une barriÚre structurelle contre les écritures accidentelles ailleurs.
Routing par utilisateur sur une install partagée : un seul Claude Code partagé entre plusieurs personnes. Chacun verrouille sur son vault perso au début de session ; les notes des uns ne fuitent pas chez les autres.
Concentration : longue session d'ingestion ou d'autoresearch sur un wiki â le lock empĂȘche l'assistant de classer "utilement" des trucs dans un vault frĂšre.
Comment lock / unlock
Trois façons de verrouiller :
Outil MCP direct (Claude l'appelle pour toi) :
lock_vault({ vault: "tradingview" }) # volatile (cette session) lock_vault({ vault: "tradingview", persist: true }) # Ă©crit dans .env, survit aux restartsSlash command (ou langage naturel â auto-dĂ©clenchement) :
/obsidian-router:lock tradingviewâ volatile/obsidian-router:lock tradingview --persistâ persistantLangage naturel : "je ne veux travailler que sur tradingview", "verrouille sur tradingview de maniĂšre permanente"
Variable d'env au démarrage :
OBSIDIAN_ROUTER_LOCKED=tradingviewdans le
.envdu workspace. Le router la lit au boot. Permanent jusqu'Ă suppression.
Pour déverrouiller :
unlock_vaults()â en mĂ©moire uniquementunlock_vaults({ persist: true })â retire aussiOBSIDIAN_ROUTER_LOCKEDdu<cwd>/.env/obsidian-router:unlockou "redonne-moi accĂšs Ă tous les vaults"
Caveat â persist refusĂ© au home directory.
lock_vault({ persist: true })refuse si le rĂ©pertoire courant EST ton home (%USERPROFILE%sur Windows,$HOMEailleurs). C'est presque toujours une erreur â Claude Code a Ă©tĂ© lancĂ© depuis~plutĂŽt que depuis un dossier de projet, et crĂ©er~/.envte surprendrait. Le lock en mĂ©moire reste actif pour la session. Pour rendre le lock persistant dans ce cas : soit relancelock_vaultdepuis un vrai dossier de projet, soit poseOBSIDIAN_ROUTER_LOCKED=<vault>dans ton profil shell (~/.bashrc,~/.zshrc, ou PowerShell$PROFILE).
Ce qui se passe pendant le lock
Opération | Comportement |
Appel d'outil avec | â procĂšde normalement |
Appel d'outil sans | â rĂ©sout vers le vault lockĂ© (override la cascade default) |
Appel d'outil avec | â throw |
Appel d'outil avec | â throw |
| â
marche toujours. Réponse inclut un nouveau champ |
Trois cas concrets
Cas 1 â lock volatile rapide pendant une session.
Tu vas ingérer 30 articles dans ton wiki recherche et tu ne veux aucune dérive vers d'autres vaults :
"verrouille sur recherche"
Le router lock. Tous les wiki-ingest partent vers recherche. à la fin de la session (ou au restart de Claude Code), le lock disparaßt (puisque pas persisté).
Cas 2 â lock permanent pour une install partagĂ©e.
Plusieurs utilisateurs partagent la mĂȘme install Claude Code. Donald veut que chaque session Claude qu'il ouvre se positionne (et reste verrouillĂ©e) sur son vault donald, peu importe ce que dit config.defaultVault.
Dans son .env du projet habituel :
OBSIDIAN_ROUTER_LOCKED=donaldOu, équivalent, lancer une fois :
"verrouille sur donald de maniĂšre permanente"
La slash command écrit OBSIDIAN_ROUTER_LOCKED=donald dans <cwd>/.env. Désormais, en ouvrant Claude dans ce workspace, le router boot déjà locké. Les autres utilisateurs (Mitch, Bernie...) sur d'autres workspaces ont leur propre .env avec leur propre valeur de lock.
Cas 3 â changer la cible du lock.
Tu es locké sur recherche. Tu veux basculer le lock sur tradingview :
"verrouille sur tradingview"
lock_vault override le lock précédent atomiquement. Pas besoin d'unlocker avant.
Vérifier l'état du lock
"liste mes vaults"La réponse contient maintenant lockedTo :
{
"defaultVault": "tradingview",
"lockedTo": "tradingview", // â non-null = locked
"vaults": [...],
"disabled": [...]
}Quand lockedTo est null, le router est en mode multi-vault normal.
Config VAULT_* en variable d'environnement (éditable depuis le dashboard)
En plus du fichier config.json ci-dessous, un vault peut ĂȘtre dĂ©fini entiĂšrement dans une variable d'environnement â une par vault â donc Ă©ditable directement depuis l'UI Environment Variables du serveur MCPHub (sans SSH ni Ă©dition de fichier). C'est une 3á” source de config, mergĂ©e aprĂšs portRegistry + remoteVaults ; une entrĂ©e VAULT_* Ă©crase tout vault de mĂȘme nom. C'est opt-in : sans aucune VAULT_*, le router se comporte exactement comme avant.
VAULT_<NOM> = <config du vault en JSON>Requis : name, baseUrl, apiKey (le token seul â le router ajoute Authorization: Bearer lui-mĂȘme). Optionnel : description, tlsInsecure, timeoutMs (dĂ©faut 10000). Il n'y a pas de flag wireguard par-vault â WireGuard est enforced au niveau dĂ©ploiement (voir ci-dessous) ; une clĂ© wireguard rĂ©siduelle est ignorĂ©e. Les trois modes de connexion sont choisis uniquement par baseUrl (tunnel WireGuard 10.8.0.x / LAN / distant TLS â cf. exemples de la section EN « VAULT_* env-var config »).
Parsing défensif : une entrée malformée est ignorée avec un warning stderr clair nommant la clé fautive (une mauvaise var ne fait jamais planter les autres). Sur un échec de parse JSON, ni la valeur brute ni le message du parser ne sont loggés (les deux peuvent contenir l'apiKey). La variable réservée VAULT_PATH est ignorée par le scan.
Liens de lecture Ă©phĂ©mĂšres (provider view-agent optionnel) â poser OBSIDIAN_ROUTER_VIEW_AGENT_URL (+ secret partagĂ© optionnel OBSIDIAN_ROUTER_VIEW_AGENT_TOKEN, envoyĂ© en X-View-Token) branche un provider de view-links sur le router. Chaque Ă©criture de note porte alors un viewLink prĂȘt Ă cliquer vers le GUI Obsidian live du vault, naviguĂ© sur la note (â„ 0.29.0, injection dĂ©terministe cĂŽtĂ© serveur), le tool get_view_link apparaĂźt (â„ 0.28.0 â masquĂ© de ListTools tant que l'URL n'est pas posĂ©e : zĂ©ro surface morte sans l'infra), et open_in_obsidian renvoie le lien pour les vaults distants en conteneur (â„ 0.30.0). Le router ne dĂ©pend que d'un petit contrat HTTP â GET /view?vault=<nom>¬e=<chemin> â {"url": "<lien prĂȘt navigateur>"} â d'aucune infrastructure particuliĂšre : voir l'implĂ©mentation de rĂ©fĂ©rence + le contrat normatif sur obsidian-mcp-router-view-agent (config-driven, Python stdlib, quick tunnels cloudflared Ă©phĂ©mĂšres).
Smart links (rĂ©solveur optionnel) â poser OBSIDIAN_ROUTER_SMART_LINK_URL (URL de base du rĂ©solveur) et OBSIDIAN_ROUTER_SMART_LINK_SECRET (secret HMAC) fait Ă©mettre des smart links signĂ©s et stables Ă la place des view-links demandĂ©s Ă l'agent : les Ă©critures de notes et open_in_obsidian sur vault distant portent alors viewLink = <rĂ©solveur>/o/<token-signĂ©> avec viewLinkKind: "smart" â un calcul HMAC pur, zĂ©ro appel rĂ©seau (une Ă©criture ne peut jamais ĂȘtre ralentie par un agent down), et le lien reste valable dans l'historique du chat (TTL du token : 30 jours). Le lien se rĂ©sout sur le device qui clique (sonde du miroir Obsidian local â deep link obsidian:// â GUI streamĂ© en dernier recours). PrioritĂ© des providers quand les deux sont configurĂ©s : smart link â view-agent â rien ; get_view_link continue de parler directement au view-agent. Configurer les smart links signale un dĂ©ploiement remote â ne posez pas OBSIDIAN_ROUTER_SMART_LINK_* sur un router purement local, sinon open_in_obsidian rendrait un lien (opened:false, delivered:"link") au lieu de naviguer votre Obsidian local. L'implĂ©mentation de rĂ©fĂ©rence du rĂ©solveur + les contrats vivent dans le repo saas privĂ© (obsidian-mcp-router-saas).
Garde de transport au niveau dĂ©ploiement â poser OBSIDIAN_ROUTER_ENFORCE_WG_OR_LOOPBACK=true (typiquement sur une instance MCPHub multi-tenant) fait REFUSER le dĂ©marrage du router si un vault servi a un baseUrl dont l'hĂŽte n'est ni loopback (127.0.0.1/::1/localhost) ni dans le mesh WireGuard 10.8.0.0/24. C'est un check de config au boot sur les baseUrls configurĂ©s â il n'exige pas que le tunnel WireGuard soit up, et le loopback passe (donc ce n'est pas « WireGuard-only »). Fail-closed â un vault ne peut jamais ĂȘtre servi silencieusement sur un lien exposĂ© ; le check tourne aprĂšs la whitelist OBSIDIAN_ROUTER_ALLOWED_VAULTS. Opt-in ; variable absente = aucun enforce (mode local inchangĂ©). Remplace l'ancien flag wireguard par-vault. (RenommĂ© depuis OBSIDIAN_ROUTER_REQUIRE_WIREGUARD en v0.27.0 â ce nom laissait croire Ă tort que « WG doit ĂȘtre up » ; l'ancien nom marche encore comme alias dĂ©prĂ©ciĂ©.)
Config
Le router lit la config existante maintenue par scripts/setup-vault.mjs, et ajoute trois champs optionnels par-dessus :
{
// --- écrits par setup-vault.mjs (ne pas éditer à la main) ---
"referenceVault": "C:\\VAULTS\\.template",
"portStart": 27124,
"portRegistry": {
"C:\\VAULTS\\.template": 27124,
"C:\\VAULTS\\TradingView": 27125
},
// --- spécifiques au router (optionnels, modifiables librement) ---
"vaultNames": {
"C:\\VAULTS\\.template": "template",
"C:\\VAULTS\\TradingView": "tradingview"
},
"remoteVaults": [
{
"name": "qnap",
"baseUrl": "https://192.168.0.11:27125",
"apiKey": "...",
"tlsInsecure": true
}
],
"defaultVault": "tradingview"
}Voir examples/config.example.json pour un exemple complet commenté, docs/remote-vaults.md pour le guide complet d'ajout d'un vault distant, et docs/cloudflare-tunnel.md pour la recette d'exposition d'un vault via Cloudflare Tunnel avec auth optionnelle Cloudflare Access (service tokens supportés via le champ extraHeaders).
Outils exposés
Outil | Description |
| Catalogue de tous les vaults configurés avec leur état online + latence. à appeler en premier. |
| Liste les fichiers d'un répertoire d'un vault donné. |
| Lit le contenu complet d'un fichier (markdown + frontmatter). |
| Recherche texte simple (substring). Passe |
| Recherche sémantique (par sens) via les embeddings de Smart Connections. Retourne les chunks classés avec scores cosinus et breadcrumbs (chemin de titres). Nécessite les plugins |
| Crée un fichier ou remplace son contenu intégral. Passe |
| Ajoute du contenu en fin de fichier. Crée le fichier si absent (sauf si |
| Ădition chirurgicale par cible |
| Suppression définitive. Exige |
| Exécute un template Templater, écrit optionnellement le rendu dans un nouveau fichier. Les arguments sont accessibles dans le template via |
| DĂ©place ou renomme un fichier. ImplĂ©mentĂ© en GET source â PUT destination â DELETE source. Passe |
| Lit le frontmatter (objet complet ou une clĂ©). Retourne les valeurs typĂ©es â nombres, boolĂ©ens, tableaux prĂ©servĂ©s. |
| Définit/remplace une propriété de frontmatter. Type préservé (string/number/bool/null/array/object). |
| Applique plusieurs mises Ă jour de frontmatter en sĂ©quence (non-atomique â voir ROADMAP pour l'alternative atomique). |
| Restreint le router Ă un seul vault pour la session (isolation mono-vault). Voir la section Mode lock. |
| Bascule le mode d'auto-enrichissement wiki entre |
| Convertit un fichier local en markdown via le CLI Python |
| Convertit une URL distante en markdown via |
| Bundle un dépÎt git (arbre de fichiers + code source) en un seul document markdown via |
| Extracteur dĂ©terministe de mĂ©tadonnĂ©es de page (JSON-LD + OpenGraph + meta tags + titre) â alimente un frontmatter non-fabriquĂ© pour l'ingestion. |
| Suit les |
| Télécharge les images d'une page dans le vault (préservation des images lors de l'ingestion web). |
| Construit un lien markdown click-to-open prĂȘt Ă coller ( |
| Ouvre une note dans l'Obsidian en cours (et ramĂšne sa fenĂȘtre au premier plan) en appelant la route |
| Retourne une enveloppe de contexte JSON structurĂ©e pour une requĂȘte (primaryPages / semanticChunks / graphNeighbors / citations) afin que des agents non-Claude consomment le vault programmatiquement. |
| Assemble le vault en un knowledge-graph JSON typĂ© (schĂ©ma Understand-Anything : 21 types de nĆuds / 35 d'arĂȘtes). Ăcrit |
| GénÚre un parcours de lecture pédagogique déterministe et ordonné depuis la topologie de liens du knowledge-graph. Read-only. |
D'autres outils (flags CLI, hot reload de la config, skills) sont sur la roadmap â voir ROADMAP.md.
Exemples d'usage
Une fois le router enregistrĂ© dans Claude, tu prompteras Claude en langage naturel et il choisira le bon outil. Les payloads ci-dessous montrent les arguments JSON que chaque outil accepte â utile pour Ă©crire des workflows custom ou pour vĂ©rifier ce que Claude a rĂ©ellement appelĂ©.
DĂ©couverte â Ă appeler au dĂ©but de chaque session
// list_vaults â pas d'argument. Retourne chaque vault avec online/latency/missingApiKey.
{}// list_files â explorer un rĂ©pertoire.
{ "vault": "tradingview", "directory": "Sessions" }
// Ou la racine si tu omets directory :
{ "vault": "tradingview" }Lecture
// get_file â contenu markdown complet + frontmatter en texte brut.
{ "vault": "tradingview", "path": "Sessions/2026-04-29.md" }// search â recherche substring avec contexte.
{ "vault": "tradingview", "query": "AL2SI", "contextLength": 80 }
// Fan-out cross-vaults :
{ "vault": "*", "query": "money management" }// search_smart â similaritĂ© sĂ©mantique (embeddings Smart Connections).
// Retourne des chunks avec scores cosinus et breadcrumbs.
{
"vault": "tradingview",
"query": "rĂšgles de breakeven et trailing stop",
"folders": ["Formations", "Indicators"],
"excludeFolders": [".trash"],
"limit": 10
}
// Fan-out sémantique cross-vaults :
{ "vault": "*", "query": "qu'est-ce que j'ai appris cette semaine ?" }Ăcriture
// write_file â crĂ©e ou remplace.
{
"vault": "tradingview",
"path": "Trades/2026-05-02 - GLE Long.md",
"content": "---\nstatus: open\nticker: GLE\n---\n\n# GLE Long\n\nEntrée: ..."
}
// Refuser l'écrasement si le fichier existe :
{ "vault": "tradingview", "path": "...", "content": "...", "ifNew": true }// append_to_file â utile pour journaux/logs.
{
"vault": "tradingview",
"path": "Sessions/2026-05-02.md",
"content": "\n## 14:32 â TSLA breakout invalidĂ©\n\nStop touchĂ© Ă 178.40\n"
}// patch_file â Ă©dit chirurgicale, pas de réécriture intĂ©grale.
// Insertion sous un heading (chemin complet avec délimiteur ::) :
{
"vault": "tradingview",
"path": "Sessions/2026-05-02.md",
"operation": "append",
"targetType": "heading",
"target": "Session 2026-05-02::Trades du jour",
"content": "- TSLA: stop touché -1.2%\n"
}
// Modifier une seule clé de frontmatter :
{
"vault": "tradingview",
"path": "Trades/2026-05-02 - GLE Long.md",
"operation": "replace",
"targetType": "frontmatter",
"target": "status",
"content": "closed"
}
// Remplacer un bloc par id :
{
"vault": "tradingview",
"path": "Indicators/ATP/notes.md",
"operation": "replace",
"targetType": "block",
"target": "atp-config",
"content": "Config mise Ă jour pour v2.3"
}// delete_file â protĂ©gĂ©. confirm: true obligatoire.
{ "vault": "tradingview", "path": "_scratch/old.md", "confirm": true }Templater
// execute_template â rend et sauvegarde optionnellement.
// Le template doit exister dans le vault. Les arguments sont accessibles
// dans le template via tp.mcpTools.prompt("clĂ©") â note : directement sous
// tp, PAS sous tp.user.
{
"vault": "tradingview",
"name": "Templates/Trade.md",
"arguments": {
"ticker": "AAPL",
"direction": "long",
"entry": "175.20",
"stop": "172.50"
},
"createFile": true,
"targetPath": "Trades/2026-05-02 - AAPL Long.md"
}
// Rendu seul (preview), sans sauvegarder :
{
"vault": "tradingview",
"name": "Templates/Trade.md",
"arguments": { "ticker": "AAPL" }
}TLS
Le plugin Local REST API génÚre un certificat auto-signé par défaut. Pour les vaults localhost, mets tlsInsecure: true (c'est le défaut pour les vaults chargés depuis portRegistry). Pour les vaults distants derriÚre un vrai certificat TLS (par exemple un reverse proxy avec Let's Encrypt), mets tlsInsecure: false.
Licence
Apache 2.0 â voir LICENSE et NOTICE. Aucune restriction d'usage.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tboome33/obsidian-mcp-router'
If you have feedback or need assistance with the MCP directory API, please join our Discord server