{
  "markdown": "# Stickies (Claude Code plugin)\n\n[![npm](https://img.shields.io/npm/v/stickies-mcp?logo=npm&color=cb3837)](https://www.npmjs.com/package/stickies-mcp)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.dumbspacecookie%2Fstickies-6f42c1)](https://registry.modelcontextprotocol.io)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n[![Node](https://img.shields.io/node/v/stickies-mcp)](https://nodejs.org)\n\n**Persistent sticky notes for Claude Code.** You pin a note — a decision, a blocker, a todo —\nand it survives session resets, `/clear`, and closing the terminal. Next time you open Claude\nin that project, the notes that still matter are handed back to it automatically.\n\n**Stickies is not a memory system, and it doesn't try to be one.** It won't watch your session\nand decide what to remember. It's the opposite: a handful of notes *you* (or Claude, on request)\nwrite down on purpose, that expire on their own, and that you can read, prune, and trust. No\nvectors, no LLM summarization, no cloud. If you want an AI that auto-remembers everything, use\n[Claude Code's built-in memory](https://code.claude.com/docs/en/memory) — it's on by default.\nStickies is for when you want the twenty notes that actually matter, and you want them to expire.\n\n---\n\n## Quick start (60 seconds)\n\nYou need **Node ≥ 22.5** (`node -v` to check — it's for the built-in SQLite).\n\n```sh\nclaude plugin marketplace add dumbspacecookie/stickies\nclaude plugin install stickies@stickies --scope user\n```\n\nRestart Claude Code. That's it — install once, it works in every project. Now try it:\n\n- **Ask Claude to remember something:** *\"pin a P1 todo: fix the auth leak before release.\"*\n  Claude writes it down; it'll be waiting for you next session.\n- **See your notes:** type `/stickies` in Claude Code. Prefer a shell? `npm i -g stickies-mcp`\n  gives you a `stickies` command — then `stickies list`.\n- **Open the board in a browser:** `/stickies dashboard`, then `stickies dashboard --link` for an\n  authorized URL (the board serves your notes, so it only answers a browser you've let in).\n\nNothing leaves your machine. Everything is a local SQLite file on your disk until *you* turn on\noptional git sync.\n\n---\n\n## Where it works\n\nNotes belong to the **project**, not the app you're in — one local database, scoped by project.\nWhat changes between surfaces is how much happens automatically.\n\n| Surface | What you get | How |\n|---|---|---|\n| **Terminal** (Claude Code CLI) | ✅ the full loop — auto-capture, session-start digest, `/stickies`, statusline, dashboard | install the plugin |\n| **Claude Desktop** (chat app) | ✅ read / write via MCP tools (no hooks; pass the project path) | add the MCP server to `claude_desktop_config.json` |\n| **iPhone / web** (Remote Control) | ✅ full loop — the phone drives a session running on your machine | run `claude remote-control` on your machine |\n| **iPhone / web** (cloud sandbox) | ✅ full loop via **repo-mode** — notes committed into the repo | `stickies init-repo` (see [Repo-mode](#repo-mode-cloud--mobile)) |\n| **Any MCP client** | ✅ read / write | it's on the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.dumbspacecookie/stickies` |\n| **Anywhere, read-only** | ✅ a glance at your board | Discord digest / board card |\n\n---\n\n## Two things here you won't find elsewhere\n\n- **Zero-turn capture.** Claude parks a note by writing one line *in a reply it was already\n  writing* — `!!sticky todo P1 :: fix the auth leak` — and a Stop hook persists it. No extra tool\n  call, no extra turn, no tokens spent on a round-trip. (See [Auto-capture](#auto-capture).)\n- **Importance-graded injection.** The session-start digest degrades *by importance*, not by\n  position: P1 in full, P2 truncated, P3 a bare count. It never just chops the list at N lines.\n\n---\n\n## Flow Board\n\nIf your project plans work in a `.planning/ROADMAP.md` (the GSD planning convention), Stickies also\ngives you a **live Kanban board** derived straight from that roadmap —\nTo-Do / Doing / Done — with your stickies cross-linked onto the phases they're about. It's a\nprojection of your plan, derived on the fly, so it can never drift out of sync with it.\n\n**Four places to see the same board, pick whichever fits where you are:**\n\n| Where | Command | Good for |\n|---|---|---|\n| **On GitHub / your phone** | `stickies board` → commit `BOARD.md` | glancing at progress from a phone browser — `BOARD.md` renders natively on github.com, no server, no app |\n| **In a browser** (local) | `stickies dashboard` → open `/board` | an interactive Kanban; `/graph` shows the plan's dependency DAG |\n| **In Discord** | `stickies board --discord` | a push-glanceable card — progress, column counts, per-phase status |\n| **In your statusline** | (see [Statusline](#statusline)) | a tiny always-on `📋 ▶2 ☐1 ✓2` (doing / to-do / done) |\n\n```sh\nstickies board                     # write BOARD.md in the project root (commit it → view on GitHub)\nstickies board --out docs/BOARD.md # write it somewhere else\nstickies board --discord           # post the board to your Discord webhook instead\n```\n\nEach phase shows its progress (`3/4`), its wave, whether it shipped (`✓ shipped 4/4`) and whether\nit's blocked (`⛔`). In a cloud/mobile session with no `.planning/`, a committed `.flow/` snapshot\nkeeps the board self-sufficient — same repo-mode idea as the notes.\n\n---\n\n## Everyday commands\n\n**In Claude Code** (the `/stickies` slash command):\n\n| Command | Does |\n|---|---|\n| `/stickies` | list this project's active notes (+ globals) |\n| `/stickies all` | list every project's notes |\n| `/stickies add <text>` | add a note by hand |\n| `/stickies dismiss <id>` | clear a note (a todo is \"done\" when dismissed) |\n| `/stickies dashboard` | open the local web board |\n| `/stickies sync` | sync through your git repo (if configured) |\n\n**In any shell** (the CLI — same engine). Install it with `npm i -g stickies-mcp` to get the\n`stickies` command on your PATH, then:\n\n```sh\nstickies list                          # active notes for this dir + globals\nstickies list --all                    # every project + globals\nstickies add \"ship the release\" -c todo -i P1     # add a P1 todo to this project\nstickies add \"pay invoice\" -c todo --due 2d       # a deadline (30m/2h/1d/1w/tomorrow/YYYY-MM-DD)\nstickies add \"call the bank\" -c todo -p global    # a global todo — shows up everywhere\nstickies dismiss <id> -r \"done\"        # clear it\nstickies dashboard --open              # local web board, open the browser\nstickies board                         # write a GitHub-viewable BOARD.md\nstickies status                        # the one-line statusline summary\nstickies sync                          # pull → merge → commit (push needs STICKIES_SYNC_PUSH=1)\nstickies notify                        # push the open list to Discord\nstickies init-repo                     # make notes work in cloud/mobile (repo-mode)\n```\n\n---\n\n## Auto-capture\n\nThe lowest-friction way in: Claude captures a durable fact by writing one line in its reply, and\na Stop hook persists it — no tool call, no extra turn.\n\n```\n!!sticky <category> [P1|P2|P3] [global] [#tag ...] :: <content>\n!!sticky decision P1 #storage :: storage is node:sqlite, no native deps\n!!sticky todo P1 global :: cut the npm release\n```\n\n`category` is required; importance defaults to **P2**; notes are deduped. `global` and `#tags`\nare optional and may appear in any order. Without `global`, a note is scoped to the current\nproject; with it, the note surfaces in **every** project.\n\nThe hook scans the whole completed turn, so a directive written *before* Claude runs more tools\nstill gets saved. Directives inside subagent replies are ignored. Secrets are scrubbed on write.\n\n---\n\n## Statusline\n\nPoint your Claude Code statusline at Stickies to get an always-on summary. It's **opt-in** — add\nthis to your `settings.json`:\n\n```json\n{ \"statusLine\": { \"type\": \"command\", \"command\": \"stickies status\" } }\n```\n\n(that uses the `stickies` command from `npm i -g stickies-mcp`)\n\nBy default it's compact — a count plus an urgency flag, e.g. `🟨 2!·19` (2 urgent of 19). It\ndeliberately does **not** print note text (so nothing sensitive lands in your prompt); set\n`STICKIES_STATUSLINE_VERBOSE=1` if you want the top note's text too.\n\n**Light / dark.** A statusline can't repaint your terminal's background — it can only colour\nits own text — so the theme's job is to stay legible on whatever background you already have.\nThe dark palette (default) uses the terminal's own bright colours; the light palette swaps in\ndarker truecolour values that survive a white background (tuned to clear WCAG AA text contrast).\nPick it with **`STICKIES_THEME=light`** (or `dark`) in your environment, or per-invocation with\n**`stickies status --light`** / `--theme dark`. On macOS/Linux terminals that publish `$COLORFGBG` it also\nautodetects; **Windows Terminal / PowerShell don't set that variable**, so on Windows set\n`STICKIES_THEME` explicitly if you run a light terminal. The dashboard (`/`, `/board`, `/graph`)\nis a real web page, so *it* gets a full ☾/☀ toggle that flips the whole background — that's a\npage it owns, unlike the statusline.\n\n**Clickable link.** In a terminal that supports OSC-8 hyperlinks (Windows Terminal, iTerm2,\nWezTerm, Kitty, Ghostty) the segment becomes a **Ctrl+click link that opens the dashboard**. Two\nthings it needs:\n\n- A **dashboard must actually be running** — `stickies dashboard --detach`. The segment is a\n  link *only* while one is; with none running you still get the counts, just not underlined and\n  not clickable. That is deliberate: a link to a closed port looks alive, fails only when you\n  click it, and blames your browser rather than us. Autostart is off unless you ask for it, so\n  **no link is the default state on a fresh install**. If the segment is not clickable and you\n  expected it to be, `stickies doctor` says which of these two it is.\n- On **Windows Terminal**, Claude Code doesn't auto-detect hyperlink support, so set\n  `FORCE_HYPERLINK=1` in your environment *before launching Claude Code* (e.g.\n  `setx FORCE_HYPERLINK 1`, then restart). Without it the segment renders but isn't clickable.\n\nThe link auto-skips under tmux (which mangles OSC-8), disables with `--no-link`, and its port\nfollows `STICKIES_DASHBOARD_PORT`.\n\n---\n\n## Dashboard\n\n```sh\nstickies dashboard                 # http://127.0.0.1:7317/\nstickies dashboard --open          # and open the browser\nstickies dashboard --detach        # run in the background\nstickies dashboard --link          # print an authorized URL for a browser\nstickies dashboard --stop          # stop the running one\n```\n\nLoopback only (never leaves `127.0.0.1`). Routes: `/` the notes board, `/board` the Flow Board\nKanban, `/graph` the plan dependency DAG. One dashboard covers **every** project you take notes\nin — the header switcher moves between them, so you don't run one per folder.\n\n**It only starts when you ask.** Installing Stickies does not put a server on your machine. If\nyou'd rather each Claude session bring one up automatically, set `STICKIES_DASHBOARD_AUTOSTART=1`\n(skipped in CI and remote sessions regardless).\n\n**\"Not authorized\"?** That's expected, not a bug. The dashboard serves your notes and planning\ndocuments, so it answers only a browser you've authorized:\n\n```sh\nstickies dashboard --link          # → paste into your browser\n```\n\n…or Ctrl+click the Stickies segment in your statusline, which carries one. Opening the link sets\na cookie; that's what lasts. Links themselves expire after a few minutes, so an old one from your\nscrollback will be refused — get a fresh one. Prefer it open? `STICKIES_DASHBOARD_AUTH=0`.\n\n**Editing the plan from the board** is off by default. With `STICKIES_BOARD_WRITEBACK=1`, dragging\na card rewrites that phase's `**Status:**` line in `.planning/ROADMAP.md`, keeping a pre-edit copy\nin `.flow/roadmap-backups/`. A move that contradicts the phase's plan checkboxes is refused rather\nthan written.\n\nSomething not behaving? `stickies doctor` reports the whole setup in one shot — what's running,\non which port, whether the installed plugin copy is stale — with your home directory abbreviated\nto `~` so the output is safe to paste.\n\n---\n\n## Provenance\n\nEvery note records **where it was written** — 💻 terminal, 🖥️ desktop, or 📱 mobile — so on the\ndashboard you can tell the note you jotted from your phone from the one Claude captured at your\ndesk. It's a best-effort stamp each entry point knows about itself; no configuration needed.\n\n---\n\n## Sync (git-backed, opt-in)\n\nSync through a git repo **you own** — no third-party service, no new account. This is the only\nfeature that ever touches the network, and only once you point it at a remote.\n\n```sh\nexport STICKIES_SYNC_REPO=/path/to/your/stickies-data   # a git clone you control\nstickies sync           # pull → merge (last-writer-wins) → export → commit (push: STICKIES_SYNC_PUSH=1)\n\n# or offline, through any file channel:\nstickies export -f notes.json\nstickies import -f notes.json\n```\n\nEach note carries a machine-independent key derived from the project's **git remote** (SSH and\nHTTPS collapse to the same key), so a project's notes follow you between machines even when the\ncheckout lives at a different path on each. Merge is whole-record last-writer-wins by `updated_at`\n— conflict-free and order-independent.\n\n**Auto-sync** (also opt-in): set `STICKIES_AUTO_SYNC=1` alongside `STICKIES_SYNC_REPO` and Stickies\npulls on session start and **commits** when a turn captures a note. Unset, nothing syncs on its own.\n\n**Pushing is a third opt-in.** Capturing a note commits to your sync repo and stops there —\n`STICKIES_SYNC_PUSH=1` is what makes it `git push` as well. Without it your notes are versioned\nlocally and **never leave the machine**, so a second machine will never see them. The push runs\nbare (no remote, no refspec) so your own git config decides where it goes; deriving that\nourselves went wrong three separate ways, once writing a stray branch onto a shared `main`.\n\n---\n\n## Repo-mode (cloud / mobile)\n\nThe plugin lives in `~/.claude`, so it doesn't exist in a cloud session (the iPhone app /\nclaude.ai/code run in an ephemeral VM that only sees the repo they cloned). **Repo-mode** makes\nStickies work there — no plugin, nothing to install:\n\n```sh\nstickies init-repo         # run inside the repo you want notes in\n```\n\nThat commits a self-contained, zero-dependency engine and wires it up:\n\n- `.stickies/notes.json` — the store, plus a human-readable `.stickies/NOTES.md` mirror\n- `.claude/settings.json` — a SessionStart hook (the digest) and a Stop hook (`!!sticky` capture)\n- `CLAUDE.md` — teaches Claude the `!!sticky` convention\n- `.github/workflows/stickies-sync.yml` — converges notes from every session branch into `main`\n\nCloud sessions write to their own branch; the bundled Action merges each note into `main`\n(union + dismiss-wins + dedupe) — one converged board per repo, hands-off. Same `!!sticky` grammar\nand same redaction as the local plugin.\n\nTwo things worth knowing before you run it: your notes live **in that repo**, so they are as\npublic as it is; and if a step can't be done safely — an unparseable `.claude/settings.json`,\nmost often an unresolved merge conflict — that file is left alone and the command warns and\nexits non-zero rather than replacing it.\n\n---\n\n## The sticky model\n\nFields: `id`, `content` (≤ 500 chars), `category`, `importance` (P1/P2/P3),\n`project_path` (absolute, or null for global), `tags[]`, `origin`, timestamps, `expires_at`,\n`source` (auto/manual), `status` (active/stale/dismissed).\n\n**Default TTLs:** decision 30d · blocker 7d · preference 90d · context 14d · **todo never expires**\n(a task is done when you dismiss it, not when a timer runs out). That last one is what makes\n`todo` + `global` a real cross-project task list — an unfinished task can't silently vanish.\n\n**Storage:** one SQLite file for all projects, scoped per-project — `$STICKIES_DB` if set, else\n`~/.stickies/stickies.db`. It uses Node's **built-in** SQLite (`node:sqlite`, hence Node ≥ 22.5),\nso the plugin has zero compiled dependencies and survives Claude Code's plugin-cache copy on any\nmachine.\n\n**Session-start digest:** P1 in full, P2 to ~100 chars, P3 a count. It's handed to Claude through\nthe SessionStart hook's `additionalContext` — it reaches the model **without writing to any file**.\n\n---\n\n## Claude Desktop (MCP only)\n\nClaude Desktop supports the MCP tools (`stickies_write` / `stickies_read` / `stickies_dismiss`) but\nnot hooks or the slash command, so there's no auto-capture or digest there — add it and pass the\nproject path explicitly. In `claude_desktop_config.json` (`%APPDATA%\\Claude\\` on Windows,\n`~/Library/Application Support/Claude/` on macOS):\n\n```json\n{\n  \"mcpServers\": {\n    \"stickies\": {\n      \"command\": \"node\",\n      \"args\": [\"--disable-warning=ExperimentalWarning\", \"/abs/path/to/stickies/src/server.js\"]\n    }\n  }\n}\n```\n\nBoth clients read the same `~/.stickies/stickies.db`, so a note written in one shows up in the\nother with no sync step.\n\n---\n\n## Components (reference)\n\n| Component | File | Purpose |\n|---|---|---|\n| MCP server | `src/server.js` | tools `stickies_write` / `stickies_read` / `stickies_dismiss` |\n| SessionStart hook | `src/session-start.js` | injects the digest via `additionalContext` (touches no file) |\n| Stop hook (auto-capture) | `src/auto-capture.js`, `src/directives.js` | persists `!!sticky …` directives, deduped |\n| Local dashboard | `src/dashboard.js`, `src/dashboard-page.js` | loopback web UI: notes, `/board`, `/graph` |\n| Flow Board | `src/flow/` | derive the Kanban from `.planning/ROADMAP.md`; `BOARD.md` export; `.flow/` snapshot |\n| Slash command | `commands/stickies.md` | `/stickies …` |\n| CLI | `src/cli.js` | backs the slash command; usable directly |\n| Store / DB | `src/store.js`, `src/db.js` | CRUD + schema + TTL + dedup + provenance |\n| Sync | `src/sync.js`, `src/git-sync.js` | export/import + git pull→merge→commit (push is opt-in) |\n| Redaction | `src/redact.js` | scrubs secrets from content on write |\n| Repo-mode | `src/repo-mode/` | committed store + hooks + reconcile Action for cloud/mobile |\n\n---\n\n## Install & develop\n\n```sh\n# use it:\nclaude plugin marketplace add dumbspacecookie/stickies\nclaude plugin install stickies@stickies --scope user     # restart Claude Code after\n\n# work on it:\ngit clone https://github.com/dumbspacecookie/stickies\ncd stickies\nnpm test        # 27 suites, 558 assertions, no network\n```\n\nInstall once at user scope and it's in every project; per-project scoping is by `project_path` on\neach note, not a per-project install.\n\n---\n\n## How Stickies compares\n\nPersistent-notes-for-Claude-Code is a crowded space. Honestly:\n\n- **[Claude Code's built-in memory](https://code.claude.com/docs/en/memory)** — on by default, the\n  model decides what to save, no expiry, no importance tiers, no cross-project globals, per-repo\n  only. Stickies is the deterministic, human-authored, *expiring* alternative for people who turned\n  that off.\n- **Knowledge-graph / vector memory servers** (mem0, OpenMemory, `server-memory`, basic-memory) —\n  fuzzy retrieval over everything you've said. Different job. Stickies stores a small typed set,\n  not an embedding index.\n- **Hook-based memory plugins** — several exist, some excellent. Stickies' narrow bets are the ones\n  above: zero-turn `!!sticky` capture, importance-graded injection, a global tier that surfaces\n  across projects, and a Flow Board derived from your plan.\n\nIf you want auto-recall of your whole history, use one of those. Stickies is for a short,\ntrustworthy, self-pruning list — and a board you can glance at from your phone.\n\n---\n\nMIT · built by [dumbspacecookie](https://github.com/dumbspacecookie)\n",
  "bytes": 19805,
  "sha": "9e15e672925fa956ee3fe98f4f190cc600ff5ac888d96380a337d8c2b45d590c",
  "repo_slug": "dumbspacecookie/stickies",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_dumbspacecookie_stickies_4bb16afc/readme"
}