Skip to main content
Glama
Obsidian MCP (pgvector + Ollama, self-hosted)

Obsidian MCP (pgvector + Ollama, self-hosted)

by maxkuminov

Related notes

find_related
Read-onlyIdempotent

Retrieve semantically similar notes by comparing a source note's chunk embeddings in pgvector, independent of the wikilink graph—useful when a note is sparsely linked or you need thematic neighbors.

Instructions

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 get_neighborhood. For arbitrary topic queries use semantic_search.

Carries semantic_search's per-row markers and its header counts: stale: true means that neighbour changed after it was embedded, so it was ranked against its previous content and its preview is withheld — read_note returns the current text. embedding_truncated: true means only that note's head was embedded, so a match against it says nothing about its tail.

One marker is about the source rather than a neighbour. If the note you asked about has itself changed since it was embedded, the result says so once, at the top — and it says so on the empty result too. The query vector is the average of the source's stored chunk vectors, so a stale source means every neighbour answers a question about content that note no longer has, and "no related notes" from a stale source means "nothing is near what this note used to say", not "this note has no neighbours". The next embed pass repairs it. A source with no vectors at all is a different message ("has not been embedded yet") with a different fix.

The bound on the staleness signal: it reports what the index has committed, so an edit the indexer has not yet scanned is not marked.

Section locator. A fresh row names the section it matched on its result line: § "<heading path>" (#N) for a heading's section, or § (top of note) for text before the first heading. read_note(path, section="#N") reads exactly that section. The quoted path is note text; the (#N) after it is the server's. The locator is omitted on stale rows and on rows not yet re-embedded since heading-aware chunking. While any of your notes is not yet re-chunked, the line after the header reads index_transition: N notes not yet re-chunked; …: ranking across the two generations is approximate, so re-run once it is gone. Previews are one line.

Args: path: Vault-relative path to the source note. limit: Maximum results (default 10, hard cap 50).

Input Schema

NameRequiredDescriptionDefault
pathYes
limitNo

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.8.2
    • addedInput schema / additionalProperties
      Added value: +false
  2. Addedv0.7.0
  3. Removedv0.5.4
  4. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already establish this as a safe, idempotent read-only operation, but the description adds substantial behavioral context beyond them. It explains stale-neighbor handling, withheld previews, truncated embeddings, source-level staleness including the empty-result case, the staleness signal's indexing bound, section locators, omitted locators, and index-transition messaging. These are exactly the non-obvious behaviors an agent needs before interpreting results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose, usage alternatives, and the most important caveats, and its paragraphs are organized around distinct concepts. It is quite long, but most detail is behaviorally relevant for interpreting semantic-neighbor results. Some repetition around source staleness and marker semantics could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the presence of an output schema, and the subtle staleness/index-transition behaviors, the description is complete enough for correct invocation and result interpretation. It covers the operation, alternatives, parameters, marker semantics, source-side caveats, and section-locator behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for both parameters. It documents `path` as a vault-relative path to the source note and `limit` as the maximum result count with default 10 and a hard cap of 50. This is sufficient for the two-parameter tool, though `path` semantics remain fairly brief.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific operation: find semantically similar notes using the source note's chunk embeddings averaged and queried via pgvector. It explicitly distinguishes this from link-graph exploration and from arbitrary topic search, naming `get_neighborhood` and `semantic_search` as alternatives. An agent can tell exactly what this tool does and when it is different from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit conditions for use: when the source is sparsely linked or when looking for thematic neighbors. It also names the alternatives and their distinct use cases: `get_neighborhood` for link-based exploration and `semantic_search` for arbitrary topic queries. This is close to ideal routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.