Skip to main content
Glama
aliasunder

Vault Cortex Obsidian MCP Server

Search Notes

vault_search
Read-onlyIdempotent

Find relevant vault notes by combining keyword and semantic search, then narrow results with metadata filters like folder, tags, type, dates, or properties.

Instructions

Hybrid search across all vault notes, ranked by combined keyword and semantic relevance using Reciprocal Rank Fusion (RRF) — combining FTS5 keyword matching with vector similarity. Results are refined by a cross-encoder reranker using position-aware score blending when available. Semantic matching finds notes even when exact keywords differ — "career aspirations" finds notes about "goals" and "targets". Falls back to keyword-only (FTS5 BM25) transparently while embeddings are being built. Combine a text query with structured filters to narrow results by metadata — the "narrow by metadata, search by text" pattern. Unquoted terms use implicit AND with porter stemming; wrap in double quotes for exact phrases; punctuated terms (vault-cortex, deploy/local) are matched as exact adjacent-word phrases automatically.

Filters — all conditions AND-combine with each other and the text query:

  • folder: path prefix (e.g. "Projects")

  • tags: require all listed tags (AND)

  • type: exact match on frontmatter type (e.g. "person", "session-log")

  • related: require all listed related links (AND)

  • properties: arbitrary frontmatter key-value pairs, supports string/number/boolean (e.g. { status: "active" })

  • created: date bounds { before, on, after } in YYYY-MM-DD on the frontmatter created property — before/after are exclusive, on is exact (calendar-day match, server-local). Notes without a parseable created property never match

  • modified: date bounds { before, on, after } in YYYY-MM-DD on filesystem modified time (server-local day boundaries) — before/after match strictly earlier/later days, on matches within the day

Example: vault_search({ query: "kubernetes networking", filters: { tags: ["reference"] } }) Example: vault_search({ query: "meeting notes", filters: { type: "meeting", folder: "Work" } }) Example: vault_search({ query: "decision", filters: { modified: { after: "2026-06-30" } } }) — matching notes touched in July or later Example: vault_search({ query: "how the server watches for file changes" }) — semantic: finds notes about chokidar and file watchers even without those exact terms

When to use: The primary discovery tool for content-based queries, optionally constrained by metadata. Semantic matching bridges vocabulary gaps — try natural-language queries, not just keywords. Prefer vault_search_by_tag for tag-only queries without text. Prefer vault_search_by_folder for browsing a folder. Prefer vault_search_by_property for metadata-only queries. Prefer vault_recent_notes for time-based browsing.

Errors:

  • No matches returns { results: [], total: 0 }, not an error

  • Malformed query syntax is sanitized automatically — the tool never throws a query syntax error

  • A malformed or calendar-invalid created/modified date filter throws with remediation text ("Use YYYY-MM-DD")

