Claude Code journal plugin: Notion session summaries at a glance
Last month I wrote about the year my notes turned into breadcrumbs, and the small Claude Code skill, /journal, that I built on May 18 to dig my way out. It finds or creates today's page in my Notion work journal and appends a summary of the session I just finished. I have run it between working sessions almost every day since.
This week I turned it into a plugin anyone can install: cseeman/claude-journal. Here is what it does, what changed from the version in that post, and how to set it up.
What an entry looks like
The May version wrote a gray callout with a robot icon and a paragraph inside it. After three months the paragraphs had grown to between 100 and 180 words each, with full URLs repeated as link text and the follow-ups buried mid-sentence. Nothing was missing from them, and I could not find anything in one without reading all of it.
The plugin writes one callout per topic, shaped like this:
<strong>Reworked /journal: seasonal callouts, structured entries, fixed monthly view</strong>
~/.claude/skills/journal/SKILL.md ยท today.sh
Callout color now follows the season and the icon the weekday, computed in today.sh so the model does no lookup.
Fixed the monthly index view call, which was missing parent_page_id, and set allow_async: falseon every write.
Entries now use a headline, a metadata line, and fact bullets, one callout per topic, about 80 words.
Next: watch the first few entries for vague headlines or bullets cut too short
That is the real entry from the session where I built this, copied out of Notion. The rules behind it are short: a bold headline stating the outcome in the past tense, a metadata line linking every ticket, PR, and branch touched with the identifier as the link text, at most four one-sentence bullets, and follow-ups on their own line prefixed Next: or Open:. About 80 words. If a session covered two unrelated things, it writes two callouts.
The rule I care about most bans narrated reasoning. Phrases like "rather than shipping a drive-by" or "worth raising with the team" are the model justifying itself, and they were the bulk of the old paragraphs. A reason that matters becomes its own bullet, stated as a fact.
Color by season, icon by weekday
I got bored of the gray robot. Every entry looked the same, so a month of pages gave no sense of time when I scrolled it.
Now the callout background follows the season and the icon follows the day of the week. The icons are the classical namesakes of the days, which gave me a set that is easy to remember and visually distinct. Plus, it pretty.
| Season | Color | | Weekday |Icon|
|--------|--------|--|-----------|----|
| Winter | blue | | Monday | ๐ |
| Spring | green | | Tuesday | โ๏ธ |
| Summer | yellow | | Wednesday | ๐ชถ |
| Autumn | orange | | Thursday | โก |
| | | | Friday | ๐ธ |
| | | | Saturday | ๐ช |
| | | | Sunday | โ๏ธ |
I built this on a Wednesday in September, so the entry above landed as an orange callout with a feather. Both are computed by a shell script that runs before the skill loads, so the model receives the finished values and never consults a table. That is for speed. The skill runs between sessions, and on a normal day it makes exactly three Notion calls: search for today's page, fetch it, append.
Setup
You need Claude Code and the Notion MCP server.
claude mcp add --transport http notion https://mcp.notion.com/mcp
Install the plugin from inside Claude Code:
/plugin marketplace add cseeman/claude-journal
/plugin install journal@cseeman
Create a Notion database with three properties: a title called Name, a multi-select called Tags with the options Work, Daily, and Monthly, and a date called Start Date. Then find the database's data source id by asking Claude to fetch the database URL through the Notion MCP. The response includes a collection://<uuid> line, and the uuid is what you want.
Write it to a config file:
# ~/.config/claude-journal/config
JOURNAL_DATA_SOURCE_ID="<uuid>"
If your Notion MCP server is not aliased notion, add JOURNAL_MCP_SERVER="<alias>" on a second line. I have two Notion servers, one for work and one personal, so mine says notion_personal. The same file takes JOURNAL_HEMISPHERE="south" to flip the seasons, and JOURNAL_COLORS and JOURNAL_ICONS if you want a different palette. Nothing in the plugin cache needs editing, so updates never overwrite your choices.
Using it
/journal on its own composes the entry from the session. The first run each month also creates a monthly index page holding a filtered view of that month's daily pages.
/journal <text> uses your text as the bullets and still writes the headline and metadata line. I use that when I know what I want recorded and do not want the model deciding.
What building the plugin turned up
Two things surprised me. The first is how much a review found in a skill I had run daily for three months. The review-skill command from our internal plugin-expert plugin flagged that the monthly index step called the Notion view tool without a required parameter. It had worked for three months only because the model guessed the parameter from context each time. It also caught that both write tools default to running asynchronously, which meant my verification step could run before the write landed. Neither had produced a visible error ๐คท๐ปโโ๏ธ
The second is that the personal version was not shareable at all. The database id and my MCP server alias were hardcoded, and the pre-approved tool names embedded that alias. Moving everything into a config file that the shell script reads took an hour, and it is the reason the plugin can work for anyone with a Notion journal.
The skill file went from 123 lines to 97 in the process. Every line that stayed is one the model acts on when it composes an entry. Enjoy! I know I have been loving the glow up.
Top comments (0)