daybook-mcp
by successaje
README.md
# daybook-mcp
Local-first tooling for logging daily activities and generating daily
summaries, weekly article ideas, and platform-specific social posts from
those logs — through Claude.
Single-user, no hosting, no auth. Storage is a single SQLite file at
`~/.daybook/daybook.db`, created on first run.
This is an npm workspaces monorepo with three packages:
- **[`packages/core`](./packages/core)** — `@daybook/core`. The shared
SQLite schema, queries, voice loading, and platform tone rules. Not used
directly; both interfaces below depend on it.
- **[`packages/mcp-server`](./packages/mcp-server)** — `daybook-mcp`, a
stdio MCP server. Register it once with your MCP host and its tools show
up automatically — but the host has to be restarted to pick up a newly
registered server.
- **[`packages/skill`](./packages/skill)** — `@daybook/skill`, a Claude
Code Skill that exposes the identical functionality through a small
bundled CLI instead of MCP tool calls. Loads instantly via the Skill
tool, no restart needed. Same database, same schema — use whichever
fits your session.
## Setup
```bash
npm install
npm run build
```
This builds all three packages (`core` first, since the other two depend
on it).
## Using the MCP server
Register it with Claude Code:
```bash
claude mcp add daybook -- node /path/to/daybook-mcp/packages/mcp-server/dist/index.js
```
This writes the server entry into Claude Code's own config — `~/.claude.json`
under this project's entry, not a file in this repo — so there's nothing
to commit for it, unlike the skill's `.claude/skills/daybook` symlink
(see "Using the skill" below).
Or add to Claude Desktop's `claude_desktop_config.json`:
```json
{
"mcpServers": {
"daybook": {
"command": "node",
"args": ["/path/to/daybook-mcp/packages/mcp-server/dist/index.js"]
}
}
}
```
**Note:** MCP hosts load registered servers at session startup, so after
registering (or after `packages/mcp-server` code changes and a rebuild),
start a new session before the tools appear.
## Using the skill
The repo ships a symlink at `.claude/skills/daybook` pointing at
`packages/skill`, so if you clone this repo and open it in Claude Code,
the skill is auto-discovered — no registration step. To use it from a
different project, copy or symlink `packages/skill` into that project's
own `.claude/skills/<name>/` directory instead.
Either way, once it's built (`npm run build`, which also builds the CLI to
`packages/skill/scripts/cli.js`), it's available immediately — no restart.
## Usage
Once either interface is set up, just talk to Claude normally. You don't
need to name tools or commands — describe what you want:
- **"Log that I fixed the flaky auth test today"** — logs an activity note.
- **"What did I get done this week?"** — fetches raw entries for a range.
- **"Summarize my day"** — pulls today's entries, drafts a short recap in
your configured voice, and stores it.
- **"Draft a tweet about today"** / **"turn this week into a LinkedIn
post"** — pulls the relevant entries/summaries, drafts a post following
that platform's tone rules, and stores it as a draft for your review.
- **"Show me my drafts"** / **"mark draft 3 as posted"** — list and update
stored drafts.
- **"Give me a weekly review"** — reads the last 7 days of summaries and
proposes the single strongest article angle from the week, as a title +
bullet outline. This is exploratory and is never saved automatically.
Because the generation tools are two-phase (see below), you'll see Claude
fetch material first, draft the text itself in your voice, then store it —
rather than a black box handing back finished text. That's deliberate: you
can watch it happen and redirect mid-draft if the tone is off.
### Proactive milestone suggestions
You don't have to remember to ask for a post. Whenever something logged
represents a completed feature, a resolved hard problem, a shipped
release, or another genuine milestone — not routine progress — Claude is
instructed to flag it and tell you, unprompted, that it seems worth a
post: which platform fits and why, in a line or two. It then waits for you
to say yes before drafting anything, and it never posts on your behalf —
copying, editing, and actually publishing the finished draft stays
entirely your call.
This works the same way in both interfaces: the MCP server advertises it
as standing server `instructions` (plus in `log_entry`'s own description),
and the skill carries the identical guidance in `SKILL.md`. Milestone
entries are stored with a flag (`milestone: true` / `--milestone`) so they
also surface prominently — marked `★ MILESTONE` — in `generate_post`
material and in `weekly_review`, which weighs them heavily when picking
the week's strongest angle. You can also flag something as a milestone
after the fact with `flag_milestone` / `flag-milestone <entry_id>`, if its
significance only becomes clear later.
## Tools / commands
Both interfaces expose the same nine operations:
- `log_entry` / `log` — log a raw activity note. Accepts an optional
`milestone` flag for genuinely significant work (see above).
- `flag_milestone` / `flag-milestone` — retroactively mark an existing
entry as a milestone.
- `get_entries` / `entries` — fetch raw entries in a date range.
- `generate_daily_summary` / `summary` — two-phase: call without the
drafted text to get the day's entries plus drafting instructions; call
again with the text to store it.
- `generate_post` / `post` — two-phase, same pattern. Platform is `x`,
`medium`, or `linkedin`, each with its own tone rules.
- `list_drafts` / `drafts` — list stored drafts, optionally filtered by
`draft`/`posted`.
- `mark_posted` / `mark-posted` — flip a draft's status to `posted`.
- `weekly_review` / `review` — pulls the last 7 days of summaries and asks
you to identify the week's strongest article angle as an outline.
Nothing is stored; the outline is just the reply.
The two-phase design exists because MCP's server-initiated "sampling"
isn't yet supported by Claude Code or Claude Desktop — so instead of the
server calling an LLM itself (which would need a separate API key), the
tool hands back the raw material and lets the Claude you're already
talking to do the writing, then a second call persists it.
## Voice
Edit [`voice.md`](./voice.md) at the repo root to tune the authorial voice
used across summaries and posts — both interfaces read from the same file.
Platform-specific tone rules (length, formality) live in
[`packages/core/src/prompts.ts`](./packages/core/src/prompts.ts).
## Why Node, not Bun
`better-sqlite3`'s native binding doesn't load under Bun's runtime yet. The
project uses Node instead (Node 22+ can run the TypeScript sources directly
via `node --experimental-strip-types`, or build with `npm run build` and
run the compiled output).
## Contributing
Contributions are welcome — bug fixes, new platform tone rules, additional
commands, whatever's useful. See [CONTRIBUTING.md](./CONTRIBUTING.md) for
the project layout, dev setup, and how to keep the MCP server and the
skill in sync when adding a capability.
## License
MIT — see [LICENSE](./LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessUnresponsive