This is a submission for the Notion MCP Challenge
Every developer has a graveyard of half-remembered side projects.
You know the feeling. Someone asks "what have you been building?" during a job search and you blank. Or you're writing a performance review and can't reconstruct what you shipped in Q1. Or you're three months into learning to code and can't tell if you're getting better, which honestly stings more than the other two.
The problem isn't that you aren't building. It's that the work disappears into git history the moment it's committed.
I built DevPulse to fix that. And then I turned your git history into a game.
What I Built
DevPulse is a global Claude Code agent that automatically logs your coding sessions to Notion after every commit. It tracks your growth with XP and levels, maintains daily streaks, runs a 25-quest achievement system, and unlocks 30 achievement badges โ all triggered by a single slash command, from any project on your machine.
๐ฎ Async Queue System for Ad Insertion Engine
โก 100 base ร 1.5 (7-day streak) ร 1.25 (diff run) + 10 (daily spark) + 50 (Ship It quest) = 247 XP
๐ Total: 1,847 XP
๐ Level: Senior Dev โ Staff Engineer ๐
๐ฅ Streak: 8 days
๐
Badges Unlocked:
- Week Warrior โก (7-day streak!)
- Challenge Accepted โ๏ธ
โ๏ธ Quest Completed:
- Challenge Accepted (50 XP) โ 2 sessions this week at Difficulty 4+
โข Built async-safe queue with retry logic and exponential backoff โ no dropped frames under load
โข Logged to Master Dev Log ยท Profile updated: 14 sessions, 1,847 XP, Staff Engineer
โข Quests DB updated: Challenge Accepted โ Completed
No server. No backend to maintain. No manual journaling. You committed your code โ DevPulse reads the diff and handles everything else.
Who It's Actually For
I designed this for two people simultaneously, because I think they have the same core problem.
If you're learning to code: DevPulse makes the invisible visible. Every session logged is proof of work โ proof that you showed up and built something. The difficulty ratings go from 1 (config tweaks) to 5 (complex algorithms). You watch them climb as you grow. Your first month might be all 2s and 3s. Six months later you're cracking 4s and 5s and the XP reflects it. The streak system is the most important feature here: building the habit of shipping daily, even small things, is what separates developers who grow fast from those who plateau. And when you can't articulate what you've been working on? Pull up your weekly recap.
If you're an experienced developer: You already know how fast projects blur together. DevPulse gives you a structured, searchable record across every project on your machine โ filtered by stack, sorted by difficulty, summarized weekly. The weekly recap generates a Growth Narrative written from your actual data, not generic encouragement. It's also genuinely useful for performance reviews, resume updates, and the "so what have you been working on?" questions you get in every technical conversation.
The Growth Narrative
This is the feature I'm most proud of. Every /weekly-recap generates a Claude-written analysis of your actual week โ specific to your data:
"Backend-heavy week โ 4 of 5 sessions touched the database layer and your average difficulty climbed to 3.8, up from 2.6 last week. TypeScript was your most-used technology for the third week running. You logged sessions on 5 different days, your most consistent week yet. Next week: your streak hits 14 days โ push for Streak Legend."
That's not templated. That's Claude reading your Master Dev Log, spotting the pattern, and writing it back to you. It's a mirror that shows you your own growth in a way raw git logs never could.
The Architecture
The system runs as a global Claude Code configuration โ installed once to ~/.claude/, active in every project on your machine:
~/.claude/
โโโ CLAUDE.md โ DevPulse identity + XP formula + all 30 badge definitions
โโโ commands/
โโโ pulse-check.md โ /pulse-check workflow (11 sequential steps)
โโโ weekly-recap.md โ /weekly-recap workflow
โโโ monthly-recap.md โ /monthly-recap workflow
When you type /pulse-check, Claude loads the agent identity from CLAUDE.md and executes the 11-step workflow in pulse-check.md. Every operation that touches persistent state goes through Notion MCP โ there is no other storage layer.
The Four Notion Databases
DevPulse manages four databases entirely through MCP:
| Database | Purpose |
|---|---|
| Master Dev Log | One row per session โ title, stack, difficulty, XP, commit hash, badges |
| DevPulse Profile | Single-row state machine: streak, total XP, level, all badges earned |
| DevPulse Quests | 25 quests (13 weekly rotating + 12 permanent milestones) |
| DevPulse Recaps | Weekly and monthly recap pages with tech breakdown + growth narrative |
Three of these are auto-created on first run. The one you set up manually (Master Dev Log) is the source of truth โ DevPulse never deletes or modifies rows in it after they're written.
The Full Gamification Engine (V2)
I started with V1 (basic logging + 7 badges) and iterated to a full gamification system.
XP Multiplier Formula:
Session XP = floor((Difficulty ร 20) ร streak_mult ร diff_run_mult) + daily_spark + quest_bonus
-
streak_mult: 1.5ร at 7-day streak, 2ร at 30 days โ consistency is rewarded -
diff_run_mult: 1.25ร when two back-to-back sessions hit Difficulty โฅ 4 โ keeps you pushing hard -
daily_spark: flat +10 XP on your first session of the day -
quest_bonus: bonus XP from any quests completed this session - Combined multiplier cap: 3.0ร โ no runaway math
25-Quest System:
- 13 weekly quests rotate every Monday: Ship It, Deep Work, Consistency Check, Stack Master, Challenge Accepted, Bug Hunter, Early Bird, Polyglot Week, and more
- 12 permanent milestone quests: Century Club, Perfectionist, Streak Legend, Tech Specialist, Versatile, and more
- Quest completion writes to the Quests DB and adds XP to the current session's total
30 Achievement Badges across three groups โ from First Flame (session 1) through Diamond Coder (30-day streak), Deep Diver (three Difficulty-5 sessions in 7 days), Full Stack (frontend + backend in one session), and Achievement Hunter (15+ badges earned).
Show Us the Code
๐ GitHub: github.com/puginator/devlog
The distributable config lives in claude-config/. Here's what makes the system tick:
claude-config/CLAUDE.md โ The Agent Identity
This file ships the XP formula, difficulty rubric, level thresholds, and all 30 badge definitions into Claude's context on every session. The badge definitions are the most interesting part โ they reference in-memory values computed earlier in the same session:
## Badge Definitions
Badge checks use post-Step-8 streak value, Total Sessions = Profile Total Sessions + 1,
and provisional Total XP.
| Label | Condition |
|---|---|
| Multiplier | Session where streak_mult โฅ 1.5 AND diff_run_mult = 1.25 AND daily_spark was applied |
| Deep Diver | 3+ sessions with Difficulty = 5 in any rolling 7-day window |
| Full Stack | Session Stack contains โฅ 1 frontend AND โฅ 1 backend technology |
| Achievement Hunter | 15+ badges in Profile Badges Earned |
The hard constraints section is what makes the system reliable across sessions:
## Hard Constraints
- Never hallucinate Notion properties โ stop and report errors exactly
- Never log empty sessions (no meaningful changes = decline and explain)
- Badge checks are idempotent โ compare against Badges Earned in Profile before announcing
- Quest evaluation is idempotent โ check Completed On before awarding quest XP; if set, skip
- Stack always written as an array of strings โ never a comma-separated string
- Difficulty run query always executes before Step 6 to read the previous session only
claude-config/commands/pulse-check.md โ The Core Workflow
11 steps executed in sequence. A few highlights:
Step 1b โ Duplicate check (prevents double-logging the same commit):
If the commit hash is NOT "uncommitted": search Master Dev Log for an existing row
where Commit Hash matches this hash. If found: stop and say "Already logged commit
[hash] โ make a new commit before running Pulse Check again!"
Step 4b โ XP multiplier computation (pure in-memory, no Notion reads):
streak_mult:
- 7โ29 days โ 1.5
- 30+ days โ 2.0
- Otherwise โ 1.0
diff_run_mult:
Query most recent Master Dev Log row (sort Date descending, limit 1). Read Difficulty.
- If previous Difficulty โฅ 4 AND current Difficulty โฅ 4 โ 1.25
- Otherwise โ 1.0
combined_mult = min(streak_mult ร diff_run_mult, 3.0)
daily_spark = +10 XP if Last Active Date โ today
provisional_xp = floor((Difficulty ร 20) ร combined_mult) + daily_spark_xp
Step 9b โ Quest evaluation (runs after the session row is written):
Each active quest has a specific condition evaluated against the session and Master Dev Log:
-
Ship It (50 XP): 3+ sessions logged this ISO week -
Deep Work (50 XP): current session Difficulty = 5 -
Challenge Accepted (50 XP): 2+ sessions this week at Difficulty โฅ 4 -
Bug Hunter (50 XP): 2+ sessions this week where Commit Message contains "fix" or "bug" -
Consistency Check (50 XP): sessions logged on 3+ different days this week
Completed quests update in the Quests DB, add to quest_bonus, and the session row's XP Earned is patched with the final total.
Step 6 โ Automatic V1โV2 schema migration:
Before writing the row, verify Master Dev Log has the `XP Earned` (Number) and
`Commit Message` (Rich Text) properties. If either is missing, add it using
notion_update_database before proceeding.
Zero manual Notion work to upgrade. DevPulse detects missing columns and adds them on the first V2 run.
claude-config/commands/weekly-recap.md โ The Recap Generator
The weekly recap queries 7 days of Master Dev Log rows and writes a Notion page. The Growth Narrative step is where it gets interesting:
## Step 6 โ Growth Narrative
Write a 3โ4 sentence analysis of the week. Must reference actual data (most-used stack,
difficulty trend, project focus, streak status). Must include one specific pattern
observation (e.g. "Backend-heavy week โ 3 of 5 sessions touched the database layer").
Must end with a forward-looking callout for next week.
Claude isn't filling in a template โ it's reading your actual session data, identifying the pattern, and writing it back as analysis.
How I Used Notion MCP
Notion MCP is the entire backend of DevPulse. Every piece of state lives in Notion. Claude reads and writes through @notionhq/notion-mcp-server โ there's no local database, no config file, no server of any kind.
Here's every MCP operation the system uses:
notion_search โ Database discovery
Every workflow starts by finding its databases by name:
notion_search("Master Dev Log") โ session logging
notion_search("DevPulse Profile") โ XP, streak, badges
notion_search("DevPulse Quests") โ active quests
notion_search("DevPulse Recaps") โ weekly/monthly summaries
This is what makes DevPulse portable. The databases can live anywhere in your Notion workspace.
notion_query_database โ Precise filtered reads
The quest system and badge checks require querying Master Dev Log with specific filters:
# Sessions this ISO week (quest evaluation)
filter: { Date: { on_or_after: "2026-03-16", on_or_before: "2026-03-22" } }
# Previous session only (diff_run_mult)
sorts: [{ property: "Date", direction: "descending" }], page_size: 1
# All Difficulty-5 sessions (Deep Diver badge, Hardcore badge)
filter: { Difficulty: { equals: 5 } }
# Active quests only
filter: { Status: { equals: "Active" } }
notion_create_page โ Writing session data
notion_create_page(
parent: { database_id: master_dev_log_id },
properties: {
"Session Title": "Async Queue System for Ad Insertion Engine",
"Project": "ad-engine",
"Stack": ["TypeScript", "Node.js", "Redis"], โ always an array, never a string
"Difficulty": 4,
"XP Earned": 247,
"Date": "2026-03-19",
"Commit Hash": "a3f9b2c",
"Commit Message": "feat: implement async ad queue with retry logic"
}
)
Stack is always written as an array of strings โ a hard constraint in CLAUDE.md because early versions wrote "TypeScript, React" as a single value, which broke the tech frequency aggregation in weekly recaps.
notion_update_page โ State management
After writing the session, DevPulse updates the Profile and patches the session row if quests completed:
# Profile update
notion_update_page(profile_row_id, {
"Current Streak": 8,
"Total XP": 1847,
"Current Level": "Staff Engineer",
"Badges Earned": ["First Flame", "Bug Slayer", "Week Warrior", "Challenge Accepted"],
"Last Active Date": "2026-03-19"
})
# Session row patched with final XP after quest bonuses resolved
notion_update_page(session_row_id, { "XP Earned": 247 }) โ was 187 before quest bonus
# Quest marked complete
notion_update_page(quest_row_id, { "Status": "Completed", "Completed On": "2026-03-19" })
notion_update_database โ Schema migration
V1โV2 upgrade adds missing columns automatically:
notion_update_database(master_dev_log_id, {
"XP Earned": { number: {} },
"Commit Message": { rich_text: {} }
})
Runs once, on the first V2 /pulse-check, only if the columns don't exist.
Auto-creating databases on first run
If DevPulse Profile or DevPulse Quests don't exist, Claude creates them with the full schema and seeds all 25 quests in a single batch โ 12 milestone quests as Active rows, plus 3 weekly quests timed to the current week's deadline.
Why Notion MCP Was the Right Choice
DevPulse works because Notion is actually a real relational database, not just a note-taking app. Filtering by date, sorting by difficulty, updating specific properties, running schema migrations โ all the things you'd normally need a backend for are just Notion API calls.
@notionhq/notion-mcp-server gives Claude direct access to every Notion operation from inside the conversation context. No server needed. The entire DevPulse backend is: Claude + a markdown config file + MCP.
The MCP interface is the key piece. Without it, I'd need a server to broker requests between Claude and the Notion API. With @notionhq/notion-mcp-server, Claude has direct access to every Notion operation from inside the conversation context. The entire DevPulse backend is: Claude + a markdown config file + MCP. That's it.
DevPulse is open source and works for anyone with Claude Code. Clone the repo, run setup.sh, and your first /pulse-check sets everything up automatically โ including writing your first entry to Notion and starting your streak at day 1.
If you're just starting to code, that first entry is going to mean more than you think it will six months from now.
Top comments (0)