MCP server for querying Markdown frontmatter with DuckDB SQL
Project description
frontmatter-mcp
An MCP server for querying Markdown frontmatter with DuckDB SQL.
Installation
uv tool install git+https://github.com/kzmshx/frontmatter-mcp.git
Configuration
{
"mcpServers": {
"frontmatter": {
"command": "frontmatter-mcp",
"args": ["--base-dir", "/path/to/markdown/directory"]
}
}
}
Tools
query_inspect
Get schema information from frontmatter across files.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
Example:
// Input
{ "glob": "**/*.md" }
// Output
{
"file_count": 186,
"schema": {
"date": { "type": "string", "count": 180, "nullable": true },
"tags": { "type": "array", "count": 150, "nullable": true }
}
}
query
Query frontmatter data with DuckDB SQL.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
sql |
string | DuckDB SQL query referencing files table |
Example:
// Input
{
"glob": "**/*.md",
"sql": "SELECT path, date FROM files WHERE date >= '2025-11-01' ORDER BY date DESC"
}
// Output
{
"columns": ["path", "date"],
"row_count": 24,
"results": [
{"path": "daily/2025-11-28.md", "date": "2025-11-28"},
{"path": "daily/2025-11-27.md", "date": "2025-11-27"}
]
}
update
Update frontmatter properties in a single file.
| Parameter | Type | Description |
|---|---|---|
path |
string | File path relative to base directory |
set |
object | Properties to add or overwrite |
unset |
string[] | Property names to remove |
Example:
// Input
{ "path": "notes/idea.md", "set": {"status": "published"} }
// Output
{ "path": "notes/idea.md", "frontmatter": {"title": "Idea", "status": "published"} }
batch_update
Update frontmatter properties in multiple files.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
set |
object | Properties to add or overwrite |
unset |
string[] | Property names to remove |
Example:
// Input
{ "glob": "drafts/*.md", "set": {"status": "review"} }
// Output
{ "updated_count": 5, "updated_files": ["drafts/a.md", "drafts/b.md", ...] }
batch_array_add
Add a value to an array property in multiple files.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
property |
string | Name of the array property |
value |
any | Value to add |
allow_duplicates |
bool | Allow duplicate values (default: false) |
Example:
// Input
{ "glob": "**/*.md", "property": "tags", "value": "reviewed" }
// Output
{ "updated_count": 42, "updated_files": ["a.md", "b.md", ...] }
batch_array_remove
Remove a value from an array property in multiple files.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
property |
string | Name of the array property |
value |
any | Value to remove |
Example:
// Input
{ "glob": "**/*.md", "property": "tags", "value": "draft" }
// Output
{ "updated_count": 15, "updated_files": ["a.md", "b.md", ...] }
batch_array_replace
Replace a value in an array property in multiple files.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
property |
string | Name of the array property |
old_value |
any | Value to replace |
new_value |
any | New value |
Example:
// Input
{ "glob": "**/*.md", "property": "tags", "old_value": "draft", "new_value": "review" }
// Output
{ "updated_count": 10, "updated_files": ["a.md", "b.md", ...] }
batch_array_sort
Sort an array property in multiple files.
| Parameter | Type | Description |
|---|---|---|
glob |
string | Glob pattern relative to base directory |
property |
string | Name of the array property |
reverse |
bool | Sort in descending order (default: false) |
Example:
// Input
{ "glob": "**/*.md", "property": "tags" }
// Output
{ "updated_count": 20, "updated_files": ["a.md", "b.md", ...] }
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.
SELECT * FROM files
WHERE TRY_CAST(date AS DATE) >= '2025-11-01'
Arrays Are JSON Strings
Arrays like tags: [ai, python] are stored as JSON strings '["ai", "python"]'. Use from_json() and UNNEST to expand them.
SELECT path, tag
FROM files, UNNEST(from_json(tags, '[""]')) AS t(tag)
WHERE tag = 'ai'
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.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file frontmatter_mcp-0.2.0.tar.gz.
File metadata
- Download URL: frontmatter_mcp-0.2.0.tar.gz
- Upload date:
- Size: 78.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d080b202851661d9337d78c5598204820d4b56edf2ee2b91faf8b691da543b6a
|
|
| MD5 |
817a4297efb02bbf26d8e2731ba2a530
|
|
| BLAKE2b-256 |
4d840cd5cc5177dd9769a544aa10cfb2a12f65949b04679afb4cc12b80037db5
|
Provenance
The following attestation bundles were made for frontmatter_mcp-0.2.0.tar.gz:
Publisher:
publish.yml on kzmshx/frontmatter-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
frontmatter_mcp-0.2.0.tar.gz -
Subject digest:
d080b202851661d9337d78c5598204820d4b56edf2ee2b91faf8b691da543b6a - Sigstore transparency entry: 731612332
- Sigstore integration time:
-
Permalink:
kzmshx/frontmatter-mcp@b59500beb7f9151ed8a0cd45baed693f099ab7e5 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/kzmshx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b59500beb7f9151ed8a0cd45baed693f099ab7e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file frontmatter_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: frontmatter_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d677b0ea2ebcb7cb67be8f142c45f34736755d43944b5919db66b0a1c3c6c363
|
|
| MD5 |
d32cc312f29cea5ee63c395f1d34c8dc
|
|
| BLAKE2b-256 |
fe7b79140d252138e2028cabd424b7bccf61206679d0a3ba6fe4d7387d4e177b
|
Provenance
The following attestation bundles were made for frontmatter_mcp-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on kzmshx/frontmatter-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
frontmatter_mcp-0.2.0-py3-none-any.whl -
Subject digest:
d677b0ea2ebcb7cb67be8f142c45f34736755d43944b5919db66b0a1c3c6c363 - Sigstore transparency entry: 731612334
- Sigstore integration time:
-
Permalink:
kzmshx/frontmatter-mcp@b59500beb7f9151ed8a0cd45baed693f099ab7e5 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/kzmshx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b59500beb7f9151ed8a0cd45baed693f099ab7e5 -
Trigger Event:
push
-
Statement type: