AtlatestRenderedmarkdown
Readme

Folio

A markdown-native knowledge and project management system, exposed as an MCP server. Folio stores all state as structured markdown files — human-readable, git-committable, and programmatically queryable.

Built with Sigil.

Install

sigil app install codeberg:sigil/folio \
  --mcp \
  --env FOLIO_ROOT=~/folio

This installs the folio binary, registers it as a user-level MCP server, and points it at ~/folio as the data directory. The folio directory will be created on first run.

To install for a specific project instead (registers in the project's .mcp.json):

cd ~/my-project
sigil app install codeberg:sigil/folio \
  --mcp \
  --mcp-scope project \
  --env FOLIO_ROOT=./folio

Or add to .mcp.json manually:

{
  "mcpServers": {
    "folio": {
      "command": "folio",
      "env": {
        "FOLIO_ROOT": "./folio"
      }
    }
  }
}

What it does

Folio gives AI agents structured access to tasks, projects, and notes through MCP tools. The agent gets clean operations; you get readable markdown files with clean git diffs.

Tasks

Checkbox items with inline metadata:

- [ ] Add contact lookup tool {id: t-a3f2, priority: high, due: 2026-03-20}
- [x] Fix reply identity selection {id: t-b1c4, completed: 2026-03-13}

Projects

One markdown file per project in projects/, with YAML frontmatter, a task list, and a reverse-chronological log:

---
status: active
goal: Add contact management and improve search
area: development
last-updated: 2026-03-13
---

# Bureau v2

## Tasks

- [ ] Add contact lookup tool {id: t-a3f2, priority: high, due: 2026-03-20}
- [ ] Improve search result ranking {id: t-b1c4, priority: medium}

## Log

### 2026-03-13

Fixed identity selection for replies. Bureau now auto-detects the
correct sending identity from the original email's To field.

Notes

Atomic reference notes in notes/ with [[crosslinks]] between them:

---
tags:
  - fastmail
  - jmap
created: 2026-03-12
last-updated: 2026-03-13
---

# Fastmail JMAP Quirks

Fastmail rejects the `#draft` back-reference key in `onSuccessUpdateEmail`.

## Related

- [[caldav-discovery]] - CalDAV has similar redirect issues
- [[bureau-send-pipeline]] - Where these quirks manifest

Notes support subdirectories for organization: procedures/, contacts/, preferences/, etc. Crosslinks resolve across both notes and projects.

Inbox

A single inbox.md for capturing items before they're triaged into projects.

Directory structure

folio/
├── inbox.md
├── projects/
│   ├── bureau-v2.md
│   └── sigil-gc.md
├── notes/
│   ├── fastmail-jmap-quirks.md
│   ├── procedures/
│   │   └── email-triage.md
│   └── contacts/
│       └── alice.md
└── archive/
    ├── projects/
    └── notes/

MCP Tools

Overview

ToolDescription
folio/statusDashboard: inbox count, overdue tasks, stale projects, orphaned notes

Tasks

ToolDescription
folio/tasksQuery tasks across all projects and inbox with filters
folio/task-addAdd a task to a project or inbox
folio/task-completeMark a task as done
folio/task-updateUpdate task metadata (priority, due, tags, waiting)
folio/task-moveMove a task between projects or to inbox

A task's id is stable: moving it between the inbox and a project, or between projects, preserves the id it already had.

Bulk operations

Triaging a full inbox one call at a time is slow enough that nobody does it routinely, which is how an inbox goes months without being triaged.

ToolDescription
folio/task-move-batchMove many tasks at once, with a result line per id
folio/task-complete-batchMark many tasks done by id list
folio/task-sweepRemove completed tasks from projects
folio/inbox-sweepRemove completed items from the inbox

folio/task-move-batch takes either one shared target or per-id targets, so a single call can fan out across many projects:

{"ids": ["t-a3f2", "t-b1c4"], "project": "bureau-v2"}

{"moves": [{"id": "t-a3f2", "project": "bureau-v2"},
           {"id": "t-b1c4", "project": "sigil-gc"},
           {"id": "t-c5d6"}]}

An entry with no project moves that task to the inbox. Every id gets its own result line, so a partial failure is visible rather than swallowed.

Inbox

ToolDescription
folio/inboxList all inbox items
folio/inbox-addAdd an item to the inbox
folio/inbox-triageMove an inbox item to a project
Keep inbox captures to a single line. An item whose text contains newlines is currently written in a shape folio cannot read back: the {id: ...} metadata lands on the item's last line, the parser sees only the first, and the item becomes invisible to every tool while a phantom one-line duplicate takes its place. For anything longer, create a note and reference it from a one-line inbox item. See the Known issues section of CHANGELOG.md.

Projects

ToolDescription
folio/projectsList projects with task counts
folio/project-infoFull project details: tasks and log entries
folio/project-createCreate a new project
folio/project-logAdd a dated log entry to a project
folio/project-archiveArchive a completed project
folio/project-cleanMove completed tasks to the project log

Notes

ToolDescription
folio/notesSearch notes by text or tag
folio/note-readRead a note's full content
folio/note-createCreate a new note
folio/note-editReplace a note's content
folio/note-linksShow outgoing links and backlinks
folio/note-renameRename a note and update all crosslinks

Development

Requires Sigil v0.9.0+.

# Install dependencies
sigil deps install

# Build
sigil build

# Test
sigil test

# Run locally
FOLIO_ROOT=/tmp/folio ./build/dev/bin/folio

# Build release bundle (standalone binary)
sigil build --config release
FOLIO_ROOT=/tmp/folio ./build/release/bin/folio

License

BSD-3-Clause