Skip to main content

MCP server for querying Markdown frontmatter with DuckDB SQL

Project description

frontmatter-mcp

An MCP server for querying Markdown frontmatter with DuckDB SQL.

Configuration

{
  "mcpServers": {
    "frontmatter": {
      "command": "uvx",
      "args": ["frontmatter-mcp"],
      "env": {
        "FRONTMATTER_BASE_DIR": "/path/to/markdown/directory"
      }
    }
  }
}

With Semantic Search

To enable semantic search, use the [semantic] extras:

{
  "mcpServers": {
    "frontmatter": {
      "command": "uvx",
      "args": ["--from", "frontmatter-mcp[semantic]", "frontmatter-mcp"],
      "env": {
        "FRONTMATTER_BASE_DIR": "/path/to/markdown/directory",
        "FRONTMATTER_ENABLE_SEMANTIC": "true"
      }
    }
  }
}

Installation (Optional)

If you prefer to install globally:

pip install frontmatter-mcp
# or
uv tool install frontmatter-mcp

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 }
  }
}

// Output (with semantic search ready)
{
  "file_count": 186,
  "schema": {
    "date": { "type": "string", "count": 180, "nullable": true },
    "tags": { "type": "array", "count": 150, "nullable": true },
    "embedding": { "type": "FLOAT[256]", "nullable": false }
  }
}

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", ...] }

index_status

Get the status of the semantic search index.

This tool is only available when FRONTMATTER_ENABLE_SEMANTIC=true.

Example:

// Output (not started)
{ "state": "idle" }

// Output (indexing in progress)
{ "state": "indexing" }

// Output (ready)
{ "state": "ready" }

index_refresh

Refresh the semantic search index (differential update).

This tool is only available when FRONTMATTER_ENABLE_SEMANTIC=true.

Example:

// Output
{ "state": "indexing", "message": "Indexing started", "target_count": 665 }

// Output (when already indexing)
{ "state": "indexing", "message": "Indexing already in progress" }

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.

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.

-- Find semantically similar documents
SELECT path, 1 - array_cosine_distance(embedding, embed('feeling better')) as score
FROM files
ORDER BY score DESC
LIMIT 10

-- Combine with frontmatter filters
SELECT path, date, 1 - array_cosine_distance(embedding, embed('motivation')) as score
FROM files
WHERE date >= '2025-11-01'
ORDER BY score DESC
LIMIT 10

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

frontmatter_mcp-0.4.3.tar.gz (181.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

frontmatter_mcp-0.4.3-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file frontmatter_mcp-0.4.3.tar.gz.

File metadata

  • Download URL: frontmatter_mcp-0.4.3.tar.gz
  • Upload date:
  • Size: 181.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for frontmatter_mcp-0.4.3.tar.gz
Algorithm Hash digest
SHA256 d898d4c20b9acda2b13c5f395dc78de2a79d3fb0ba6c97648e1d7e139c69b98f
MD5 d7b6d4f15579d133162c97f2ae12549c
BLAKE2b-256 fa7360e55e7bbda4324bff3613ccdabff19459555422cdd270ac474bf5aa4145

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontmatter_mcp-0.4.3.tar.gz:

Publisher: publish.yml on kzmshx/frontmatter-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontmatter_mcp-0.4.3-py3-none-any.whl.

File metadata

File hashes

Hashes for frontmatter_mcp-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 960ff893e3daffdce4d0558e8c7443e25ca0ff31e37734ca9cc368c699f06c84
MD5 e35ad51d84076fb128028b48ebfb1920
BLAKE2b-256 3e33e57a9098d3c36b50cbe384a0de7b26ab0a2ea76ad6f4e0b149be5c07f669

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontmatter_mcp-0.4.3-py3-none-any.whl:

Publisher: publish.yml on kzmshx/frontmatter-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page