standup-journal-mcp
A personal standup journal and checklist manager exposed as an MCP server, letting Claude or an agent log tasks, track statuses/tags/due dates, generate standup reports, and manage an interactive checklist dashboard.
Log work items with natural-language status normalization (
done,in_progress,blocked), optional tags, and due dates (log_task)Update tasks after the fact: change status, edit/clear tags, or set/change/clear due dates without rewriting history (
update_task_status,update_task_tag,update_task_due_date)Query the journal by a single date or a date range, optionally filtered by tag (
get_tasks_by_date,get_tasks_between)List tags in use with open task counts (
list_tags)Generate standup reports for yesterday/today or a weekly rollup, grouped by tag/project (
generate_standup_report)Manage a checklist backed by the same task store: add items with nested subtasks, delete items, toggle done/not-done, and view all tasks grouped by status (
add_checklist_item,delete_checklist_item,toggle_checklist_item,get_checklist)Open an interactive local dashboard at
http://localhost:9249with progress bar, subtasks, due dates, and tag badges (open_checklist_dashboard)
Generates Slack-ready standup reports summarizing logged tasks for a specific date range or a 7-day weekly rollup.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@standup-journal-mcp Generate my standup report for today."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Standup Journal MCP
A personal standup journal as an MCP server — log tasks, generate standup reports, and manage a checklist dashboard, all from Claude Desktop.
One Dataset, Two Views
The standup log tools and the checklist dashboard both read from and write to the same underlying task table — they are not separate stores. An item logged with log_task shows up in get_checklist and the dashboard, and vice versa, using the same task IDs.
Standup log tools (
log_task,get_tasks_by_date,get_tasks_between,generate_standup_report) present tasks as a dated journal — good for "what did I do on Aug 12" or generating a Slack-ready standup message.Checklist dashboard (
get_checklist,add_checklist_item,toggle_checklist_item,delete_checklist_item,open_checklist_dashboard) presents the same tasks as a checkable to-do list athttp://localhost:9249.
In short: it's one list of tasks, viewable either as a standup journal or as a checklist — pick whichever framing suits what you're trying to do in the moment.
Related MCP server: work-tracker-mcp
Following Along (YouTube Tutorial)
This project follows MCP Tutorial: Build Your First MCP Server, adapted for uv and the current v2 SDK.
Step 1: Initialize the project
uv init
uv add "mcp[cli]"Step 2: Write the server
Create main.py in the project root. The server uses MCPServer from mcp.server with @mcp.tool() decorators.
Note: The video uses FastMCP from mcp.server.fastmcp (v1.x SDK). uv add "mcp[cli]" today installs v2, where FastMCP was renamed MCPServer and moved to mcp.server. Decorators are unchanged.
Data lives in ~/.standup-journal/standups.db (override with STANDUP_DB_PATH).
Step 3: Install into Claude Desktop
uv run mcp install main.pyFully quit and reopen Claude Desktop for the server to appear.
Step 4: Verify in Claude Desktop
Open Settings → Developer → Edit Config to confirm standup-journal is listed under mcpServers. Restart Claude Desktop, then check Connectors — your tools should be available.
Connecting from a Kiro / KiroCrew scheduled job
A Kiro / KiroCrew agent can use this same MCP server the same way Claude Desktop does — you call the tools by asking in chat. It connects exactly the same way as Claude Desktop: the agent spawns the server over stdio using an identical mcpServers entry. On top of that, you can optionally schedule a KiroCrew cron job to wake the agent every weekday morning and auto-generate your standup — but that scheduling is an extra setup step, not something the server does by itself.
Step 1: Register the server on your Kiro agent
Add the same entry Claude Desktop uses to your agent config (~/.kiro/agents/<agent>.json) under mcpServers:
"standup-journal": {
"command": "/opt/homebrew/bin/uv",
"args": [
"run", "--frozen",
"--with", "mcp[cli]==2.0.0",
"mcp", "run",
"/Users/you/standup-journal-mcp/main.py"
]
}Then allow the agent to call the tools by adding "@standup-journal" to the agent's tools and allowedTools arrays, and a permissions rule:
{ "capability": "mcp", "match": ["standup-journal/*"], "effect": "allow" }This is byte-for-byte the same launch command as the Claude Desktop connector — the only difference is whether Claude Desktop or a Kiro Crew agent spawns it. Because the data lives in ~/.standup-journal/standups.db, Kiro Crew and Claude Desktop see the same task list.
Step 2: Schedule the standup
Create a recurring job that wakes the agent to produce your standup. From the KiroCrew dashboard or CLI:
kirocrew cron add "Daily Standup Report" \
"Generate my standup report using the standup-journal generate_standup_report tool and send it to me." \
--agent kirocrew \
--cron "0 9 * * 1-5" \
--approval-mode autoCron expressions are evaluated in your machine's local timezone, so 0 9 * * 1-5 fires weekdays at 9:00 AM local. --approval-mode auto lets the unattended job call the tools without a prompt. Manage it later with kirocrew cron list, kirocrew cron trigger <id> (run once now), or kirocrew cron pause <id>.
The job wakes the agent on schedule, the agent connects to the standup-journal MCP server the same way Claude Desktop does, calls generate_standup_report, and delivers the result to you.
Note: a Kiro scheduled job is a different mechanism from an MCP connector — the job is what wakes the agent on a timer, and the
mcpServersregistration is what lets that agent reach these tools. You need both: the registration (Step 1) makes the connection "the same way Claude Desktop does," and the cron (Step 2) is what points a schedule at it.
Tools
Standup log — what you did / are doing / are blocked on
Tool | Description |
| Log what you did/are doing/are blocked on. Supports tags, due dates, deduplicates recurring blockers, and normalizes natural-language statuses (e.g. "todo" → in_progress). |
| Change a task's status (done, in_progress, blocked). |
| View tasks for a specific date. Optional tag filter. |
| View tasks across a date range. Optional tag filter. |
| See all tags in use with open task counts. |
| Slack-ready standup message. Set |
Tags get a consistent royal-themed emoji (👑💎🦋🕯️ etc.) assigned automatically per tag name.
Checklist dashboard — what you need to do
Tool | Description |
| Add a task (or subtask) to the checklist. Supports nested subtasks. |
| Remove a task by ID (recursively deletes nested subtasks). |
| Toggle done/not-done. |
| Set, change, or clear a task's due date without touching its status, tag, or log date. |
| View all tasks as a checklist. |
| Get the localhost URL for the interactive HTML dashboard. |
Due dates are parsed from natural language by Claude (e.g. "due Aug 20"). In the dashboard, a due date only appears next to a task once one is set — undated tasks show nothing. Click the 📅 icon on any task to set or edit its due date directly. Tasks with due dates sort to the top; overdue dates show in red.
Interactive Checklist Dashboard
The server starts a local HTTP server on port 9249 (override with CHECKLIST_PORT) alongside the MCP stdio transport. The dashboard at http://localhost:9249 provides an interactive checklist with a progress bar, nested subtasks, due dates, and tag badges. Use it as your working to-do list — items you still need to do, not a record of what's already happened.
The progress bar reflects all-time completion (done tasks ÷ total tasks), not just a recent window — so finishing an older item always moves it. It's a plain sliding bar by design, with no numeric done/in-progress/blocked counts shown alongside it.
# Run standalone (starts MCP server + dashboard)
uv run python main.py
# Custom port
CHECKLIST_PORT=8080 uv run python main.pyOnly binds to localhost — not exposed to the network.
Testing in Claude Desktop
Try these:
"Log that I finished the login screen styling."
"Log that I'm blocked on AWS permissions, tag it infra."
"Log that the API docs are due Friday, tag it github."
"What have I logged for today?"
"Generate my standup report."

Verify data directly:
sqlite3 ~/.standup-journal/standups.db "SELECT * FROM tasks;"Troubleshooting
Connector won't connect: Check
~/Library/Logs/Claude/mcp-server-standup-journal.log(macOS) or%APPDATA%\Claude\logs\(Windows).Stray stdout corrupts the connection — use
logging(stderr), neverprint().
Sources: MCP docs, Claude MCP troubleshooting, PyPI MCP
License
Released under the MIT License — free to use, modify, and distribute with attribution and no warranty.
Available Tools
13 toolsadd_checklist_itemA
Add a task to the checklist. Set parent_id to nest it as a subtask under an existing task.
Inputs: title (required), parent_id. Returns: result
delete_checklist_itemA
Delete a task from the checklist by ID, including all nested subtasks.
Inputs: item_id (required). Returns: result
generate_standup_reportA
Generate a clean, bulleted standup message from yesterday and today.
Automatically groups items by tag/project if any logged tasks have one.
Set include_weekly=True to append a rollup covering the last `range_days`
days (default 7). The rollup follows the standard three-question standup
format — Done / In Progress / Blocked — for that whole period, not just
completed items, so it works for a weekly retro, a 1:1, or any custom
stretch of time by adjusting range_days.
Uses standard Markdown (**bold**, _italic_, - bullets) so it renders
cleanly in Claude's chat UI. If pasting into Slack, swap ** for single
* around headers (Slack uses single asterisks for bold).
Inputs: range_days, include_weekly. Returns: result
get_checklistA
Get all tasks as a checklist view, grouped by status.
Inputs: no named parameters. Returns: result
get_tasks_betweenA
Retrieve all logged tasks within an inclusive date range (YYYY-MM-DD each).
Use this for "what did I do last week" style questions instead of
calling get_tasks_by_date multiple times. Optionally filter to a single
`tag`/project.
Inputs: end_date (required), start_date (required), tag. Returns: result
get_tasks_by_dateA
Retrieve all logged tasks for a given ISO date (YYYY-MM-DD).
Optionally filter to a single `tag`/project.
Inputs: log_date (required), tag. Returns: result
list_tagsA
List all distinct tags/projects currently in use, with open task counts.
Inputs: no named parameters. Returns: result
log_taskA
Log a single piece of work: what you did, are doing, or are blocked on.
If the user gives a rambling, multi-item update in one message (e.g.
"finished the login screen, still working on the API integration, and
I'm blocked on AWS permissions"), call this tool ONCE PER DISTINCT ITEM
rather than logging it as one combined entry.
Infer `status` from the language used for each item:
- "done" -> finished, shipped, completed, past tense ("fixed", "wrote")
- "in_progress" -> still working on, in the middle of, ongoing, todo, to do, need to, planning to
- "blocked" -> blocked, stuck, waiting on, can't proceed until
IMPORTANT: Always normalize status to exactly one of: "done", "in_progress", "blocked".
Never use "todo", "to do", "in progress" (with space), or any other variant.
`tag` is an optional project/category label (e.g. "frontend", "acme-client",
"customer-advisor", "infra", "github"). Set it whenever the user's phrasing implies
a category, using any of these patterns:
- "log ___ under/as/for [category]"
- "tag this as [category]"
- "categorize/sort this as [category]"
- simply mentioning a known project/client name in the task description
Each distinct tag automatically gets a consistent colored-circle emoji
in every response, so tasks stay visually grouped by category over time.
If no category is stated or inferable from context, leave `tag` unset.
`due_date` is an optional ISO date (YYYY-MM-DD) deadline. Set it whenever
the user mentions a due date, deadline, or "by [date]" in their message.
Parse natural language dates (e.g. "due Friday", "by next week", "due Aug 21")
into ISO format.
If `status` is "blocked" and there's already an open blocker with a very
similar description, this updates that existing entry's date instead of
creating a duplicate — so a recurring blocker doesn't pile up as
multiple rows across days.
Inputs: task_description (required), tag, status, due_date. Returns: result
open_checklist_dashboardA
Launch the interactive task checklist in the browser.
Use this whenever the user wants to view, manage, or work through their tasks interactively — whether they're starting their day, checking what's left, or asking about what to do next.
Returns a localhost URL. Data persists across sessions.
Inputs: no named parameters. Returns: result
toggle_checklist_itemB
Toggle a task between done and not done.
Inputs: item_id (required). Returns: result
update_task_due_dateA
Change the due date on an existing logged task, without altering its log_date, status, description, tag, or ID.
Use this whenever the user wants to set, change, or clear a due date on
a task they already logged — e.g. "the behavioral stories task is due
today EOD" or "push #12's due date to Sept 1" or "clear the due date on
#7". This is the correct tool for that; do NOT delete and re-log the
task, since that rewrites its original log_date and loses history.
`due_date` must be an ISO date (YYYY-MM-DD). Parse natural language
dates (e.g. "today", "EOD today", "Friday", "next week") into ISO
format before calling this — relative phrasing stored as-is will not
sort or display correctly in the checklist dashboard.
Pass due_date=None (or an empty string) to clear an existing due date.
Inputs: task_id (required), due_date (required). Returns: result
update_task_statusA
Update the status of an existing logged task (e.g. unblock it).
Use this when the user says a previously logged item has changed state
— e.g. a blocker just got resolved, or something in progress is now
done. `status` must be one of: "done", "in_progress", "blocked".
Inputs: status (required), task_id (required). Returns: result
update_task_tagA
Change the tag on an existing logged task, without altering its log_date, status, description, or ID.
Use this whenever the user wants to retroactively add, change, or
remove a category/tag on a task they already logged — e.g. "tag #12
as infra" or "remove the tag from #7". This is the correct tool for
that; do NOT delete and re-log the task, since that rewrites its
original log_date and loses history.
Pass tag=None (or an empty string) to clear an existing tag.
Note: if the task has subtasks (other tasks tagged "subtask:<task_id>"),
those are untouched by this call — only task_id's own tag changes.
Inputs: tag (required), task_id (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 13 tools
Most tools have clearly distinct purposes, and the descriptions carefully separate journal tasks from checklist items. However, log_task vs add_checklist_item and update_task_status vs toggle_checklist_item could cause confusion when a user simply says 'add a task' or 'mark this done' without clarifying which store they mean.
Tool names mostly follow a consistent verb_noun snake_case pattern like update_task_status, get_tasks_by_date, and delete_checklist_item. The main inconsistency is the mixing of 'task' and 'checklist_item' terminology without a clear prefix to distinguish the two domains, plus the less patterned generate_standup_report and open_checklist_dashboard.
Thirteen tools is well within the ideal range for a focused server. Each tool earns its place: seven support journal logging and reporting, five cover checklist management, and one launches the interactive dashboard.
The journal and checklist domains both have solid create/read/update coverage, and the dashboard fills an interactive role. The notable gap is that logged journal tasks cannot be deleted or have their description edited, which could leave an agent unable to fully correct a mislogged entry.
Maintenance
Related MCP Connectors
timesheet.io MCP server - manage timers, projects, tasks and reports
Toggl 2.0 MCP server for tasks, projects, time entries, and workspace operations.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for structured daily work diary management, enabling entries, standup summaries, weekly reports, full-text search, and automatic git commits.1455 PyPIMIT
- FlicenseAqualityDmaintenanceMCP server that tracks what you are working on. Logs are stored locally as one markdown file per day on your Desktop.5-
- FlicenseBqualityDmaintenanceA task manager MCP server that enables creating, reading, updating, and deleting tasks persisted in a local JSON file.4-
- AlicenseBqualityCmaintenanceA basic MCP server for managing a todo list stored in a local JSON file, enabling task creation, completion, listing, and daily summary generation.25 npmMIT