backrooms
Works on a git clone of the vault and can integrate with git: optional modes to commit every write (one commit per write touching exactly those files) or to also fetch/rebase before writes and push after commits, with configurable pull interval and conflict aborts. Provides git:status, git:log, git:show and git:revert commands so agents can inspect and undo changes, and uses git history to determine a note's original creation date.
Serves an Obsidian vault (a git clone) headlessly without the Obsidian app, implementing a subset of the Obsidian CLI. Agents can search notes, inspect backlinks, read and edit note content, set frontmatter properties, rename/move and delete notes (to .trash/), with atomic writes, rollback of multi-file changes, and safety checks such as rejecting renames that would break links. Also reimplements community plugin behavior when the vault enables it, e.g. the Linter's yaml-timestamp rule for created/modified dates. Exposed both as a CLI and as ten agent-oriented MCP tools (search, list, read, vault, history, create, edit, move, delete, undo), and a vault-root AGENTS.md is injected into the server instructions.
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., "@backroomssearch my vault for notes about pizza"
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.
backrooms
A headless server for an Obsidian vault. backrooms works on a git clone of the vault and implements a subset of the Obsidian CLI without the Obsidian app, so agents can read, search and edit the vault from anywhere, for example from the Claude app on a phone through MCP.
docs/vision.md explains why backrooms exists and what it is for.
docs/obsidian-cli-coverage.md lists the Obsidian CLI features backrooms needs.
docs/compatibility.md says which commands backrooms implements, how they are checked against Obsidian, and where backrooms deliberately differs.
docs/adr/ holds the architecture decisions.
Install
backrooms runs on Bun:
bun add -g @felixscherz/backrooms # or run it once with: bunx @felixscherz/backrooms helpRelated MCP server: obsidian-gate
Usage
backrooms takes the same commands and key=value parameters as the Obsidian CLI:
cd ~/notes # or: export BACKROOMS_VAULT=~/notes
backrooms search query="pizza"
backrooms backlinks path="Note.md" format=json counts
backrooms property:set path="Note.md" name=last_reviewed value=2026-10-21 type=date
backrooms rename path="Old.md" name="New"
backrooms help # every command with its parametersThe vault is the folder in BACKROOMS_VAULT, or the nearest folder at or above the current one that contains a
.obsidian folder. vault=<name> is accepted and ignored, since backrooms serves one vault.
Commands that only make sense with the app running, such as open or command, fail with an error that says they are
not supported.
Commands backrooms adds
edit path=<path> old=<text> new=<text> [all]replaces an exact piece of text. The text has to occur exactly once unlessallis set. A remote agent cannot edit files itself, so this replaces the file edits an agent makes on a local vault.file path=<path>prints aversion. Pass it asversion=<version>toedit,append,prepend,deleteorcreate ... overwriteand the write is rejected if the file changed since.create ... overwriterequires it.git:status,git:log [limit=<n>] [path=<path>],git:show commit=<id>andgit:revert commit=<id>let an agent look at and undo what backrooms changed.
Writes
Every write goes through one write path (ADR 2): only the intended bytes change, each file is replaced atomically,
multi-file changes such as a rename roll back if they fail part way, deleted notes go to .trash/, and backrooms never
touches .obsidian/ or other hidden folders. A rename or move that would make any link point at a different file is
rejected. A write that fails says whether the vault was left unchanged or names the files it could not restore.
Several backrooms processes on one vault, such as the MCP server and a CLI run, take turns: a write holds a lock file in
.git/, or in the system's temporary folder when the vault is not a git repository, while it runs. A lock left by a process that ended is taken over, and a write gives up
with a busy error after waiting 10 seconds for a lock that a running process holds.
Plugins
backrooms reimplements some features of community plugins and applies them when the vault enables the plugin, with the
plugin's own settings from .obsidian/plugins/<id>/data.json (ADR 7). A note is linted when a command creates or
changes it, not when it is only renamed, moved or deleted. Like the Linter, backrooms only lints when the Linter lints on
save or on leaving a note, or updates timestamps as a note changes, and leaves the folders and files it ignores alone.
Plugin | What backrooms does |
Linter ( | The |
Timestamps are written in the local time of the process, so set TZ on a server. A note without a creation date gets
the date git first saw it, or the file system's date outside git. When the Linter's settings ask for something backrooms
cannot do the same way, such as a date format with month names, writes fail with an error.
Git
| Behavior |
| backrooms does not touch git. |
| Every write becomes one commit of exactly the files it touched. |
| Also fetches and rebases before each write and every minute in the MCP server, and pushes after each commit. |
BACKROOMS_PULL_INTERVAL sets how many seconds the MCP server waits between pulls in sync mode (default 60).
A rebase that conflicts is aborted. backrooms keeps its local commits, stops syncing and reports it in git:status and
as a warning after each write, until a human resolves it.
MCP
backrooms mcp serves the vault over stdio with ten tools designed for agents (ADR 9), rather than one per CLI
command: search, list, read, vault and history read, create, edit, move, delete and undo write.
They take typed arguments, name a note by its path or its name as note, and return JSON. edit applies several
changes as one write and one commit. Content is taken literally, without the \n escapes the shell needs.
The server's instructions tell the agent how the tools work together. When the vault has a note AGENTS.md at its
root, its text is added to them, so the vault's conventions, such as how notes are named, reach the agent without
exploring the vault. A client sees a change to it the next time it connects.
{
"mcpServers": {
"backrooms": { "command": "backrooms", "args": ["mcp"], "env": { "BACKROOMS_VAULT": "/srv/notes" } }
}
}Remote MCP with OAuth
backrooms serve serves the same tools over streamable HTTP at /mcp, for the Claude apps and Claude Code on other
devices. backrooms is its own OAuth server for one person who signs in with a passphrase (ADR 8). Run it behind a
reverse proxy that terminates TLS.
backrooms auth:hash < passphrase.txt # prints the hash for BACKROOMS_PASSPHRASE_HASH; use 16 or more charactersVariable | Meaning |
| Public origin, such as |
| Output of |
| Local address to listen on, default |
| Folder for the sign-in database, default |
| Comma-separated origins whose clients may sign in, default |
In Claude, add a custom connector with the URL BACKROOMS_URL/mcp and the default authentication settings. Claude
opens backrooms' sign-in page, which names the client asking, and you enter the passphrase. Tokens last an hour and
are refreshed for up to 30 days of not being used. backrooms auth:revoke ends every sign-in. Five wrong passphrases
in a row pause sign-in for 15 minutes.
Development
backrooms is written in TypeScript and runs on Bun.
bun install
bun test
bun run typecheck
bun run format
bun run build # single executable in dist/backroomsThe tests drive the CLI against temporary vaults on disk, and the git tests use real repositories with a bare remote.
compat/compat.test.ts checks that backrooms answers like the Obsidian CLI on test-vault/, against
answers recorded with bun compat/record.ts (see docs/compatibility.md).
compat/linter.test.ts does the same for the Linter plugin on compat/linter-vault/, recorded with
bun compat/record-linter.ts.
License
Related MCP Connectors
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Notes and memory assistant: one Markdown vault that Claude, ChatGPT and any MCP client can share.
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Search, read, and safely update Markdown notes in your connected Phasoric knowledge vaults.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceExposes Obsidian vault tools via Model Context Protocol (MCP) server over stdio, HTTP, or SSE transports, enabling AI assistants to read, write, search, and manage vault notes with 28+ built-in tools and CLI bridge integration.2PolyForm Noncommercial 1.0.0
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to read, search, write, and link notes in an Obsidian vault via MCP tools and resources.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to list, read, search, create, update, rename, and delete markdown notes in a local Obsidian vault via an HTTP MCP endpoint.15 npm1MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP-capable assistants to securely search, read, create, edit, move, and delete notes in a private Obsidian vault via Cloudflare, using official Obsidian Sync and OAuth-protected tools.87 npmAGPL 3.0