Enables querying Markdown frontmatter data using DuckDB SQL, including support for complex queries with type casting, JSON array operations, and semantic search with vector embeddings.
Provides tools for querying, updating, and managing frontmatter metadata in Markdown files, including batch operations for properties and array manipulation across multiple files.
Supports querying and updating frontmatter in Obsidian vaults with graceful handling of Templater expressions, enabling automated metadata management across Obsidian notes.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Frontmatter MCPfind all markdown files with 'project' tag from this year"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
frontmatter-mcp
An MCP server for querying Markdown frontmatter with DuckDB SQL.
Configuration
Basic Usage
With Semantic Search
Semantic search requires large dependencies (~1GB). Set MCP_TIMEOUT to extend installation timeout:
Note: MCP_TIMEOUT is in milliseconds (300000 = 5 minutes).
Installation (Optional)
If you prefer to install globally:
Tools
query_inspect
Get schema information from frontmatter across files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
Example:
query
Query frontmatter data with DuckDB SQL.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| string | DuckDB SQL query referencing |
Example:
update
Update frontmatter properties in a single file.
Parameter | Type | Description |
| string | File path relative to base directory |
| object | Properties to add or overwrite |
| string[] | Property names to remove |
Example:
batch_update
Update frontmatter properties in multiple files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| object | Properties to add or overwrite |
| string[] | Property names to remove |
Example:
batch_array_add
Add a value to an array property in multiple files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| string | Name of the array property |
| any | Value to add |
| bool | Allow duplicate values (default: false) |
Example:
batch_array_remove
Remove a value from an array property in multiple files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| string | Name of the array property |
| any | Value to remove |
Example:
batch_array_replace
Replace a value in an array property in multiple files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| string | Name of the array property |
| any | Value to replace |
| any | New value |
Example:
batch_array_sort
Sort an array property in multiple files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| string | Name of the array property |
| bool | Sort in descending order (default: false) |
Example:
batch_array_unique
Remove duplicate values from an array property in multiple files.
Parameter | Type | Description |
| string | Glob pattern relative to base directory |
| string | Name of the array property |
Example:
index_status
Get the status of the semantic search index.
This tool is only available when FRONTMATTER_ENABLE_SEMANTIC=true.
Example:
index_refresh
Refresh the semantic search index (differential update).
This tool is only available when FRONTMATTER_ENABLE_SEMANTIC=true.
Example:
Technical Notes
All Values Are Strings
All frontmatter values are passed to DuckDB as strings. Use TRY_CAST in SQL for type conversion when needed.
Arrays Are JSON Strings
Arrays like tags: [ai, python] are stored as JSON strings '["ai", "python"]'. Use from_json() and UNNEST to expand them.
Templater Expression Support
Files containing Obsidian Templater expressions (e.g., <% tp.date.now("YYYY-MM-DD") %>) are handled gracefully. These expressions are treated as strings and naturally excluded by date filtering.
Semantic Search
When semantic search is enabled, you can use the embed() function and embedding column in SQL queries. After running index_refresh, the markdown body content is indexed as vectors.
Environment variables:
Variable | Default | Description |
FRONTMATTER_BASE_DIR | (required) | Base directory for files |
FRONTMATTER_ENABLE_SEMANTIC | false | Enable semantic search |
FRONTMATTER_EMBEDDING_MODEL | cl-nagoya/ruri-v3-30m | Embedding model name |
FRONTMATTER_CACHE_DIR | FRONTMATTER_BASE_DIR/.frontmatter-mcp | Cache directory for embeddings |
License
MIT