Returns: JSON with results array (path, title, snippet, score, tags, folder, type, kind, extension, created, modified, bytes), total count, search_mode ("hybrid" or "fts"), and reranked (boolean — true when cross-encoder reranking refined the ordering). search_mode indicates which ranking was used — "hybrid" when vector embeddings contributed, "fts" when only keyword matching was available. score reflects combined relevance (higher = more relevant). kind is "note" for markdown notes or "file" for non-markdown content (canvas, PDF, and text files — .txt, .csv, .json, .xml, .svg, .log, .yaml, .yml, .base); file results also carry extension (e.g. ".canvas", ".pdf", ".txt"). created is omitted when null. bytes is the on-disk file size. With include_leading_callout, each result also carries leading_callout ({ type, title, body }) when present.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoMax results (default 20)
queryYesSearch query text — unquoted terms use implicit AND with stemming; wrap in double quotes for exact phrases
filtersNoOptional structured filters — all conditions AND-combine with each other and with the text query
snippet_tokensNoSnippet length in tokens (default 30)
include_leading_calloutNoIf true, each result includes its leading_callout ({ type, title, body }) when present. Off by default to keep results lean.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.50.0
    • removedInput schema / properties / filters / properties / include_leading_callout
      Removed value: -{
      -  "description": "If true, each result includes its leading_callout ({ type, title, body }) when present. Off by default to keep results lean.",
      -  "type": "boolean"
      -}
    • removedInput schema / properties / filters / properties / limit
      Removed value: -{
      -  "description": "Max results (default 20)",
      -  "type": "number"
      -}
    • removedInput schema / properties / filters / properties / snippet_tokens
      Removed value: -{
      -  "description": "Snippet length in tokens (default 30)",
      -  "type": "number"
      -}
    • addedInput schema / properties / include_leading_callout
      Added value: +{
      +  "default": false,
      +  "description": "If true, each result includes its leading_callout ({ type, title, body }) when present. Off by default to keep results lean.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / limit
      Added value: +{
      +  "default": 20,
      +  "description": "Max results (default 20)",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / snippet_tokens
      Added value: +{
      +  "default": 30,
      +  "description": "Snippet length in tokens (default 30)",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
  2. Changed2 schema fields changedv0.27.2
    • addedInput schema / properties / filters / properties / created
      Added value: +{
      +  "description": "Created date bounds (YYYY-MM-DD) on the frontmatter \"created\" property — notes without a parseable value never match",
      +  "properties": {
      +    "after": {
      +      "description": "Exclusive lower bound (YYYY-MM-DD) — strictly later dates",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "before": {
      +      "description": "Exclusive upper bound (YYYY-MM-DD) — strictly earlier dates",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "on": {
      +      "description": "Exact date match (YYYY-MM-DD)",
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / filters / properties / modified
      Added value: +{
      +  "description": "Modified date bounds (YYYY-MM-DD) on filesystem modified time, server-local day boundaries",
      +  "properties": {
      +    "after": {
      +      "description": "Exclusive lower bound (YYYY-MM-DD) — strictly later dates",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "before": {
      +      "description": "Exclusive upper bound (YYYY-MM-DD) — strictly earlier dates",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "on": {
      +      "description": "Exact date match (YYYY-MM-DD)",
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  3. Changed7 schema fields changedv0.22.1
    • addedInput schema / properties / filters / properties / folder / minLength
      Added value: +1
    • changedInput schema / properties / filters / properties / properties / additionalProperties / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "boolean"
      -  }
      -]New value: +[
      +  {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "type": "boolean"
      +  }
      +]
    • addedInput schema / properties / filters / properties / properties / propertyNames / minLength
      Added value: +1
    • addedInput schema / properties / filters / properties / related / items / minLength
      Added value: +1
    • addedInput schema / properties / filters / properties / tags / items / minLength
      Added value: +1
    • addedInput schema / properties / filters / properties / type / minLength
      Added value: +1
    • addedInput schema / properties / query / minLength
      Added value: +1
  4. Changed7 schema fields changedv0.19.2
    • changedInput schema / properties / filters / description
      Previous value: -"Optional search filters"New value: +"Optional structured filters — all conditions AND-combine with each other and with the text query"
    • changedInput schema / properties / filters / properties / folder / description
      Previous value: -"Restrict to folder"New value: +"Restrict to a folder path prefix (e.g. \"Projects\")"
    • addedInput schema / properties / filters / properties / include_leading_callout
      Added value: +{
      +  "description": "If true, each result includes its leading_callout ({ type, title, body }) when present. Off by default to keep results lean.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / filters / properties / properties / description
      Previous value: -"Arbitrary property key-value filters"New value: +"Match arbitrary frontmatter properties by key-value (e.g. { status: \"active\", priority: 1 })"
    • changedInput schema / properties / filters / properties / tags / description
      Previous value: -"Require all listed tags"New value: +"Require all listed tags (AND — every tag must be present)"
    • changedInput schema / properties / filters / properties / type / description
      Previous value: -"Frontmatter type field value"New value: +"Match the frontmatter type field (exact match, e.g. \"person\", \"meeting\")"
    • changedInput schema / properties / query / description
      Previous value: -"Search query text"New value: +"Search query text — unquoted terms use implicit AND with stemming; wrap in double quotes for exact phrases"
  5. Added

TDQS

A4.8/5.0
Behavior5/5

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

Documents search_mode, ranking changes, fallback to FTS-only without embeddings, no result mutation (consistent with readOnlyHint), and exact match semantics per filter. Generous detail on post-processing and result shape, far beyond what annotations capture.

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?

Long but neatly structured with clear sections and purposeful detail — sorting, case-insensitivity, match semantics, and output shape. Slightly verbose in the example block, but every part is informative and it is front-loaded with usage guidance.

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?

Covers query syntax, filter multiplication, result shape, error behavior RRFRF, and common use cases. The description is exhaustive for an agent to confidently call this tool without further clarification.

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?

The input schema is very rich with per-field descriptions ablob; the tool adds the crucial semantic that filters are AND-combined and that tags/tags_exclude combine per field. Descriptions beyond schema (nested fields, sorting behavior) are helpful context an agent cannot infer from schema alone.

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?

States a specific verb and resource ('search all vault notes') with ranking semantics (semantic + FTS, reranking). Clearly distinguishes itself from tag/folder/date-only siblings by combining filters and text.

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?

Explicitly states it is the primary discovery tool which composes text and metadata. Includes when-not-to-use examples (a simple tag search is better served by vault_search_by_tag) and directs to alternatives for browsing/filtering. This is model-grade guidance.

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