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

For many local MCP clients, run one shared server:

FOLIO_ROOT=~/folio folio serve --http 18765 \
  --token-file ~/.config/folio/http.token

Clients connect to http://127.0.0.1:18765/mcp with a bearer token read from that private file. Default stdio remains supported. See shared HTTP operation and dependency status before building or preparing a service/client migration.

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.

Backlinks and note summaries are cached in .folio-index.db alongside the existing search index. The offline --migrate-index step below is required before the first v0.3.1 server start. It populates the backlink cache; server starts then reuse it and parse only changed files. Writes through Folio refresh affected entries immediately. External edits are discovered by a metadata census every 15 seconds in both stdio and HTTP modes.

An edit made outside Folio (an editor, sync, or an older Folio process) can therefore take up to about 15 seconds to appear in backlinks or status. If checking a backlink after such an edit, retry after the next census. Writes through this version of Folio update the index before returning.

Upgrade an existing store to 0.3.1

The offline migration is required before starting any v0.3.1 server. Use this order: stop, migrate, install, reconnect. Do not let multiple clients perform the initial migration concurrently. On a large store this first pass can take minutes; subsequent starts reuse the persisted cache.

  1. Stop every MCP client process and shared server using the store. Disable automatic restarts for the duration of the upgrade.
  2. Run the approved new executable directly, before installing it:
   export FOLIO_ROOT=/absolute/path/to/folio-store
   candidate=/absolute/path/to/new/folio
   "$candidate" --migrate-index

Use exactly the same FOLIO_ROOT path spelling as the server configuration. Require exit status zero and Index migration complete. A failure logs the affected items and exits nonzero. Repair those items and retry; the migration resumes without rebuilding documents already completed.

  1. Install that same executable through the deployment's normal package or service mechanism. For a standalone executable deployment:
   destination=/absolute/path/to/installed/folio
   install -m 755 "$candidate" "$destination"
   "$destination" --version
  1. Re-enable the shared service or MCP clients and reconnect them to the same FOLIO_ROOT. The normal metadata census now starts from the migrated cache. Keep the old executable available for rollback.

rebuild-index replaces documents atomically without clearing the shared tables, so connected readers retain complete documents during maintenance.

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.22.15, sigil-json 0.16.2, sigil-mcp 0.18.4 and sigil-http 0.18.8. Install the published dependency graph from the committed lock without redirects; see dependency status before building.

# 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