Rust CLI and MCP server for managing a personal knowledge base and todo system built on markdown files with YAML frontmatter.
This is like a lot of other markdown-based "graph knowledge base" systems, with a few small twists:
- It's designed mostly to be useful for LLMs rather than humans directly, though it's fine for humans to read and author also. But there's no automatic keyword-based Wiki-style linking; all links are explicit paths or URIs.
- It integrates the knowledge base and a to-do/ticket-tracking system. Any doc can become a tracked to-do item or "ticket" simply by setting a check-in date (when the item needs attention next) or due date. A simple recurrence system is provided for recurring tasks, but LLMs can also step in to handle more complex schedules directly.
- It supports multiple graf repos ("vaults" in Obsidian terminology) with a well-defined cross-repo linking system. It's suggested to make each graf repo also be its own git repo.
- It's written in Rust: Single binary to deploy, very few deps, very fast.
It includes an MCP server and a repo linter/tidier, though it's also usable by LLMs directly just through normal filesystem read/write/search tools. The MCP server handles structured tasks like marking a to-do item complete, or snoozing/rescheduling it, or running the linter, which are mechanical tasks LLMs are less reliable at (and more expensive).
cargo install --path . --bin grafThis puts the graf binary in ~/.cargo/bin.
For working on graf itself:
make check # fmt + clippy + test
make build # debug build
make release # optimized release buildA graf repo is a directory of .md files with YAML frontmatter, tracked by
git. Any directory works — graf doesn't require a particular layout.
mkdir ~/grafdata/myrepo && cd ~/grafdata/myrepo
git initGraf creates a SQLite cache file (.graf.db) in the repo root. This is
derived data and must not be committed:
.graf.db
The pre-commit hook runs graf lint on changed files and blocks commits
with lint errors (missing frontmatter, invalid fields, etc.):
mkdir -p .githooks
cat > .githooks/pre-commit << 'EOF'
#!/usr/bin/env bash
exec graf lint --changed
EOF
chmod +x .githooks/pre-commit
git config core.hooksPath .githooks
git add .gitignore .githooks
git commit -m "Set up graf hooks"graf needs the repo to have at least one commit before it will touch it, so don't skip this step even if you have nothing else to commit yet.
graf todo add todo/my-first-task.md "Set up graf repo" --priority 2 --check-in 2026-07-21The title is positional. At least one of --check-in or --due is required —
a task with no date isn't a task graf will ever surface to you.
Or manually create any .md file with frontmatter:
---
tldr: My first document
created: '2026-04-11T12:00:00-04:00'
updated: '2026-04-11T12:00:00-04:00'
---
Document body here.| Command | Description |
|---|---|
graf todo |
Query tasks (due today or earlier by default) |
graf todo add <path> <title> |
Create a new task |
graf todo done <path> |
Mark a task done |
graf todo cancel <path> |
Cancel a task |
graf todo schedule <path> <date> |
Set tentative date |
graf todo reorder <path> --after/--before <path> |
Reorder tasks |
graf lint |
Validate all files |
graf lint --changed |
Validate git-changed files only |
graf lint <files...> |
Validate specific files |
graf fix |
Auto-fix timestamps on changed files |
graf manifest init --id <id> |
Initialize a repo's .graf/config.toml |
graf manifest add |
Add a repo to the application manifest |
graf manifest list |
List all manifest entries |
graf manifest check |
Validate the manifest against repo configs |
graf reindex |
Rebuild the SQLite cache from scratch |
graf mcp |
Run as an MCP server (JSON-RPC over stdio) |
Paths accept slug:path (e.g. life:todo/my-task.md) to address a document
in another repo — see the multi-repo guide.
--json— JSON output (auto-enabled when stdout is not a TTY)--repo <slug|path>— repo slug or path. Defaults to the current directory, exceptgraf todo(query), which defaults to every repo in the manifest.
graf mcp serves MCP over stdio, for use by Claude Code or other MCP
clients. The tool surface is close to the CLI but not identical: the
graf_ref_* tools are MCP-only, returning reference material an LLM would
otherwise have to guess at.
| Group | Tools |
|---|---|
| Validation | graf_lint, graf_fix, graf_reindex |
| Todos | graf_todo_query, graf_todo_add, graf_todo_done, graf_todo_cancel, graf_todo_schedule, graf_todo_reorder |
| Manifest | graf_manifest_list, graf_manifest_check |
| Reference (MCP-only) | graf_ref_frontmatter_schema, graf_ref_attachments, graf_ref_links, graf_ref_context_link |