Hatchdoor

Self-hosted server for Markdown and Obsidian-style vaults, with a browser UI and an MCP endpoint

By BatterWorks Rust Local · Streamable HTTP Knowledge and memoryProductivity

39 popularity score ★ 73 ⇣ 10k pulls

Connect your client

Local (once it is running)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add --transport http hatchdoor http://127.0.0.1:42824/mcp
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "hatchdoor": {
      "url": "http://127.0.0.1:42824/mcp"
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "hatchdoor": {
      "type": "http",
      "url": "http://127.0.0.1:42824/mcp"
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.hatchdoor]
url = "http://127.0.0.1:42824/mcp"
Gemini CLITerminal
gemini mcp add --scope user --transport http hatchdoor http://127.0.0.1:42824/mcp

Settings 9

HATCHDOOR_WEB_BEARER_TOKEN Required: Web UI token. The server refuses to start on a non-loopback bind (as under Docker Compose) without it and prints a fresh one.
HOST_VAULT_PATH Optional: Host folder of Markdown notes mounted into the container; Compose mounts an empty vault folder by default.
HATCHDOOR_MCP_ENABLED Optional: Turns on the /mcp endpoint; off by default, can also be set in Settings.
HATCHDOOR_MCP_BEARER_TOKEN Optional: MCP password clients send as a bearer token; can also be generated in Settings.
HATCHDOOR_MCP_WRITE_ENABLED Optional: Allows the write tools; off by default.
HATCHDOOR_MCP_RATE_LIMITS_ENABLED Optional: Turns the per-token and concurrency limits on or off.
HATCHDOOR_PUBLIC_URL Optional: Address used in upload and download links when behind a proxy.
HATCHDOOR_DEMO_MODE Optional: Read-only, unauthenticated public mode.
HATCHDOOR_USAGE_REPORT_ENABLED Optional: Daily setup report to the maintainer; off unless set to true.

What it does

Hatchdoor is a self-hosted Rust service that serves one or more folders of Markdown notes, such as Obsidian vaults, without Obsidian or any plugin running. People use its web UI to browse, search and edit notes. AI agents connect to the same vaults through an MCP endpoint built into the service at /mcp, over Streamable HTTP, on port 42824 by default.

Through MCP an agent can list vaults, run semantic or keyword search, read whole notes or just chosen sections, follow wikilinks and backlinks, select notes by tag, path or frontmatter property, and fetch attachments. With write mode turned on it can also create, edit, move, rename, archive and trash notes, rename or remove a tag across a vault, upload attachments and manage vault definitions and their Git sync. Writes use a content hash for optimistic concurrency. Deleted notes go to a .hatchdoor-trash folder, and each vault can commit and push changes to Git if you set it up that way. The Markdown files stay the source of truth: search, links and stats come from a SQLite cache that Hatchdoor rebuilds when it is deleted.

The tools reference lists 51 MCP tools, batch included. In v2.8.2, src/mcp/limits.rs caps each bearer token at 120 tool calls per rolling minute, allows 8 calls to run at once across the server (only 2 of them semantic searches), and limits one batch call to 50 read items or 20 write items. Calls over the limit get HTTP 429 with a Retry-After header. HATCHDOOR_MCP_RATE_LIMITS_ENABLED turns these limits off for setups that run behind their own gateway.

What it needs

Docker with Docker Compose, or Podman with the podman-latest image tag. Running from source needs a Rust toolchain plus Node.js and npm to build the frontend. You need a folder of Markdown notes, or an empty one. On first launch you pick a search model for Hatchdoor to download: Gemma, which needs its terms accepted, or Nomic Embed Text v1.5. Vault features stay off until that download finishes. The state directory has to be owned by UID 65532. Then turn on MCP in Settings and make an MCP password. Your client must speak Streamable HTTP and send an Authorization header.

Limits

MCP and write mode are both off by default. A pull-only Git vault, or a vault that is not ready yet, refuses writes. After setup you cannot change the search model. The server assumes one trusted user: anyone with the web token or the MCP password can reach every vault it serves. Multi-account permission scoping is planned for v3 and not released. An install from 2.4.x or earlier has to go through a 2.5 to 2.7 release before upgrading, or it will not start. Demo mode has no rate limiting of its own. It is not a sync service and does not replace Obsidian.

Who it suits

A good fit if you keep notes as Markdown files on a home server or NAS and want both a browser view and agent access on an always-on machine, across several vaults, with Git history as a safety net. It runs on your hardware and can start read-only. If you only work inside the Obsidian desktop app and want a small bridge to it, the README points to plugin-based tools such as mcp-obsidian, which need Obsidian and its Local REST API plugin running. If you want a stdio server you can launch from a single client config, pick something else: Hatchdoor is a service you deploy and keep running.

Tools 51

get_model_setup_status
Shows first-run search model setup state and terms links
accept_gemma_terms
Accepts Gemma's terms, downloads it and starts indexing
decline_gemma_terms
Declines Gemma and downloads Nomic Embed Text v1.5 instead
read_docs
Reads a page of Hatchdoor's built-in manual
search_docs
Searches the built-in manual, up to five pages
list_vaults
Lists vaults with status, capabilities and registry revision
create_vault
Adds a vault definition (write mode)
edit_vault
Replaces a whole vault definition (write mode)
enable_vault
Re-enables a disabled vault (write mode)
disable_vault
Disables a vault, keeping its files (write mode)
disconnect_vault
Removes a vault from the registry, keeping its files (write mode)
sync_vault
Runs a vault's Git sync or local commit now (write mode)
retry_vault
Retries a vault's failed Git operation (write mode)
publish_recovery_branch
Pushes a two-way vault's conflicting side to a recovery branch (write mode)
refresh_vault
Requests a rebuild of a vault's index (write mode)
search_notes
Semantic or keyword search; 10 hits by default, up to 50
get_note
Reads one note's Markdown and metadata
get_note_outline
Lists a note's headings with section sizes
get_note_section
Reads chosen sections of a note by heading
get_note_links
Returns a note's outgoing links and backlinks
resolve_wikilink
Resolves a wikilink target within a vault
get_tree
Returns the folder tree of one or all vaults
get_stats
Returns vault statistics and the running version
get_graph
Returns the link graph of one or all vaults
get_frontmatter
Reads a note's frontmatter without the body
recently_modified
Lists recently changed notes; 5 by default, up to 25
query_notes
Selects notes by tag, path or frontmatter property
find_text
Finds notes containing a literal string, with counts
evaluate_saved_query
Runs a saved Bases-style query found in a note
list_note_attachments
Lists the attachments a note references
get_attachment
Fetches an attachment's bytes
get_attachment_import_config
Reports whether a vault accepts uploads and the limits
create_note
Creates a Markdown note, adding folders as needed
update_note
Replaces a note's full content
append_to_note
Appends text to a note
edit_note
Replaces one exact string in a note
replace_section
Replaces or inserts content around a heading
update_frontmatter
Merges keys into a note's frontmatter
rename_note
Renames a note and rewrites links to it
move_note
Moves a note to another folder, updating links
move_rename_note
Moves and renames a note in one step
archive_note
Moves a note to the archive folder
delete_note
Moves a note to .hatchdoor-trash
rename_tag
Renames a tag and its nested tags across a vault
delete_tag
Removes a tag from every note in a vault
import_attachment
Uploads an attachment sent as base64
create_upload_link
Creates a short-lived upload link for a file
move_attachment
Moves an attachment and rewrites references
rename_attachment
Renames an attachment and rewrites references
delete_attachment
Moves an attachment to .hatchdoor-trash
batch
Runs a list of tool calls in order, as one call

Similar servers