Your notes, in bullets, on your own machines.

  • An outliner like Logseq: nested blocks, [[links]], #tags, a daily journal and tasks.
  • Every device keeps the whole graph and works offline. A server you run keeps them in sync.
  • Give an agent a token and it can search, read and edit your notes one bullet at a time, over MCP.
nooklet showing a project page: nested bullets with links, tags, a task with a deadline, and linked references at the bottom.The same project page in the dark theme.
A project page with its tasks, links and the pages that reference it.

What is in it

The parts of an outliner you use every day, and nothing you would have to switch off.

  • Outlines

    Nested bullets you can fold, zoom into and drag. A block reference shows the text of the block it points to.

  • Links and references

    [[Pages]], #tags and namespaces. Every page lists what links to it, grouped by source, plus unlinked mentions.

  • Journal and tasks

    Today’s page opens first. Tasks cycle TODO, DOING, DONE with one shortcut and carry scheduled and deadline dates.

  • Search

    Full-text search on every device. Add a local Ollama model and search by meaning too, in any language.

  • Logseq import

    Point the importer at a Logseq file graph: pages, journals, properties and assets come across.

  • Plugins

    TypeScript plugins with a server half and a client half: commands, slash commands, renderers, MCP tools.

The journal: today’s page on top with tasks and links, earlier days below.The journal in the dark theme.
The journal. Today is always on top; empty days do not exist.

How sync works

Each edit becomes a small op. Devices push their ops to your server and pull everyone else’s.

  1. You edit on any device. The change and its op land in the device’s own SQLite in one transaction, online or not.
  2. The device pushes its outbox. The server checks the tree, then logs each op with the next sequence number.
  3. The server pokes the other devices. Each one pulls every op after the last number it saw.
  4. Every field merges on its own. The value with the latest clock stamp wins, so all devices land on the same state.
Phoneonline
  • Saturday
  • Return library books
  • Call the plumber
Outboxempty
Your server
  1. seq 126block.text
  2. seq 127block.place
  3. seq 128block.create
 
Laptoponline
  • Saturday
  • Return library books
  • Call the plumber
Outboxempty
Step 8 of 8: “Call the plumber” appears on the laptop. Both devices’ cursors read 128.
Laptoponline
  • Buy oat milk
  • scheduled:: 2026-10-05
Outboxempty
Your server
  1. seq 40block.create
  2. seq 41block.text
  3. seq 42block.prop
 
Phoneonline
  • Buy oat milk
  • scheduled:: 2026-10-05
Outboxempty
Step 6 of 6: Both devices show “Buy oat milk” with the date. The edits touched different fields, so both survive.

When two edits meet

Two devices change the same block’s text while offline. nooklet merges the words it can and keeps the rest where you can see it.

Starting text
Call the plumber
Laptop
Call the plumber on Monday
Phone
Call the plumber on Tuesday
Everywhere, after sync
Call the plumber on Tuesdayconflict_copy:: Call the plumber on Monday
Step 5 of 5: That cannot merge cleanly. The later edit wins, and the other text stays on the block as a conflict_copy property for you to read.

Read how sync, offline and conflicts work

Agents edit by the bullet

The operations the app uses are also an HTTP API, an OpenAPI document and an MCP server. An agent works on blocks, not whole pages.

  • graph_overview to get its bearings, then keyword, semantic or hybrid search.
  • Replace an exact substring inside one bullet and leave the rest alone.
  • Run several edits as one atomic batch, and undo that batch.
  • Every change it makes carries the token’s label in page history and the audit log.
  • Nothing is on until you run nooklet token create.
.mcp.json
{
  "mcpServers": {
    "nooklet": {
      "type": "http",
      "url": "http://127.0.0.1:6100/g/default/mcp",
      "headers": { "Authorization": "Bearer ${NOOKLET_TOKEN}" }
    }
  }
}

Connect an agent

Plain files you can walk away with

SQLite holds the truth. The server also writes every page to a markdown file that Logseq and Obsidian can open.

  • One file per page, one per journal day.
  • The ^id at the end of a line is the block’s stable id, so references survive the round trip.
  • grep and git work on the folder. Edit through the app, though: nooklet writes the files and does not read them back.
pages/Aurora.md
type:: project

- TODO Read the ADR on sync ^1m433dkhgaxame
  - started on the HLC part ^1m433dkhgaxamf
- Ask [[Jana]] about the #trip dates ^1m433dkhgaxamg

Install it, write notes, and stop there if you like. Sync and agents wait until you ask.