Skip to main content
Glama
README.md
# 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.

## Following Along (YouTube Tutorial)

This project follows [MCP Tutorial: Build Your First MCP Server](https://www.youtube.com/watch?v=jLM6n4mdRuA), adapted for `uv` and the current v2 SDK.

### Step 1: Initialize the project

```bash
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

```bash
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`:

```json
"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:

```json
{ "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:

```bash
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.

```bash
# 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](mcppermissions.png)
![Log Example](logmcpexample.png)
![Log Example](logmcpexample1.png)

Verify data directly:

```bash
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](https://modelcontextprotocol.io/docs/2026-07-28/develop/connect-local-servers), [Claude MCP troubleshooting](https://claude.com/docs/connectors/building/mcp-apps/troubleshooting), [PyPI MCP](https://pypi.org/project/mcp/)

---

## License

Released under the [MIT License](LICENSE) — free to use, modify, and distribute with attribution and no warranty.

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

ActivityMaintained
ResponsivenessNo issues