Construe MCP Server for Obsidian Vault Context Management
Streamline Obsidian vault context with an MCP server offering frontmatter filtering, automatic chunking, and secure bidirectional knowledge operations.
npx -y @mattjoyce/mcp-construeOverview
Construe MCP Server is a small FastMCP-compatible server that exposes curated content from an Obsidian vault to LLM-driven tools. It loads notes by parsing YAML frontmatter and tags, lets you search and paginate large result sets, and supports controlled read/write operations back to the vault so agents can both consume and update knowledge safely.
This server is useful when you want your assistant to use a focused subset of a personal knowledge base (for example: personal notes, project docs, or research snippets) without exposing unrelated files. Built-in frontmatter filtering and file protection rules let you whitelist which files the server may create or overwrite; automatic chunking keeps responses within typical model context limits.
Features
- Bidirectional knowledge operations: read notes and (optionally) write new/updated files into the vault.
- Frontmatter-based filtering: query by YAML properties and tags using AND / OR semantics.
- Smart chunking: automatically splits large result sets into chunks (default max 95,000 characters) — files are never split across chunks.
- File protection policy: configurable frontmatter key + allowed values to prevent unauthorized writes or overwrites.
- Proper YAML frontmatter handling: generates and parses frontmatter reliably when creating files.
- Simple FastMCP API surface for integration with LLM orchestration tools.
Installation / Configuration
Prerequisites: Python 3.8+.
Install, configure, and run:
# or: pip install fastmcp pyyaml pathlib
Create a config.yaml in the same directory (expand ~ for home directory):
vault_path: "/path/to/obsidian/vault"
default_context:
properties:
context: "personal"
tags:
# Protection: which frontmatter property and allowed values gate file writes
protection_property: "author"
protection_value: # can be a single string or a list
Command-line options:
Available Tools
The server exposes helper functions (used internally by the MCP endpoints) to operate on vault content. Example names and purposes:
- fetch_context(context_type, chunk_index=0, max_chars=95000)
- Load files whose frontmatter
contextequalscontext_type. Returns a chunk of complete files.
- Load files whose frontmatter
- fetch_matching_files(properties, tags, match_all_tags=False, chunk_index=0, max_chars=95000)
- Flexible search: match frontmatter properties and tags. match_all_tags controls AND (True) vs OR (False) tag logic.
- fetch_frontmatter_index(properties, tags, match_all_tags=False, chunk_index=0, max_chars=95000)
- Return metadata (frontmatter index) instead of full file bodies; useful for browsing.
- list_context_chunks(context_type, max_chars=95000)
- List chunk descriptors (how many chunks are available) for a given context.
- list_matching_chunks(properties, tags, match_all_tags=False, max_chars=95000)
- List chunks for an arbitrary filter.
- fetch_context_chunk(context_type, chunk_index, max_chars=95000)
- Retrieve a specific chunk by index.
- fetch_matching_chunk(chunk_index, properties, tags, match_all_tags=False, max_chars=95000)
- Retrieve a specific chunk for a custom filter.
- create_file(filename, content, properties, tags, subfolder=“”, overwrite=False)
- Create or overwrite a Markdown file with generated YAML frontmatter. Subject to protection rules.
Default max_chars is 95,000 characters (configurable per call). Chunking ensures each returned chunk contains only whole files, never partial files.
Protection Rules (File Write Security)
The server enforces a file protection policy before creating or overwriting files:
- New files must include the configured protection property with one of the allowed values.
- Overwriting an existing file is allowed only if the existing file already has the protection property set to an allowed value.
- The protection_property is configurable (e.g.,
author,owner,context) and allowed values may be a string or list.
Table: example scenarios
| Scenario | Existing file present | File frontmatter | Allowed? |
|---|---|---|---|
| Create new with required property | No | author: claude | ✅ |
| Create new missing property | No | (none) | ❌ |
| Overwrite existing with required author | Yes | existing has author: claude | ✅ |
| Overwrite existing wrong author | Yes | existing has author: human | ❌ |
Use Cases
Contextual assistant that only reads “personal” notes:
- Configure
default_context.properties.context: personal. - Use fetch_context(“personal”) to return notes scoped to that context; large results are chunked so you can iterate.
- Configure
Agent that writes summaries back to a vault, but only into files owned by the assistant:
- Set
protection_property: "author"andprotection_value: ["assistant"]. - create_file(“summary.md”, content, properties={“author”:“assistant”}) will succeed.
- Attempts to create or overwrite files without the allowed author value are blocked.
- Set
Browsing metadata before retrieving full notes:
- Use fetch_frontmatter_index(…) to page through file metadata and decide which chunk(s) to fetch with fetch_matching_chunk(…).
Example snippet (Python-style pseudo-usage):
# fetch first chunk of "research" context
=
# list available chunks for custom filter
=
# create a new file (subject to protection rules)
Examples of Frontmatter
Files should use standard YAML frontmatter to be discoverable:
Notes
- The server never splits individual files across chunks; chunk boundaries are determined by cumulative character count.
- Adjust max_chars if you target smaller or larger model context windows.
- For full source, issues, and contributions see the repository: https://github.com/mattjoyce/mcp-construe