loading…
Search for a command to run...
loading…
MCP server for Obsidian that exposes tools for reading/writing notes, managing frontmatter and tags, querying Tasks, semantic search, and interacting with Obsid
MCP server for Obsidian that exposes tools for reading/writing notes, managing frontmatter and tags, querying Tasks, semantic search, and interacting with Obsidian Bases, with shared local caching and support for various runtime modes.
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.
npm install
npm run build
node dist/stdio-proxy.js
Recommended for Codex: point your MCP config to dist/stdio-proxy.js, not directly to dist/index.js.
live mode. Headless modes only require a local vault path..base tools, bundled in this repo).smart-env folderFrom source:
git clone https://github.com/optimikelabs/optimike-obsidian-mcp.git
cd optimike-obsidian-mcp
npm install
npm run build
Run the recommended local MCP entrypoint:
node dist/stdio-proxy.js
.smart-env)Optimike Obsidian MCP gives agents a structured way to work with an Obsidian vault:
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.
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.
list_all_tasks and query_taskssmart_semantic_searchobsidian_runtime_status and obsidian_runtime_maintenanceobsidian_read_note and obsidian_list_notes when Obsidian REST is downThe 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.
Obsidian has no native API for Bases (.base).
The Bases Bridge (REST) plugin fills the gap by adding dedicated REST endpoints.
Official prefix (recommended):
GET /extensions/obsidian-bases-bridge/basesGET /extensions/obsidian-bases-bridge/bases/:id/schemaPOST /extensions/obsidian-bases-bridge/bases/:id/queryPOST /extensions/obsidian-bases-bridge/bases/:id/upsertPOST /extensions/obsidian-bases-bridge/bases.base file.GET /extensions/obsidian-bases-bridge/bases/:id/configPUT /extensions/obsidian-bases-bridge/bases/:id/configLegacy aliases (MCP compat):
GET /basesGET /bases/:id/schemaPOST /bases/:id/queryPOST /bases/:id/upsertPOST /basesGET /bases/:id/configPUT /bases/:id/configWhen evaluate: true, the bridge returns:
source: "engine": auto‑cache + formula evaluation (no Bridge view)source: "fallback": partial on‑disk evaluation if engine is OFFThis 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 .basebases_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.
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 workThe 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.sqlite
The same database also stores:
file_cache for note contenttask_file_cache for parsed Tasks datasemantic_manifest and semantic_vectors for semantic metadataIf 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-filesystem to choose the runtime contractOBSIDIAN_SHARED_CACHE_DB_PATH to move the shared SQLite fileOBSIDIAN_CONTENT_HOT_CACHE_LIMIT to tune the bounded in-memory hot setOBSIDIAN_CACHE_SOURCE=auto|filesystem|rest to choose cache refresh source (auto prefers the local vault path when available)OBSIDIAN_CACHE_CONCURRENCY to bound local filesystem refresh workOBSIDIAN_VAULT_EXCLUDE_PATTERNS to add comma- or newline-separated gitignore-style exclusions on top of the built-in vault safety policyMCP_WRITE_MODE=readonly|guarded|full to enforce server-side write safety (full is the default; set guarded or readonly explicitly to harden a host)MCP_GUARDED_MAX_WRITE_CHARS and MCP_GUARDED_MAX_BATCH_OPERATIONS to tune guarded-mode limitsFor 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:
.obsidian, .trash, .git, .tmp, tmp, node_modules, screenshots folders, build/cache folders, SQLite/DB files, and log files.OBSIDIAN_VAULT_EXCLUDE_PATTERNS lets an operator add project-specific exclusions, for example tmp/**,**/tmp/**,Efforts/Archives/**.npm run check:vault-exclusions -- --vault=/path/to/vault prints 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.
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 when OBSIDIAN_API_KEY is configured. The API startup check is non-blocking. If no API key is configured, OBSIDIAN_VAULT is required.headless-readonly: no Obsidian Desktop, no Local REST API, no OBSIDIAN_API_KEY. Requires OBSIDIAN_VAULT; set OBSIDIAN_CACHE_SOURCE=filesystem for an explicit server profile. Exposes read/list/search/tasks/semantic/runtime tools plus local readonly bases_list, bases_get_schema, and bases_query.headless-guarded: no Obsidian Desktop; exposes the headless read surface plus guarded filesystem writes for obsidian_update_note, obsidian_search_replace, and obsidian_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; exposes headless-guarded plus bounded filesystem features: frontmatter/inline tags, local tag index/audit and dry-run rename, admin move/archive/delete operations with expectedHash or expectedMtime, batch frontmatter with dry-run, .base YAML create/config, Bases rows as Markdown frontmatter set operations, 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-run
npm 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_format is available in every runtime mode..base YAML, and JSON Canvas structure before writes.Local Bases fallback:
bases_list, bases_get_schema, and bases_query are available in headless modes with source: "local-fallback"..base YAML from OBSIDIAN_VAULT and cached Markdown frontmatter from the shared cache.contains, in, comparisons, simple sorting, pagination, and schema inspection.Useful scripts:
npm run build
npm run start:proxy
npm run start:http
Health endpoint when running the backend directly:
curl http://127.0.0.1:3010/healthz
Extended health / maintenance:
GET /healthz?integrity=1 adds a SQLite integrity checkobsidian_runtime_status returns process, cache, semantic, and degraded-mode statusobsidian_runtime_maintenance supports:integrity_checkrun_maintenancerefresh_vault_cacherefresh_semantic_cacherefresh_tasks_cacherefresh_allRuntime write safety:
readonly blocks all write tools except validation-only operationsguarded allows bounded explicit writes and blocks destructive operations such as delete, overwrite, frontmatter unset, broad regex replace-all, and large batchesfull is the default and keeps unrestricted write behavior for trusted local environmentsGuarded 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_notes supports responseMode="compact", limit, and cursorobsidian_global_search supports responseMode="compact" while keeping existing page/pageSize paginationlist_all_tasks and query_tasks support responseMode="compact"|"detailed", responseLimit, and cursorobsidian_read_noteTypical checks:
curl http://127.0.0.1:3010/healthz
curl http://127.0.0.1:3010/healthz?integrity=1
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:
~/.codex/config.toml (do not commit personal machine paths)./path/to/...) and keep real paths only in local config.dist/index.js is still the backend entrypoint, but Codex should point to dist/stdio-proxy.js.Local REST API plugin repo: https://github.com/coddingtonbear/obsidian-local-rest-api
In Obsidian:
OBSIDIAN_BASE_URL and OBSIDIAN_API_KEY in your MCP envExample:
export OBSIDIAN_BASE_URL=http://127.0.0.1:27123
export OBSIDIAN_API_KEY=<your_api_key>
OBSIDIAN_API_KEY private and local.OBSIDIAN_API_KEY and OPENAI_API_KEY in environment variables, not committed config files.npm audit reports 0 known vulnerabilities, and
npm audit signatures verifies registry signatures for the installed npm
dependency tree.MCP_AUTH_MODE=jwt
or MCP_AUTH_MODE=oauth, use a strong secret/provider, and keep
MCP_ALLOWED_ORIGINS narrow. The default stdio / 127.0.0.1 profile is the
safer local setup.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.1 from WSL points to WSL, not WindowsOBSIDIAN_BASE_URLExample:
GW=$(ip route | awk '/default/ {print $3; exit}')
export OBSIDIAN_BASE_URL=http://$GW:27123
If you use a Windows portproxy, adapt the port accordingly.
The main MCP now includes:
list_all_tasks, query_taskssmart_semantic_search, smart_search, smart-searchobsidian_runtime_status, obsidian_runtime_maintenanceThe main MCP now owns the Tasks surface directly.
What this means:
optimike-obsidian-tasks-mcp entry anymorelist_all_tasks and query_tasks are exposed by this main servertask_file_cache inside the shared SQLite databaseDependencies for Tasks support:
<vault>/.obsidian/plugins/obsidian-tasks-plugin/data.json
How it works:
file_cachetask_file_cachelist_all_tasks and query_tasks reuse that persisted layerThis gives you one MCP surface, one runtime, and one durable local data path.
Required depending on the MCP surfaces you use:
.base support via REST..smart-env for semantic search.Tool: smart_semantic_search (aliases: smart_search, smart-search).
Example:
{ "query": "publication X threads", "top_k": 10, "with_snippets": false }
The server:
.smart-env/multi/*.ajsontimings_ms, vector_count, and filtered_count for operational diagnosisImportant:
SEMANTIC_SEARCH_PREWARM=false to disable startup prewarmThat means:
Ollama (local)
export QUERY_EMBEDDER=ollama
export QUERY_EMBEDDER_MODEL=snowflake-arctic-embed2
export OLLAMA_BASE_URL=http://127.0.0.1:11434
Xenova / 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=1024
For shared MCP setups, avoid hard‑coding OLLAMA_BASE_URL inside the vault.
Keep auto mode and let each user override via env vars.
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.
See LICENSE.
Выполни в терминале:
claude mcp add optimike-obsidian-mcp -- npx Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.