Skip to main content
Glama
Rithvickkr

worklog-telegram

by Rithvickkr
README.md
# Work log → Telegram

## What this is

MCP server that logs what you got done throughout the day via a `log_work`
tool, keeping one Markdown file per day with entries grouped by project. The
day's log goes to Telegram two ways: automatically at 11 PM, or on demand when
you ask Claude to send it.

## Architecture

- `server.py` — MCP server. Two tools: `log_work(entry, project)` files a
  bullet under `## <project>` in `logs/<date>.md`; `send_summary(day)` posts
  that day's log to Telegram on request.
- `send.py` — standalone script, reads a day's log, posts to Telegram.
  Also the shared implementation the MCP tool calls.
- Scheduled via Windows Task Scheduler at 11 PM daily (`register-task.ps1`)
- `~/.claude/CLAUDE.md` — the parent prompt telling Claude to log as it works,
  in every project

The scheduled task only needs `send.py`, so the nightly summary keeps
working even when no MCP server is running. That script is stdlib-only for the
same reason — the task doesn't have to activate the virtualenv.

## Setup

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

Copy-Item .env.example .env   # then fill in the two Telegram values
```

## Telegram setup

Bot token and chat_id are obtained via BotFather + getUpdates:

1. Message [@BotFather](https://t.me/BotFather) → `/newbot` → copy the token.
2. Send your new bot any message (a bot can't start the conversation).
3. Open `https://api.telegram.org/bot<TOKEN>/getUpdates` and copy
   `result[0].message.chat.id`.
4. Put both in `.env` as `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID`.

`.env` is gitignored. The scheduled task reads it from disk, so real
environment variables aren't required — but if both are set, the environment
wins.

## Wiring the MCP server to Claude Code

```powershell
claude mcp add worklog -- "E:\Reels graphics\code logs\.venv\Scripts\python.exe" "E:\Reels graphics\code logs\server.py"
```

Or add it to `.mcp.json` by hand:

```json
{
  "mcpServers": {
    "worklog": {
      "command": "E:\\Reels graphics\\code logs\\.venv\\Scripts\\python.exe",
      "args": ["E:\\Reels graphics\\code logs\\server.py"]
    }
  }
}
```

Add it once at user scope (`claude mcp add --scope user ...`) so every project
logs to the same folder, not just this one.

## The parent prompt

Tool descriptions alone make logging optional. `~/.claude/CLAUDE.md` loads into
every session and carries the standing instruction:

- log after each meaningful unit of work, one call per item, `project` set to
  the working directory's name
- don't log routine steps, don't batch a whole session into one entry, don't
  ask permission first
- call `send_summary` when you ask for it, never unprompted

Edit that file to change the logging behaviour — it's the lever, not the tool
descriptions.

## Scheduling

```powershell
powershell -ExecutionPolicy Bypass -File .\register-task.ps1
```

Registers `WorkLogSummary` at 23:00 daily, running under your account while
logged on. Override with `-At "22:30"` or `-TaskName "..."`.

```powershell
Start-ScheduledTask -TaskName "WorkLogSummary"              # fire it now
Get-ScheduledTaskInfo -TaskName "WorkLogSummary"            # last run + result
Unregister-ScheduledTask -TaskName "WorkLogSummary" -Confirm:$false
```

The task passes `--skip-if-empty`, so days with no logged work send nothing.
Drop that flag in `register-task.ps1` if you'd rather get a "Nothing logged
today" ping as proof the job ran.

## Sending on demand

Just ask Claude — "send me today's log", "send it", "text me what I did
yesterday" — and it calls the `send_summary` tool. From the shell:

```powershell
python send.py --dry-run              # print, don't send
python send.py --date 2026-08-01      # re-send an older day
python send.py                        # send today's
```

## Log format

`logs/2026-08-02.md`:

```markdown
# 2026-08-02

## Reels graphics

- 09:14 Rebuilt the beat cards in comic style
- 11:02 Added project grouping to the daily log

## contextvolt

- 14:30 Fixed the bolt glyph in the logo
```

New entries are inserted at the end of their project's section, so a day spent
switching between projects still reads as one block per project. A section is
created the first time that project is logged.

Plain Markdown on purpose — readable on its own, easy to grep or feed somewhere
else later. `send.py` re-reads the bullets and reformats them; it does
not condense with an LLM. If you want summarizing instead of verbatim bullets,
that's the place to add it.