Obsidian MCP (pgvector + Ollama, self-hosted)
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CHUNK_SIZE | No | Approximate tokens per chunk (4-char heuristic) | 512 |
| OLLAMA_URL | No | Ollama server URL (required when provider is ollama) | |
| SECRET_KEY | Yes | Secret key for itsdangerous signer | |
| VAULT_PATH | Yes | In-container path to the Obsidian vault (default: /obsidian) | |
| DATABASE_URL | Yes | PostgreSQL connection string (e.g., postgresql+asyncpg://user:pass@host/db) | |
| CHUNK_OVERLAP | No | Token overlap between chunks | 0 |
| OPENAI_API_KEY | No | OpenAI API key (required when provider is openai) | |
| EMBEDDING_MODEL | No | Ollama model name (used when provider is ollama) | bge-m3 |
| MULTI_USER_MODE | No | Enable multi-user mode (requires SECRET_KEY) | false |
| OPENAI_BASE_URL | No | Base URL for OpenAI-compatible API | https://api.openai.com/v1 |
| MCP_SANDBOX_MODE | No | Registry-eval only. Skips DB, indexer, embedding provider, and /mcp auth so introspection works without external deps. Do not enable in production. | false |
| EMBEDDING_PROVIDER | No | Embedding provider: 'ollama' or 'openai' | ollama |
| EMBEDDING_DIMENSIONS | No | pgvector column width (must match model output) | 1024 |
| INDEX_INTERVAL_SECONDS | No | Periodic reindex cadence in seconds | 300 |
| OPENAI_EMBEDDING_MODEL | No | OpenAI embedding model name | text-embedding-3-small |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| keyword_searchA | Full-text keyword search via PostgreSQL tsvector. Use this for exact identifiers, code symbols, proper nouns, or known phrases — anywhere semantic noise hurts. For conceptual or paraphrased queries, use semantic_search instead. Args: query: Keywords or phrase to match (websearch tsquery syntax: "foo bar", "foo OR bar", "-bar"). folder: Optional folder prefix (e.g. "Cards/", "Projects/"). limit: Maximum number of results (default 20). tags: Optional list of tag names; only notes carrying ALL listed tags match (e.g. ["project", "active"]). frontmatter: Optional dict of frontmatter key/value pairs; only notes whose JSONB frontmatter contains every pair match. Strict type matching — string "0" does not match integer 0 (e.g. {"status": "draft"}). |
| read_noteA | Read a note from the Obsidian vault by its relative path. Args: path: Vault-relative path to the note (e.g. "Cards/My Note.md") |
| list_notesA | List notes in a vault folder, sorted by most recently modified. Results come from the index, so a note that exists on disk but has not yet been picked up by the indexer will not appear (lag is bounded by the index interval, typically up to 5 minutes). Args: folder: Vault-relative folder path (e.g. "Cards/", "Projects/"). Empty for vault root. limit: Maximum number of results (default 50). tags: Optional list of tag names; only notes carrying ALL listed tags match (e.g. ["idea"]). frontmatter: Optional dict of frontmatter key/value pairs; strict type match (e.g. {"status": "active"}). |
| get_tagsB | List all tags used across the vault with note counts. Args: limit: Maximum number of tags to return (default 50) |
| get_recentA | Get recently modified notes. Args: limit: Number of recent notes to return (default 20). folder: Optional folder prefix to filter (e.g. "Projects/"). tags: Optional list of tag names; only notes carrying ALL listed tags match (e.g. ["meeting"]). frontmatter: Optional dict of frontmatter key/value pairs; strict type match (e.g. {"status": "active"}). |
| semantic_searchA | Vector similarity search using bge-m3 embeddings. Use this for conceptual or paraphrased queries — anywhere exact word matching would miss the point. For exact identifiers, code symbols, proper nouns, or known phrases, use keyword_search instead. Each result is one note (deduped) with its best-matching chunk as a ~500-char preview.
Call Args: query: Natural language description of what you're looking for. limit: Maximum number of distinct notes to return (default 15). folder: Optional folder prefix (e.g. "Projects/"). tags: Optional list of tag names; only notes carrying ALL listed tags match (e.g. ["product"]). frontmatter: Optional dict of frontmatter key/value pairs; strict type matching — string "0" does not match integer 0 (e.g. {"status": "active"}). |
| create_noteA | Create a new markdown note in the Obsidian vault. Requires a readwrite API key. See Args: path: Vault-relative path for the new note (e.g. "Cards/New Topic.md"). The .md extension is added if missing. content: Full markdown content for the note, including any frontmatter. |
| edit_noteA | Edit an existing note in the Obsidian vault. Requires a readwrite API key. See Four mutually exclusive modes (set at most one of append/find/section):
Flags:
Writes are atomic (tmp file + os.replace) so a crash mid-write cannot truncate
the destination. Frontmatter mutation is better done via Args:
path: Vault-relative path to the note.
content: New full content, replacement text, text to append, or section body.
append: If True, append content to the end of the note.
find: Exact text to find and replace.
section: ATX heading text identifying the section whose body to replace.
Use |
| get_vault_guideA | Returns a two-part guide for working with this Obsidian vault:
|
| get_backlinksA | Notes that link TO Resolved links only (dangling references are not counted as backlinks). Args: path: Vault-relative path to the target note (e.g. "Cards/Foo.md"). limit: Maximum results (default 50, hard cap 500). |
| get_linksA | Outgoing links from Useful for "what does this note depend on?" or finding broken references that need follow-up notes. Args: path: Vault-relative path to the source note. |
| get_neighborhoodA | The connected subgraph reachable from Use this when an agent needs the local cluster around a topic — e.g.
"summarize everything connected to this project". Prefer this over
Args: path: Vault-relative path to the seed note. depth: Maximum BFS depth (default 1, capped at 5). limit: Maximum distinct neighbor notes (default 50, hard cap 200). |
| find_relatedA | Semantically similar notes based on the source note's chunk embeddings, averaged then queried via pgvector. Independent of the link graph — useful when the source is sparsely linked
or when looking for thematic neighbors. For link-based exploration use
Args: path: Vault-relative path to the source note. limit: Maximum results (default 10, hard cap 50). |
| find_orphansA | Notes with zero incoming AND zero outgoing resolved links — useful for vault hygiene ("what's disconnected?") and cleanup decisions. Args: folder: Optional vault-relative folder prefix to scope the search (e.g. "Cards/"). limit: Maximum results (default 50, hard cap 500). |
| move_noteA | Move or rename a note inside the vault. Requires a readwrite API key. Updates With Writes are atomic. See Args: from_path: Vault-relative path of the existing note. to_path: Vault-relative path of the destination. Must not exist. Parent directories are created automatically. rewrite_links: If True, also rewrite incoming wikilinks and embeds in source notes. Off by default — opting in is destructive (it modifies other notes' bodies). |
| delete_noteA | Delete a note from the vault. Requires a readwrite API key. By default this is a soft-delete: the file is moved to
With Dangling backlinks left behind by a delete are surfaced via
Args: path: Vault-relative path to the note. permanent: If True, unlink instead of soft-deleting. |
| set_frontmatterA | Mutate a note's YAML frontmatter without touching its body. Requires a readwrite API key. Parses the existing frontmatter, merges in Re-serialization uses See Args: path: Vault-relative path to the note. updates: Mapping of keys to set. Use the empty dict (or omit) to skip. remove: List of keys to delete from the frontmatter. Missing keys are silently ignored. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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/maxkuminov/obsidian-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server