Markdown元数据查询服务

一个基于DuckDB SQL的Markdown元数据查询和语义搜索服务,适用于文档管理和内容检索。

  • by kzmshx
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 kzmshx/filesystem-frontmatter-mcp

使用说明

frontmatter mcp

用于使用DuckDB SQL查询Markdown frontmatter的MCP服务器。

配置

基本用法

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

使用语义搜索

语义搜索需要较大的依赖关系(~1GB)。集 MCP_TIMEOUT 要延长安装超时时间,请执行以下操作:

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

注: MCP_TIMEOUT 以毫秒为单位(300000=5分钟)。

安装(可选)

如果您希望全局安装:

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

工具

query_inspect

跨文件从frontmatter获取模式信息。

参数 类型 说明
glob string 相对于基本目录的全局模式

例子:

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

怎么翻译

使用DuckDB SQL查询前台数据。

参数 类型 说明
glob string 相对于基本目录的全局模式
sql string DuckDB SQL查询引用 files 桌子

例子:

// 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"}
  ]
}

更新

在单个文件中更新frontmatter属性。

参数 类型 说明
path string 相对于基本目录的文件路径
set object 要添加或覆盖的属性
unset string[] 要删除的属性名称

例子:

// Input
{ "path": "notes/idea.md", "set": {"status": "published"} }

// Output
{ "path": "notes/idea.md", "frontmatter": {"title": "Idea", "status": "published"} }

批量更新

更新多个文件中的frontmatter属性。

参数 类型 说明
glob string 相对于基本目录的全局模式
set object 要添加或覆盖的属性
unset string[] 要删除的属性名称

例子:

// Input
{ "glob": "drafts/*.md", "set": {"status": "review"} }

// Output
{ "updated_count": 5, "updated_files": ["drafts/a.md", "drafts/b.md", ...] }

batch_array_add

为多个文件中的数组属性添加值。

参数 类型 说明
glob string 相对于基本目录的全局模式
property string 数组属性的名称
value any 要添加的值
allow_duplicates bool 允许重复值(默认值:false)

例子:

// Input
{ "glob": "**/*.md", "property": "tags", "value": "reviewed" }

// Output
{ "updated_count": 42, "updated_files": ["a.md", "b.md", ...] }

batch_array_remove

从多个文件中的数组属性中删除一个值。

参数 类型 说明
glob string 相对于基本目录的全局模式
property string 数组属性的名称
value 任何 要删除的值

例子:

// Input
{ "glob": "**/*.md", "property": "tags", "value": "draft" }

// Output
{ "updated_count": 15, "updated_files": ["a.md", "b.md", ...] }

batch_array_replace

替换多个文件中数组属性中的值。

参数 类型 说明
glob string 相对于基本目录的全局模式
property string 数组属性的名称
old_value 任何 要替换的值
new_value any 新值

例子:

// Input
{ "glob": "**/*.md", "property": "tags", "old_value": "draft", "new_value": "review" }

// Output
{ "updated_count": 10, "updated_files": ["a.md", "b.md", ...] }

批次排序

对多个文件中的数组属性进行排序。

参数 类型 说明
glob string 相对于基本目录的全局模式
property string 数组属性的名称
reverse bool 按降序排序(默认值:false)

例子:

// Input
{ "glob": "**/*.md", "property": "tags" }

// Output
{ "updated_count": 20, "updated_files": ["a.md", "b.md", ...] }

batch_array_unique

从多个文件中的数组属性中删除重复值。

参数 类型 说明
glob string 相对于基本目录的全局模式
property string 数组属性的名称

例子:

// Input
{ "glob": "**/*.md", "property": "tags" }

// Output
{ "updated_count": 5, "updated_files": ["a.md", "b.md", ...] }

索引状态

获取语义搜索索引的状态。

此工具仅在以下情况下可用 FRONTMATTER_ENABLE_SEMANTIC=true.

例子:

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

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

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

索引_刷新

刷新语义搜索索引(差异更新)。

此工具仅在以下情况下可用 FRONTMATTER_ENABLE_SEMANTIC=true.

例子:

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

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

技术说明

所有值都是字符串

所有frontmatter值都以字符串形式传递给DuckDB。使用 TRY_CAST 在SQL中用于在需要时进行类型转换。

SELECT * FROM files
WHERE TRY_CAST(date AS DATE) >= '2025-11-01'

数组是JSON字符串

数组类似 tags: [ai, python] 存储为JSON字符串 '["ai", "python"]'.使用 from_json() 和 UNNEST 扩大它们。

SELECT path, tag
FROM files, UNNEST(from_json(tags, '[""]')) AS t(tag)
WHERE tag = 'ai'

模板表达式支持

包含黑曜石模板表达式的文件(例如。, <% tp.date.now("YYYY-MM-DD") %>)被优雅地处理。这些表达式被视为字符串,自然会被日期过滤排除在外。

语义搜索

启用语义搜索后,您可以使用 embed() 功能和 embedding SQL查询中的列。运行后 index_refresh,markdown正文内容被索引为向量。

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

环境变量:

变量 默认值 描述
FRONTMATER_BASE_DIR (必填) 文件的基本目录
FRONTMATTER_ENABLE_SEMANTIC false 启用语义搜索
FRONTMATTER_EMBEDDING_MODEL cl nagoya/ruri-v3-30m 嵌入模型名称
FRONTMATTER_CACHE_DIR FRONTMATER_BASE_DIR/.FRONTMATTER mcp 缓存嵌入目录

许可证

麻省理工学院