AtlatestRepositoryfolio
1
# Folio3
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.5
Built with [Sigil](https://codeberg.org/sigil/sigil).7
## Install9
```bash10
sigil app install codeberg:sigil/folio \11
--mcp \12
--env FOLIO_ROOT=~/folio13
```15
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.17
To install for a specific project instead (registers in the project's `.mcp.json`):19
```bash20
cd ~/my-project21
sigil app install codeberg:sigil/folio \22
--mcp \23
--mcp-scope project \24
--env FOLIO_ROOT=./folio25
```27
Or add to `.mcp.json` manually:29
```json30
{31
"mcpServers": {32
"folio": {33
"command": "folio",34
"env": {35
"FOLIO_ROOT": "./folio"36
}37
}38
}39
}40
```42
## What it does44
For many local MCP clients, run one shared server:46
```bash47
FOLIO_ROOT=~/folio folio serve --http 18765 \48
--token-file ~/.config/folio/http.token49
```51
Clients connect to `http://127.0.0.1:18765/mcp` with a bearer token read from52
that private file. Default stdio remains supported. See53
[shared HTTP operation and dependency status](docs/shared-http.md)54
before building or preparing a service/client migration.56
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.58
### Tasks60
Checkbox items with inline metadata:62
```markdown63
- [ ] Add contact lookup tool {id: t-a3f2, priority: high, due: 2026-03-20}64
- [x] Fix reply identity selection {id: t-b1c4, completed: 2026-03-13}65
```67
### Projects69
One markdown file per project in `projects/`, with YAML frontmatter, a task list, and a reverse-chronological log:71
```markdown72
---73
status: active74
goal: Add contact management and improve search75
area: development76
last-updated: 2026-03-1377
---79
# Bureau v281
## Tasks83
- [ ] Add contact lookup tool {id: t-a3f2, priority: high, due: 2026-03-20}84
- [ ] Improve search result ranking {id: t-b1c4, priority: medium}86
## Log88
### 2026-03-1390
Fixed identity selection for replies. Bureau now auto-detects the91
correct sending identity from the original email's To field.92
```94
### Notes96
Atomic reference notes in `notes/` with `[[crosslinks]]` between them:98
```markdown99
---100
tags:101
- fastmail102
- jmap103
created: 2026-03-12104
last-updated: 2026-03-13105
---107
# Fastmail JMAP Quirks109
Fastmail rejects the `#draft` back-reference key in `onSuccessUpdateEmail`.111
## Related113
- [[caldav-discovery]] - CalDAV has similar redirect issues114
- [[bureau-send-pipeline]] - Where these quirks manifest115
```117
Notes support subdirectories for organization: `procedures/`, `contacts/`, `preferences/`, etc. Crosslinks resolve across both notes and projects.119
Backlinks and note summaries are cached in `.folio-index.db` alongside the120
existing search index. The offline `--migrate-index` step below is required121
before the first v0.3.1 server start. It populates the backlink cache; server122
starts then reuse it and parse only changed files. Writes through Folio123
refresh affected entries immediately. External edits are discovered by a124
metadata census every 15 seconds in both stdio and HTTP modes.126
An edit made outside Folio (an editor, sync, or an older Folio process) can127
therefore take up to about 15 seconds to appear in backlinks or status.128
If checking a backlink after such an edit, retry after the next census.129
Writes through this version of Folio update the index before returning.131
### Upgrade an existing store to 0.3.1133
The offline migration is required before starting any v0.3.1 server.134
Use this order: **stop, migrate, install, reconnect**. Do not let multiple135
clients perform the initial migration concurrently. On a large store this136
first pass can take minutes; subsequent starts reuse the persisted cache.138
1. Stop every MCP client process and shared server using the store. Disable139
automatic restarts for the duration of the upgrade.140
2. Run the approved new executable directly, before installing it:142
```bash143
export FOLIO_ROOT=/absolute/path/to/folio-store144
candidate=/absolute/path/to/new/folio145
"$candidate" --migrate-index146
```148
Use exactly the same `FOLIO_ROOT` path spelling as the server configuration.149
Require exit status zero and `Index migration complete`. A failure logs150
the affected items and exits nonzero. Repair those items and retry; the151
migration resumes without rebuilding documents already completed.152
3. Install that same executable through the deployment's normal package or153
service mechanism. For a standalone executable deployment:155
```bash156
destination=/absolute/path/to/installed/folio157
install -m 755 "$candidate" "$destination"158
"$destination" --version159
```161
4. Re-enable the shared service or MCP clients and reconnect them to the162
same `FOLIO_ROOT`. The normal metadata census now starts from the migrated163
cache. Keep the old executable available for rollback.165
`rebuild-index` replaces documents atomically without clearing the shared166
tables, so connected readers retain complete documents during maintenance.168
### Inbox170
A single `inbox.md` for capturing items before they're triaged into projects.172
## Directory structure174
```175
folio/176
├── inbox.md177
├── projects/178
│ ├── bureau-v2.md179
│ └── sigil-gc.md180
├── notes/181
│ ├── fastmail-jmap-quirks.md182
│ ├── procedures/183
│ │ └── email-triage.md184
│ └── contacts/185
│ └── alice.md186
└── archive/187
├── projects/188
└── notes/189
```191
## MCP Tools193
### Overview195
| Tool | Description |196
|------|-------------|197
| `folio/status` | Dashboard: inbox count, overdue tasks, stale projects, orphaned notes |199
### Tasks201
| Tool | Description |202
|------|-------------|203
| `folio/tasks` | Query tasks across all projects and inbox with filters |204
| `folio/task-add` | Add a task to a project or inbox |205
| `folio/task-complete` | Mark a task as done |206
| `folio/task-update` | Update task metadata (priority, due, tags, waiting) |207
| `folio/task-move` | Move a task between projects or to inbox |209
A task's id is stable: moving it between the inbox and a project, or between210
projects, preserves the id it already had.212
### Bulk operations214
Triaging a full inbox one call at a time is slow enough that nobody does it215
routinely, which is how an inbox goes months without being triaged.217
| Tool | Description |218
|------|-------------|219
| `folio/task-move-batch` | Move many tasks at once, with a result line per id |220
| `folio/task-complete-batch` | Mark many tasks done by id list |221
| `folio/task-sweep` | Remove completed tasks from projects |222
| `folio/inbox-sweep` | Remove completed items from the inbox |224
`folio/task-move-batch` takes either one shared target or per-id targets, so a225
single call can fan out across many projects:227
```json228
{"ids": ["t-a3f2", "t-b1c4"], "project": "bureau-v2"}230
{"moves": [{"id": "t-a3f2", "project": "bureau-v2"},231
{"id": "t-b1c4", "project": "sigil-gc"},232
{"id": "t-c5d6"}]}233
```235
An entry with no `project` moves that task to the inbox. Every id gets its own236
result line, so a partial failure is visible rather than swallowed.238
### Inbox240
| Tool | Description |241
|------|-------------|242
| `folio/inbox` | List all inbox items |243
| `folio/inbox-add` | Add an item to the inbox |244
| `folio/inbox-triage` | Move an inbox item to a project |246
> **Keep inbox captures to a single line.** An item whose text contains247
> newlines is currently written in a shape folio cannot read back: the248
> `{id: ...}` metadata lands on the item's last line, the parser sees only the249
> first, and the item becomes invisible to every tool while a phantom250
> one-line duplicate takes its place. For anything longer, create a note and251
> reference it from a one-line inbox item. See the Known issues section of252
> CHANGELOG.md.254
### Projects256
| Tool | Description |257
|------|-------------|258
| `folio/projects` | List projects with task counts |259
| `folio/project-info` | Full project details: tasks and log entries |260
| `folio/project-create` | Create a new project |261
| `folio/project-log` | Add a dated log entry to a project |262
| `folio/project-archive` | Archive a completed project |263
| `folio/project-clean` | Move completed tasks to the project log |265
### Notes267
| Tool | Description |268
|------|-------------|269
| `folio/notes` | Search notes by text or tag |270
| `folio/note-read` | Read a note's full content |271
| `folio/note-create` | Create a new note |272
| `folio/note-edit` | Replace a note's content |273
| `folio/note-links` | Show outgoing links and backlinks |274
| `folio/note-rename` | Rename a note and update all crosslinks |276
## Development278
Requires [Sigil](https://codeberg.org/sigil/sigil) v0.22.15, sigil-json 0.16.2,279
sigil-mcp 0.18.4 and sigil-http 0.18.8. Install the published dependency graph280
from the committed lock without redirects; see281
[dependency status](docs/shared-http.md#development-status) before building.283
```bash284
# Install dependencies285
sigil deps install287
# Build288
sigil build290
# Test291
sigil test293
# Run locally294
FOLIO_ROOT=/tmp/folio ./build/dev/bin/folio296
# Build release bundle (standalone binary)297
sigil build --config release298
FOLIO_ROOT=/tmp/folio ./build/release/bin/folio299
```301
## License303
BSD-3-Clause