Skip to main content
Glama
caffeinatedwes

Markdown Frontmatter MCP

README.md
# markdown-frontmatter-mcp

A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that queries Markdown files by front matter metadata. Designed for Obsidian vaults and other Markdown-based knowledge bases.

## The Problem

You have a Markdown knowledge base (Obsidian, etc.) with front matter like:

```yaml
---
created: 2025-12-09
updated: 2025-12-11
tags: [ai-systems, strategy]
---
```

You want to ask an AI: *"What have I been thinking about [X] lately?"*

Existing tools can search by keywords or do semantic search, but none let you query by **front matter metadata** — filtering by tags AND recency.

## The Solution

This MCP server exposes one tool: `query_recent_notes`

```
query_recent_notes(
  tags: ["ai-systems"],     # Filter by these tags (matches ANY)
  days: 7,                  # How far back to look
  folders: ["thoughts"],    # Which folders to search
  limit: 10                 # Max results
)
```

Returns:
- File path
- Title (from H1 or filename)
- Tags
- Created/updated dates
- Excerpt (first ~200 chars)

## Installation

### From PyPI (coming soon)

```bash
pip install markdown-frontmatter-mcp
```

### From Source

```bash
git clone https://github.com/caffeinatedwes/markdown-frontmatter-mcp
cd markdown-frontmatter-mcp
pip install -e .
```

## Configuration

### Environment Variable

Set `KB_PATH` to point to your knowledge base:

```bash
export KB_PATH=/path/to/your/obsidian/vault
```

### MCP Client Configuration

#### TypingMind

Add to your MCP config:

```json
{
  "mcpServers": {
    "markdown-kb": {
      "command": "python3",
      "args": ["/path/to/markdown-frontmatter-mcp/src/server.py"],
      "env": {
        "KB_PATH": "/path/to/your/obsidian/vault"
      }
    }
  }
}
```

#### Claude Desktop

Add to `~/.config/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "markdown-kb": {
      "command": "python3",
      "args": ["/path/to/markdown-frontmatter-mcp/src/server.py"],
      "env": {
        "KB_PATH": "/path/to/your/obsidian/vault"
      }
    }
  }
}
```

## Usage Examples

Once configured, you can ask the AI:

> "Get my recent thinking on AI systems"

The AI will call:
```
query_recent_notes(tags=["ai-systems"], days=7)
```

> "What personal growth stuff have I been working on?"

```
query_recent_notes(tags=["personal-growth", "therapy"], days=14)
```

> "Catch me up on what's been on my mind"

```
query_recent_notes(days=3, limit=5)
```

## Front Matter Requirements

For files to be queryable, they need YAML front matter with:

- `created` or `date`: When the note was created (YYYY-MM-DD)
- `updated` (optional): When last meaningfully edited (YYYY-MM-DD)
- `tags` (optional): List of tags for filtering

Example:
```yaml
---
created: 2025-12-09
updated: 2025-12-11
tags:
  - ai-systems
  - knowledge-management
---

# My Note Title

Content here...
```

## How It Works

1. Walks the specified folders in your knowledge base
2. Parses YAML front matter from each `.md` file
3. Filters by:
   - Date: `created` or `updated` within the `days` window
   - Tags: matches ANY of the specified tags
4. Returns results sorted by most recently touched

## Skipped Directories

The server automatically skips:
- `.obsidian`
- `.git`
- `.smart-env`
- `.versiondb`
- `node_modules`
- Any directory starting with `.`

## Development

### Testing Locally

```bash
# Set your KB path
export KB_PATH=~/your-obsidian-vault

# Run the server directly (for testing)
python3 src/server.py
```

Then send JSON-RPC messages via stdin:

```json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"query_recent_notes","arguments":{"tags":["ai-systems"],"days":7}}}
```

## License

MIT