Skip to main content
Glama

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 at http://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.py

Fully 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 auto

Cron 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 mcpServers registration 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_task

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).

update_task_status

Change a task's status (done, in_progress, blocked).

get_tasks_by_date

View tasks for a specific date. Optional tag filter.

get_tasks_between

View tasks across a date range. Optional tag filter.

list_tags

See all tags in use with open task counts.

generate_standup_report

Slack-ready standup message. Set include_weekly=True for a 7-day rollup.

Tags get a consistent royal-themed emoji (👑💎🦋🕯️ etc.) assigned automatically per tag name.

Checklist dashboard — what you need to do

Tool

Description

add_checklist_item

Add a task (or subtask) to the checklist. Supports nested subtasks.

delete_checklist_item

Remove a task by ID (recursively deletes nested subtasks).

toggle_checklist_item

Toggle done/not-done.

update_task_due_date

Set, change, or clear a task's due date without touching its status, tag, or log date.

get_checklist

View all tasks as a checklist.

open_checklist_dashboard

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.py

Only binds to localhost — not exposed to the network.


Testing in Claude Desktop

Try these:

  1. "Log that I finished the login screen styling."

  2. "Log that I'm blocked on AWS permissions, tag it infra."

  3. "Log that the API docs are due Friday, tag it github."

  4. "What have I logged for today?"

  5. "Generate my standup report."

Permission Prompt Log Example Log Example

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), never print().

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 tools
add_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

    A3.9/5.0

    Scored across 13 tools

    Disambiguation4/5

    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.

    Naming Consistency4/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers