Obsidian Vault MCP Server
Provides tools for accessing and managing notes in an Obsidian vault via Obsidian Sync, including listing, reading, searching, writing, appending, and deleting markdown files.
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 Vault MCP Serversearch my vault for notes about project ideas"
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 + Claude via Cloudflare
Access your Obsidian vault from Claude (web, desktop, Code) using an MCP server on Cloudflare Workers + Containers + R2.
No NAS, no Docker Compose, no tunnels. Just Cloudflare infrastructure with the Agents SDK for a proper MCP server.
Architecture
Obsidian (phone, desktop)
│
│ Obsidian Sync (your existing subscription)
▼
Cloudflare Container (Node.js 22)
runs `ob sync --continuous`
writes to R2 via FUSE mount
│
▼
Cloudflare R2 (vault file storage)
▲
│ R2 binding (native)
│
Cloudflare Worker (MCP server via Agents SDK)
tools: list, read, search, write, append, delete
auth via bearer token (or OAuth / Cloudflare Access)
▲
│ MCP over Streamable HTTP
│
Claude (web, desktop, Code)The Container and Worker both access the same R2 bucket — the Container via FUSE-mounted filesystem, the Worker via its R2 binding.
MCP Tools
Tool | Description |
| List all markdown notes with paths, sizes, and dates |
| Read the full content of a note by path |
| Full-text search across all notes with snippets |
| Create or overwrite a note |
| Append to an existing note (or create it) |
| Delete a note |
Prerequisites
Cloudflare account with Workers Paid plan ($5/month)
Active Obsidian Sync subscription
Node.js 22+ on your workstation
wranglerCLI:npm install -g wrangler
Setup
0. Wrangler Login
wrangler loginAll required scopes are granted by default.
1. Generate Obsidian Auth Token
One-time step on your workstation:
npm install -g obsidian-headless
ob login
# Enter email, password, MFA code if enabled
ob sync-list-remote
# Note your vault name2. Create the R2 Bucket
wrangler r2 bucket create obsidian-vaultCreate an R2 API token for the Container's FUSE mount:
Cloudflare dashboard → R2 → Overview → Manage R2 API Tokens
Create token with Object Read & Write on
obsidian-vaultSave the Access Key ID and Secret Access Key
3. Configure Environment
Copy the example env file and fill in your values:
cp .dev.vars.example .dev.varsEdit .dev.vars with your Cloudflare account ID, R2 credentials, and Obsidian
auth. This file is used by wrangler dev for local development and by the
setup script to push secrets to Cloudflare. It's already in .gitignore.
4. Deploy
Run the setup script to create the R2 bucket, push all secrets, and deploy:
./scripts/setup.shOr run steps individually:
./scripts/setup.sh bucket # Create R2 bucket
./scripts/setup.sh secrets # Push secrets to Cloudflare
./scripts/setup.sh validate # Check prerequisites
./scripts/setup.sh deploy # Validate + install deps + deploy + restart container
./scripts/setup.sh status # Check sync container health
./scripts/setup.sh restart # Restart sync container
./scripts/setup.sh container-logs # View sync container logsYour MCP server is live at:
https://obsidian-mcp.<your-subdomain>.workers.dev/mcp
5. Connect Claude
Claude.ai (web)
Settings → Connectors → Add custom connector:
URL:
https://obsidian-mcp.<your-subdomain>.workers.dev/mcp?token=YOUR_MCP_AUTH_TOKENLeave OAuth fields blank — the token in the URL handles auth
Claude Code
claude mcp add \
--transport http \
--scope user \
obsidian-vault \
https://obsidian-mcp.<your-subdomain>.workers.dev/mcpClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"obsidian-vault": {
"url": "https://obsidian-mcp.<your-subdomain>.workers.dev/mcp"
}
}
}How Data Flows
You edit a note on your phone:
Obsidian Sync pushes the change
Container's
ob sync --continuouspulls it to/vaultrsync mirrors it to
/mnt/r2(R2 via FUSE)Next time Claude reads or searches, it sees the update via R2 binding
Claude creates a note:
Worker writes to R2 via binding (
VAULT.put())Container's FUSE mount sees the new file on R2
rsync picks it up (or
ob syncdetects it if writing directly)ob syncpushes it upstream via Obsidian SyncIt appears on your phone and desktop
Development
# Local dev (MCP server only, no container)
npm run dev
# Deploy
npm run deployCost
Service | Usage | Cost |
Workers Paid Plan | Already paying | $5/month (covers everything) |
R2 | Markdown vault, <100MB | Free tier (10GB included) |
Container | 1 instance, mostly idle | Included in Workers plan |
Total additional | $0 |
Project Structure
obsidian-mcp/
├── src/
│ └── index.ts # MCP server (Agents SDK + R2)
├── sync-container/
│ ├── Dockerfile # Headless sync + FUSE mount
│ └── entrypoint.sh # Auth, mount, sync, mirror
├── scripts/
│ └── setup.sh # Create bucket, push secrets, deploy
├── .dev.vars.example # Template for env vars / secrets
├── wrangler.jsonc # Worker + R2 + Container config
└── package.jsonNext Steps
These are left as exercises to harden the setup for your needs:
Auth Hardening
The included auth (MCP_AUTH_TOKEN secret) supports both Authorization: Bearer
headers and ?token= query params. The URL token approach is convenient for
Claude.ai connectors where custom headers aren't always available.
For shared or public deployments, consider stronger options:
Cloudflare Access: Put Zero Trust Access in front of the Worker for identity-based SSO with audit logs and no code changes
OAuth: Integrate
workers-oauth-providerfor GitHub/Google OAuth flows
Container Auth
Check whether obsidian-headless supports --token or env-var-based auth for
ob login to avoid interactive prompts. If not, persist the auth session from a
one-time interactive login to an R2 object and restore it on container start.
Container Restart Resilience
The ob sqlite state file lives on ephemeral container disk. A restart triggers
a full re-sync. To fix: add a SIGTERM trap in entrypoint.sh that uploads the
state file to R2, and restore it on startup.
Search Performance
The brute-force search reads every .md from R2 per query — fine for <500 files.
For larger vaults, build a search index in D1
or Workers KV, updated by the rsync loop.
Bidirectional Sync Conflicts
MCP write_note writes directly to R2 while the container's rsync also writes.
Options: write to a staging prefix (_incoming/), use R2 event notifications, or
add last-modified checks before writes.
Attachments
Currently filters to .md only. Extend to support images, PDFs, and other
vault attachments with additional tools.
Troubleshooting
Docker must be running — The sync container requires Docker. Run docker info
to verify. The validate subcommand checks this automatically.
Two passwords — OBSIDIAN_PASSWORD is your Obsidian account password (used
to log in at obsidian.md). VAULT_PASSWORD is the separate end-to-end encryption
password set in Obsidian → Sync → Encryption. Leave VAULT_PASSWORD empty if
your vault doesn't use E2EE.
Deploy doesn't restart containers — wrangler deploy does not restart running
containers. The setup script handles this automatically. If deploying manually,
restart with ./scripts/setup.sh restart.
Container logs not in wrangler tail — Container stdout is not streamed through
wrangler tail. Use ./scripts/setup.sh container-logs instead.
Build fails at tigrisfs — The FUSE mount binary is fetched during Docker build. Check your network and Docker setup. The version is pinned in the Dockerfile.
Component Reference
Component | What it does |
Official Obsidian CLI, syncs vault headlessly | |
FUSE adapter, mounts R2 as a local filesystem | |
| Handles MCP transport, sessions, auth |
| Tool registration, JSON-RPC protocol |
Object storage, shared between Container and Worker | |
Runs the sync process alongside the Worker |
This server cannot be installed
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/JonHollander/obsidian-mcp-cloudflare'
If you have feedback or need assistance with the MCP directory API, please join our Discord server