Skip to main content
Glama
markdown-vault-mcp

markdown-vault-mcp

by pvliesdonk

Search Vault

search
Read-onlyIdempotent

Find notes by keyword or meaning and return ranked results with best-matching snippets, so you can quickly identify relevant vault content.

Instructions

Search notes by keyword and meaning; returns notes ranked by score, each with its best-matching sections as snippets.

Use list_documents for a complete listing and read for a path you already know.

Input Schema

NameRequiredDescriptionDefault
modeNoOmit for the best mode this vault serves. `"keyword"` suits exact terms, operators and filenames; `"semantic"` matches meaning only; `"hybrid"` combines both. `"semantic"` and `"hybrid"` need semantic_search_available from stats.
limitNoMaximum notes to return (default 10).
queryYesWords to match or a natural-language question.
folderNoOnly notes under this folder, a value from list_folders; `""` for top-level notes only.
filtersNoFrontmatter values to match, all of them, such as `{"tags": "pacing"}`; keys come from indexed_frontmatter_fields in stats, and a list field matches when it holds the value. On an OKF bundle, status (draft, stable or deprecated; stable includes notes with none), stale (`"true"` or `"false"`) and trust_tier (unverified, machine-confirmed or human-reviewed) filter too.
snippet_wordsNoSnippet width in words; omit for the server default, 0 for whole sections. read with section set to a result's heading returns that whole section.
chunks_per_fileNoMaximum sections per note, at least 1; omit for the server default.
wait_for_pending_writesNoWait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changedv6.1.0
    • changedInput schema / properties / chunks_per_file / description
      Previous value: -"Maximum number of sections to return per file\n(default 2).  Set to 1 to get only the top-ranked section\nper file.  Must be >= 1."New value: +"Maximum sections per note, at least 1; omit for the server\ndefault."
    • changedInput schema / properties / filters / description
      Previous value: -"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list. On an OKF\nbundle three keys carry OKF semantics: status (\"draft\"/\n\"stable\"/\"deprecated\"; \"stable\" also matches notes without\na status field), stale (\"true\"/\"false\" — stale_after\nreached), and trust_tier (\"unverified\"/\"machine-confirmed\"/\n\"human-reviewed\"); \"type\" filters normally, e.g.\n{\"type\": \"Playbook\", \"stale\": \"false\"}."New value: +"Frontmatter values to match, all of them, such as `{\"tags\": \"pacing\"}`;\nkeys come from indexed_frontmatter_fields in stats, and a list field\nmatches when it holds the value. On an OKF bundle, status (draft, stable\nor deprecated; stable includes notes with none), stale (`\"true\"` or\n`\"false\"`) and trust_tier (unverified, machine-confirmed or\nhuman-reviewed) filter too."
    • changedInput schema / properties / folder / description
      Previous value: -"Restrict to documents under this folder path (e.g.\n\"Journal\"). Must match a value from 'list_folders'.\nUse folder=\"\" for root-level (top-level) documents only."New value: +"Only notes under this folder, a value from list_folders; `\"\"` for\ntop-level notes only."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum results to return (default 10)."New value: +"Maximum notes to return (default 10)."
    • changedInput schema / properties / mode / description
      Previous value: -"\"keyword\" uses FTS5/BM25 for exact terms. \"semantic\" uses\nvector similarity (requires embeddings). \"hybrid\" fuses both\nvia reciprocal rank fusion — best quality when available.\nOmit it (the default) to follow the vault's configured\nDEFAULT_SEARCH_MODE, which ships as \"auto\": hybrid where\nembeddings exist, keyword otherwise. Any configured default\ndegrades to \"keyword\" when it needs embeddings the vault\nlacks; an explicit \"semantic\"/\"hybrid\" still errors when\nunconfigured."New value: +"Omit for the best mode this vault serves. `\"keyword\"` suits exact terms,\noperators and filenames; `\"semantic\"` matches meaning only; `\"hybrid\"`\ncombines both. `\"semantic\"` and `\"hybrid\"` need semantic_search_available\nfrom stats."
    • changedInput schema / properties / query / description
      Previous value: -"Natural language or keyword query string."New value: +"Words to match or a natural-language question."
    • changedInput schema / properties / snippet_words / description
      Previous value: -"Width of the snippet window in words. Omit to use\nthe server default. Set to 0 to return full chunk content.\nUse read(path, section=heading) for full section recovery."New value: +"Snippet width in words; omit for the server default, 0 for\nwhole sections. read with section set to a result's heading returns that\nwhole section."
  2. Changed2 schema fields changedv5.0.0
    • changedInput schema / properties / filters / description
      Previous value: -"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list. On an OKF\nbundle three keys carry OKF semantics: status (\"draft\"/\n\"stable\"/\"deprecated\"; \"stable\" also matches notes without\na status field), stale (\"true\"/\"false\" — stale_after\npassed), and trust_tier (\"unverified\"/\"machine-confirmed\"/\n\"human-reviewed\"); \"type\" filters normally, e.g.\n{\"type\": \"Playbook\", \"stale\": \"false\"}."New value: +"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list. On an OKF\nbundle three keys carry OKF semantics: status (\"draft\"/\n\"stable\"/\"deprecated\"; \"stable\" also matches notes without\na status field), stale (\"true\"/\"false\" — stale_after\nreached), and trust_tier (\"unverified\"/\"machine-confirmed\"/\n\"human-reviewed\"); \"type\" filters normally, e.g.\n{\"type\": \"Playbook\", \"stale\": \"false\"}."
    • changedInput schema / properties / wait_for_pending_writes / description
      Previous value: -"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
  3. Changed5 schema fields changedv4.1.0
    • addedInput schema / properties / mode / anyOf
      Added value: +[
      +  {
      +    "enum": [
      +      "keyword",
      +      "semantic",
      +      "hybrid"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / mode / default
      Previous value: -"keyword"New value: +null
    • changedInput schema / properties / mode / description
      Previous value: -"\"keyword\" uses FTS5/BM25 for exact terms. \"semantic\" uses\nvector similarity (requires embeddings). \"hybrid\" fuses both\nvia reciprocal rank fusion — best quality when available."New value: +"\"keyword\" uses FTS5/BM25 for exact terms. \"semantic\" uses\nvector similarity (requires embeddings). \"hybrid\" fuses both\nvia reciprocal rank fusion — best quality when available.\nOmit it (the default) to follow the vault's configured\nDEFAULT_SEARCH_MODE, which ships as \"auto\": hybrid where\nembeddings exist, keyword otherwise. Any configured default\ndegrades to \"keyword\" when it needs embeddings the vault\nlacks; an explicit \"semantic\"/\"hybrid\" still errors when\nunconfigured."
    • removedInput schema / properties / mode / enum
      Removed value: -[
      -  "keyword",
      -  "semantic",
      -  "hybrid"
      -]
    • removedInput schema / properties / mode / type
      Removed value: -"string"
  4. Changed2 schema fields changedv4.0.0
    • changedInput schema / properties / filters / description
      Previous value: -"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list."New value: +"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list. On an OKF\nbundle three keys carry OKF semantics: status (\"draft\"/\n\"stable\"/\"deprecated\"; \"stable\" also matches notes without\na status field), stale (\"true\"/\"false\" — stale_after\npassed), and trust_tier (\"unverified\"/\"machine-confirmed\"/\n\"human-reviewed\"); \"type\" filters normally, e.g.\n{\"type\": \"Playbook\", \"stale\": \"false\"}."
    • changedInput schema / properties / wait_for_pending_writes / description
      Previous value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
  5. First observedv3.1.0

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is fully covered structurally. The description adds the ranking/snippet return behavior, but that is also carried by the output schema, and it does not mention latency, index-staleness behavior, or result caps beyond what the schema states.

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

Conciseness5/5

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

Two sentences with zero filler; the capability and return shape are front-loaded and the sibling routing is compressed into one clause. Nothing could be removed without losing routing information.

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

Completeness4/5

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

With 8 parameters, full schema coverage, an output schema, and rich annotations, the description only needs to establish purpose and routing, which it does. The minor gap is that it does not point to stats or embeddings_status for the semantic-mode prerequisite, though the schema does.

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

Parameters3/5

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

Schema description coverage is 100%, so every parameter including mode, folder, filters, snippet_words and wait_for_pending_writes is already documented in detail in the schema. The description adds no parameter-level meaning beyond the input schema, which is the expected baseline-3 case.

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 notes by keyword and meaning') plus the return shape (notes ranked by score with best-matching sections as snippets). The second sentence names two siblings it is not, so an agent can distinguish it from list_documents and read without consulting schemas.

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

Usage Guidelines4/5

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

Explicitly routes two alternatives: list_documents for a complete listing and read for a path already known, giving the condition that selects each. No exclusion guidance is offered against other retrieval siblings such as search_paths, query_documents, get_similar, or aggregate_documents, which leaves some ambiguity in a 50-tool namespace.

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