Optimike Obsidian MCP
Provides tools for interacting with an Obsidian vault, including reading/writing notes, managing frontmatter and tags, searching, semantic search via Smart Connections, querying Tasks, and managing Obsidian Bases.
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., "@Optimike Obsidian MCPsemantic search for 'quarterly goals'"
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.
Optimike Obsidian MCP
French version: README.fr.md Operations guide: OPERATIONS.md Guide d’exploitation (FR): OPERATIONS.fr.md

MCP (Model Context Protocol) server for Obsidian with shared local caching, integrated Tasks tools, and semantic search powered by Smart Connections.
TL;DR
npm install
npm run build
node dist/stdio-proxy.jsRecommended for Codex: point your MCP config to dist/stdio-proxy.js, not directly to dist/index.js.
Prerequisites
Node.js >= 22.7.5
Obsidian Desktop for
livemode. Headless modes only require a local vault path.Plugins:
Local REST API (required for live REST tools): https://github.com/coddingtonbear/obsidian-local-rest-api
Smart Connections (required for semantic search): https://github.com/brianpetro/obsidian-smart-connections
Bases Bridge (REST) (required for live/plugin-backed
.basetools, bundled in this repo)Obsidian Tasks plugin (required for canonical Tasks behavior)
For semantic search, make sure your vault has a
.smart-envfolder
Installation
From source:
git clone https://github.com/optimikelabs/optimike-obsidian-mcp.git
cd optimike-obsidian-mcp
npm install
npm run buildRun the recommended local MCP entrypoint:
node dist/stdio-proxy.jsWhy
Connect Obsidian to MCP agents (Codex, IDEs, etc.)
Expose Obsidian REST tools (read/write, frontmatter, tags, search)
Provide local vector search via Smart Connections (
.smart-env)Keep one durable local backend instead of re-spawning heavy state on every stdio run
What it can do
Optimike Obsidian MCP gives agents a structured way to work with an Obsidian vault:
read, list, update, and search notes
manage frontmatter and tags
query and update Obsidian Bases through the bundled Bases Bridge
inspect and query Obsidian Tasks
run semantic search against a Smart Connections index
check server health, cache state, degraded mode, and write policy
In short: it does more than read notes. It exposes the vault as an operational MCP surface, with read/write tools, structured metadata operations, Tasks, Bases, semantic search, and server health/status observability.
Shared backend use
The durable backend is useful in local setups, but it becomes especially valuable in shared or remote backend setups.
Instead of syncing and indexing the vault separately for every agent client, clients can talk to one MCP backend that owns the cache, semantic metadata, task cache, and Obsidian operations. The backend still needs access to the vault itself, a mounted vault path, or the Obsidian REST API, but the agent clients do not each need their own full vault sync or indexing layer.
This makes the MCP a practical boundary between agents and Obsidian: agents call tools, the backend handles the vault.
Highlights
Complete MCP toolset (notes, frontmatter, tags, global search, etc.)
Integrated Tasks tools:
list_all_tasksandquery_tasksLocal semantic search
smart_semantic_searchServer health/status tools:
obsidian_runtime_statusandobsidian_runtime_maintenanceRead-only degraded mode for
obsidian_read_noteandobsidian_list_noteswhen Obsidian REST is downShared SQLite store for vault content, task cache, and semantic manifest data
Embedder‑agnostic: query embedding aligned to the vault model
Ollama / OpenAI support (env overrides); Xenova / Transformers is disabled until its vulnerable ONNX/protobuf chain can be safely reintroduced
Architecture (overview)
Obsidian + plugins (Local REST API, Bases Bridge, Smart Connections)
Optimike Obsidian MCP (this server)
MCP Agents (Codex, IDEs, etc.)
The server acts as a bridge between agents and Obsidian, adds a “Base” layer for .base files, and persists shared runtime state locally so Codex can stay fast and stable across runs.
Bases Bridge (REST) — why & how
Obsidian has no native API for Bases (.base).
The Bases Bridge (REST) plugin fills the gap by adding dedicated REST endpoints.
Endpoints exposed by Bases Bridge
Official prefix (recommended):
GET /extensions/obsidian-bases-bridge/bases
List all available bases.GET /extensions/obsidian-bases-bridge/bases/:id/schema
Return the schema (properties, formulas, views).POST /extensions/obsidian-bases-bridge/bases/:id/query
Query a base (filters, sorting, pagination, evaluate).POST /extensions/obsidian-bases-bridge/bases/:id/upsert
Bulk frontmatter upsert.POST /extensions/obsidian-bases-bridge/bases
Create/validate a.basefile.GET /extensions/obsidian-bases-bridge/bases/:id/config
Read the base YAML.PUT /extensions/obsidian-bases-bridge/bases/:id/config
Update the base YAML.
Legacy aliases (MCP compat):
GET /basesGET /bases/:id/schemaPOST /bases/:id/queryPOST /bases/:id/upsertPOST /basesGET /bases/:id/configPUT /bases/:id/config
Engine / Evaluate
When evaluate: true, the bridge returns:
source: "engine": auto‑cache + formula evaluation (no Bridge view)source: "fallback": partial on‑disk evaluation if engine is OFF
MCP tools for Bases
This server exposes “Base” MCP tools:
bases_list: list basesbases_get_schema: fetch schemabases_query: paged query with filters/sortbases_upsert_rows: bulk frontmatter updatebases_upsert_config: validate or update base YAML/JSON configbases_create: create/validate a.base
bases_upsert_rows is batch-safe by default for live Obsidian writes: it runs a live preflight, supports dryRun, configurable chunkSize, delayMs, maxRetries, retryBackoffMs, and requestTimeoutMs, and returns a structured summary with changed_count, failed_count, failed_operations, and retry metadata. For large or sensitive batches, prefer dryRun: true first, then chunkSize: 1, continueOnError: true, and maxRetries: 2.
Protected or virtual keys (file.*, formula.*, création/creation, modification) are refused before writing. Bridge-side processFrontMatter timeouts are surfaced as retryable write_timeout errors; treat them as an Obsidian busy/indexing/locked signal before blaming the payload.
Final Runtime Model
The repo supports two local runtime modes:
stdio proxy(recommended for Codex): a lightweight stdio process that auto-starts a local Streamable HTTP backend if neededhttp backend: the actual long-lived backend process that owns the heavy cache / warmup work
The backend persists vault content to a shared SQLite store and keeps only a bounded hot set in RAM. By default the cache lives at:
<vault>/.obsidian/optimike-mcp/shared-cache.sqliteThe same database also stores:
file_cachefor note contenttask_file_cachefor parsed Tasks datasemantic_manifestandsemantic_vectorsfor semantic metadata
If OBSIDIAN_VAULT is not set, the server falls back to the parent vault inferred from SMART_ENV_DIR, then to the project root.
Useful env overrides:
OBSIDIAN_RUNTIME_MODE=live|hybrid|headless-readonly|headless-guarded|headless-filesystemto choose the runtime contractOBSIDIAN_SHARED_CACHE_DB_PATHto move the shared SQLite fileOBSIDIAN_CONTENT_HOT_CACHE_LIMITto tune the bounded in-memory hot setOBSIDIAN_CACHE_SOURCE=auto|filesystem|restto choose cache refresh source (autoprefers the local vault path when available)OBSIDIAN_CACHE_CONCURRENCYto bound local filesystem refresh workOBSIDIAN_VAULT_EXCLUDE_PATTERNSto add comma- or newline-separated gitignore-style exclusions on top of the built-in vault safety policyMCP_WRITE_MODE=readonly|guarded|fullto enforce server-side write safety (fullis the default; setguardedorreadonlyexplicitly to harden a host)MCP_GUARDED_MAX_WRITE_CHARSandMCP_GUARDED_MAX_BATCH_OPERATIONSto tune guarded-mode limits
For production-like tests on a real vault, set OBSIDIAN_SHARED_CACHE_DB_PATH outside the vault so validation databases do not pollute the synced note tree.
Vault exclusion policy:
Built-in filesystem/cache exclusions cover
.obsidian,.trash,.git,.tmp,tmp,node_modules, screenshots folders, build/cache folders, SQLite/DB files, and log files.OBSIDIAN_VAULT_EXCLUDE_PATTERNSlets an operator add project-specific exclusions, for exampletmp/**,**/tmp/**,Efforts/Archives/**.Exclusions apply to filesystem cache refreshes and local Bases fallback scans. They do not claim Desktop parity and they do not stop Obsidian Sync itself from downloading files; use a clean server vault or Sync-side hygiene for that.
npm run check:vault-exclusions -- --vault=/path/to/vaultprints the policy effect before running a long headless validation.
This runtime exposes the Tasks surface directly from the main MCP, so Codex no longer needs a second dedicated optimike-obsidian-tasks-mcp entry when using this server.
Warm semantic refreshes now load from SQLite first instead of re-reading the whole .smart-env path every time.
Runtime modes
live(default): Obsidian Desktop + Local REST API. Full REST, write, and Bases Bridge surface.hybrid: starts from the local vault/cache and uses Local REST API whenOBSIDIAN_API_KEYis configured. The API startup check is non-blocking. If no API key is configured,OBSIDIAN_VAULTis required.headless-readonly: no Obsidian Desktop, no Local REST API, noOBSIDIAN_API_KEY. RequiresOBSIDIAN_VAULT; setOBSIDIAN_CACHE_SOURCE=filesystemfor an explicit server profile. Exposes read/list/search/tasks/semantic/runtime tools plus local readonlybases_list,bases_get_schema, andbases_query.headless-guarded: no Obsidian Desktop; exposes the headless read surface plus guarded filesystem writes forobsidian_update_note,obsidian_search_replace, andobsidian_manage_frontmatter. Note updates are append/prepend only; overwrite remains blocked by the guarded write policy. Local readonly Bases fallback is also available.headless-filesystem: no Obsidian Desktop; exposesheadless-guardedplus bounded filesystem features: frontmatter/inline tags, local tag index/audit and dry-run rename, admin move/archive/delete operations withexpectedHashorexpectedMtime, batch frontmatter with dry-run,.baseYAML create/config, Bases rows as Markdown frontmattersetoperations, and minimal JSON Canvas create/validate helpers.
Headless means Optimike MCP running over a synchronized Markdown vault. It does not mean Obsidian Desktop, community plugins, command palette, active file, or Bases Bridge are available without Desktop.
Smoke tests and runtime contract:
npm run test:runtime
npm run smoke:headless-readonly
npm run smoke:hybrid-unavailable
npm run smoke:hybrid-api-available
npm run smoke:headless-guarded
npm run smoke:headless-filesystem
npm run smoke:headless-status
npm run check:vault-exclusions -- --vault=/path/to/vault
npm run test:headless-long-run
npm run snapshot:vault
npm pack --dry-runnpm run test:runtime runs the build, all runtime mode smokes, and the HTTP health/status smoke. It uses temporary vaults and does not require a real Obsidian vault or API key. The headless smokes also assert that excluded tmp/** content is not indexed.
For a mode-by-mode comparison, see Runtime Capability Matrix. For the dedicated server path, see Headless Server Profile. For agent routing across MCP, Desktop/API, filesystem, CLI, and format skills, see MCP Routing Guide.
Format validation:
obsidian_validate_formatis available in every runtime mode.It validates Obsidian Markdown,
.baseYAML, and JSON Canvas structure before writes.It catches local format issues but does not render Obsidian, load plugins, or evaluate exact Bases UI semantics.
Local Bases fallback:
bases_list,bases_get_schema, andbases_queryare available in headless modes withsource: "local-fallback".The fallback reads
.baseYAML fromOBSIDIAN_VAULTand cached Markdown frontmatter from the shared cache.It supports direct equality filters, arrays,
contains,in, comparisons, simple sorting, pagination, and schema inspection.It does not evaluate Obsidian formulas, plugin-specific filters, calculated properties, or exact UI view semantics.
Useful scripts:
npm run build
npm run start:proxy
npm run start:httpHealth endpoint when running the backend directly:
curl http://127.0.0.1:3010/healthzExtended health / maintenance:
GET /healthz?integrity=1adds a SQLite integrity checkMCP tool
obsidian_runtime_statusreturns process, cache, semantic, and degraded-mode statusMCP tool
obsidian_runtime_maintenancesupports:integrity_checkrun_maintenancerefresh_vault_cacherefresh_semantic_cacherefresh_tasks_cacherefresh_all
Runtime write safety:
readonlyblocks all write tools except validation-only operationsguardedallows bounded explicit writes and blocks destructive operations such as delete, overwrite, frontmatter unset, broad regex replace-all, and large batchesfullis the default and keeps unrestricted write behavior for trusted local environments
Guarded filesystem writes support optional expectedHash and expectedMtime preconditions. Use expectedHash for multi-agent or synced-vault writes so stale updates fail as explicit conflicts instead of overwriting newer content.
Agent-context controls:
obsidian_list_notessupportsresponseMode="compact",limit, andcursorobsidian_global_searchsupportsresponseMode="compact"while keeping existing page/pageSize paginationlist_all_tasksandquery_taskssupportresponseMode="compact"|"detailed",responseLimit, andcursorreading an identified note remains full-fidelity through
obsidian_read_note
Typical checks:
curl http://127.0.0.1:3010/healthz
curl http://127.0.0.1:3010/healthz?integrity=1Minimal Codex Config
In ~/.codex/config.toml:
[mcp_servers.optimike-obsidian-mcp-stdio]
command = "node"
args = ["/path/to/optimike-obsidian-mcp/dist/stdio-proxy.js"]
tool_timeout_sec = 900
[mcp_servers.optimike-obsidian-mcp-stdio.env]
MCP_HTTP_HOST = "127.0.0.1"
MCP_HTTP_PORT = "3010"
MCP_PROXY_START_TIMEOUT_MS = "20000"
OBSIDIAN_VAULT = "/path/to/<vault>"
# Smart Connections
SMART_ENV_DIR = "/path/to/<vault>/.smart-env"
ENABLE_QUERY_EMBEDDING = "true"
# Recommended: auto (do not set)
# QUERY_EMBEDDER = "auto"
# Obsidian REST (if Local REST API plugin is active)
OBSIDIAN_BASE_URL = "http://127.0.0.1:27123"
OBSIDIAN_API_KEY = "<token>"
# Startup behavior (optional, recommended for faster startup)
# OBSIDIAN_STARTUP_BLOCKING=false starts MCP immediately and runs health check in background.
OBSIDIAN_STARTUP_MAX_RETRIES = "2"
OBSIDIAN_STARTUP_RETRY_DELAY_MS = "1200"
OBSIDIAN_STARTUP_BLOCKING = "false"
# Shared cache tuning (optional)
# OBSIDIAN_SHARED_CACHE_DB_PATH = "/path/to/<vault>/.obsidian/optimike-mcp/shared-cache.sqlite"
# OBSIDIAN_CONTENT_HOT_CACHE_LIMIT = "64"Notes:
Keep this config local in
~/.codex/config.toml(do not commit personal machine paths).Use logical placeholders in documentation (
/path/to/...) and keep real paths only in local config.dist/index.jsis still the backend entrypoint, but Codex should point todist/stdio-proxy.js.
Obsidian Local REST API Setup
Local REST API plugin repo: https://github.com/coddingtonbear/obsidian-local-rest-api
In Obsidian:
install and enable Local REST API
enable the HTTP server
copy the API key
set
OBSIDIAN_BASE_URLandOBSIDIAN_API_KEYin your MCP env
Example:
export OBSIDIAN_BASE_URL=http://127.0.0.1:27123
export OBSIDIAN_API_KEY=<your_api_key>Security
Keep
OBSIDIAN_API_KEYprivate and local.Do not expose the Obsidian REST API to the public internet.
Keep
OBSIDIAN_API_KEYandOPENAI_API_KEYin environment variables, not committed config files.Current dependency check:
npm auditreports 0 known vulnerabilities, andnpm audit signaturesverifies registry signatures for the installed npm dependency tree.If you expose the MCP over HTTP beyond localhost, enable
MCP_AUTH_MODE=jwtorMCP_AUTH_MODE=oauth, use a strong secret/provider, and keepMCP_ALLOWED_ORIGINSnarrow. The defaultstdio/127.0.0.1profile is the safer local setup.
Legacy WSL2 Troubleshooting: Obsidian on Windows
Most local setups should use the native stdio entrypoint and 127.0.0.1.
This section is only for older or explicit WSL2 setups where Obsidian runs on
Windows and Codex runs inside WSL2:
127.0.0.1from WSL points to WSL, not Windowsuse the Windows host IP (the WSL gateway) for
OBSIDIAN_BASE_URL
Example:
GW=$(ip route | awk '/default/ {print $3; exit}')
export OBSIDIAN_BASE_URL=http://$GW:27123If you use a Windows portproxy, adapt the port accordingly.
Main MCP Surface
The main MCP now includes:
note tools: read, list, update, search-replace, tags, frontmatter
Bases tools: list, schema, query, create, upsert config, upsert rows
Tasks tools:
list_all_tasks,query_taskssemantic tools:
smart_semantic_search,smart_search,smart-searchserver health/status tools:
obsidian_runtime_status,obsidian_runtime_maintenance
Tasks Integration
The main MCP now owns the Tasks surface directly.
What this means:
Codex does not need a separate
optimike-obsidian-tasks-mcpentry anymorelist_all_tasksandquery_tasksare exposed by this main serverparsed task data is persisted in
task_file_cacheinside the shared SQLite database
Dependencies for Tasks support:
Obsidian vault access
shared cache database
Obsidian Tasks plugin configuration file at:
<vault>/.obsidian/plugins/obsidian-tasks-plugin/data.jsonHow it works:
note content is indexed in
file_cachetask parsing reuses that content instead of rescanning the vault from scratch
parsed tasks are stored in
task_file_cachelist_all_tasksandquery_tasksreuse that persisted layer
This gives you one MCP surface, one runtime, and one durable local data path.
Required and useful Obsidian plugins
Required depending on the MCP surfaces you use:
Local REST API: Obsidian API used by MCP.
Bases Bridge (REST):
.basesupport via REST.Smart Connections: vector index and
.smart-envfor semantic search.
Semantic search (Smart Connections)
Tool: smart_semantic_search (aliases: smart_search, smart-search).
Example:
{ "query": "publication X threads", "top_k": 10, "with_snippets": false }The server:
reads
.smart-env/multi/*.ajsonselects the dominant dimension
embeds the query with the same model as the vault
persists a semantic manifest in SQLite for faster warm refreshes
prewarms semantic search on startup by loading the snapshot and warming the query embedder
returns
timings_ms,vector_count, andfiltered_countfor operational diagnosis
Important:
semantic query execution still requires a reachable query embedder provider
if the vault was built with Ollama embeddings, an unreachable Ollama instance will produce a clear error instead of a silent hang
set
SEMANTIC_SEARCH_PREWARM=falseto disable startup prewarm
That means:
the semantic metadata path is now durable and observable
the final query still depends on a live embedding provider at request time
Providers (optional override)
Ollama (local)
export QUERY_EMBEDDER=ollama
export QUERY_EMBEDDER_MODEL=snowflake-arctic-embed2
export OLLAMA_BASE_URL=http://127.0.0.1:11434Xenova / Transformers
The local Xenova provider is disabled for now because its ONNX/protobuf dependency chain was affected by npm audit vulnerabilities. Use Ollama locally, or OpenAI in cloud mode.
OpenAI (cloud)
export QUERY_EMBEDDER=openai
export QUERY_EMBEDDER_MODEL=text-embedding-3-small
export OPENAI_API_KEY=...
# export OPENAI_EMBEDDING_DIMENSIONS=1024MCP sharing: portability
For shared MCP setups, avoid hard‑coding OLLAMA_BASE_URL inside the vault.
Keep auto mode and let each user override via env vars.
Legacy Tasks Repo
optimike-obsidian-tasks-mcp can still exist as a legacy standalone repo, but Codex no longer needs it when using this main server. The main MCP is now the canonical surface.
More Documentation
Product overview and install: this README
Runtime and maintenance guide: OPERATIONS.md
Mode-by-mode capability matrix: docs/runtime-capability-matrix.md
Dedicated headless server profile: docs/headless-server-profile.md
Agent routing guide: docs/mcp-routing-guide.md
Current tool surface: docs/obsidian_mcp_tools_spec.md
French README: README.fr.md
Credits
Created by Optimike (Mickaël Ahouansou)
License
See LICENSE.
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/optimikelabs/optimike-obsidian-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server