I built an AI coworker that works while I sleep, using nothing but Claude Code
Claude Code has a feature called routines : a cloud session that starts on a cron schedule, clones a GitHub repository, uses the MCP connectors you've attached on claude.ai (Slack, Gmail), and exits. No server, no extra tooling. I used it to build a watcher that, every morning at 09:00 JST, reads 1

Claude Code hat eine Funktion namens Routines: eine Cloud-Sitzung, die nach einem Cron-Zeitplan startet, ein GitHub-Repository klont, die MCP-Connectors verwendet, die man auf claude.ai hinterlegt hat (Slack, Gmail), und sich dann beendet. Kein Server, keine zusà¤tzliche Tooling-Infrastruktur.
Damit habe ich einen Watcher gebaut, der jeden Morgen um 09:00 Uhr JST 12 Seiten der offiziellen Anthropic-Dokumentation liest, sie mit dem Stand vom Vortag abgleicht, eine japanische Zusammenfassung in Slack postet und, wenn eine ànderung meine Bà¼cher betrifft, einen Artikel-Entwurf nach GitHub pusht. Die Motivation war peinlich: Ich schreibe Anleitungen zur Claude API und habe den Start von Haiku 5.5 fà¼nf Tage lang verpasst. Ein lokales Skript postete tà¤glich âchangedâ-Hinweise in Slack. Niemand hat sie gelesen.
Alles Folgende ist der Stand vom 16. Oktober 2026. Routines entwickeln sich schnell weiter; fà¼r den aktuellen Zustand sollte man die offizielle Dokumentation prà¼fen.
volvox-ltd/claude-docs-watch (private) ├── pages.json # 12 offizielle Seiten (die.md-Versionen auf platform.claude.com) ├── watch.py # fetch -> Vergleich mit state/ -> diffs/<date>/ + result.json (nur Stdlib) ├── state/ # Text vom Vortag ├── diffs/ # Unified Diffs pro Tag ├── drafts/ # Artikelentwà¼fe, die die Routine schreibt, wenn eine ànderung relevant ist ├── log/ # tà¤gliche Zusammenfassungen └๠ROUTINE_PROMPT.md # die Anweisungen, die die Routine erhà¤lt Enter fullscreen mode Exit fullscreen mode Die Designentscheidung, die zà¤hlt: Python findet den Diff; das Modell urteilt nur und schreibt. Ein Modell zu bitten, âlies diese 12 Seiten und sag mir, was sich geà¤ndert hatâ, bedeutet, jeden Morgen rund 300.000 Zeichen zu lesen und dabei Dinge zu à¼bersehen. watch.py erzeugt die Diff-Dateien; das Modell liest nur diese.
{ "name": "claude-docs-watch 09:00 JST", "cron_expression": "0 0 * * *", "enabled": true, "job_config": { "ccr": { "environment_id": "env_â¦", "session_context": { "model": "claude-sonnet-5-5", "sources": [{ "git_repository": { "url": "https://github.com/volvox-ltd/claude-docs-watch" }}], "allowed_tools": [ "Bash", "Read", "Write", "Edit", "Glob", "Grep", "mcp__Slack__slack_send_message", "mcp__Slack__slack_search_channels" ]}, "events": [{ "data": { "uuid": "â¦", "session_id": "", "type": "user", "parent_tool_use_id": null, "message": { "role": "user", "content": "<der Prompt unten>" }}}]}}, "mcp_connections": [{ "connector_uuid": "â¦", "name": "Slack", "url": "https://mcp.slack.com/mcp" }] } Enter fullscreen mode Exit fullscreen mode Sonnet 5.5 reicht và¶llig: Die tà¤gliche Aufgabe lautet âlies einen Diff und fasse ihn zusammenâ.
Das Repository https://github.com/volvox-ltd/claude-docs-watch ist bereits in dein Arbeitsverzeichnis geklont (Branch main). Konfiguriere git mit user.name 'docs-watch-bot' und user.email 'contact@volvox-ltd.com', bevor du committest. Du bist der tà¤gliche Docs-Watcher fà¼r persimmoq, einen Autor von Claude-API-Anleitungen.
Du là¤ufst jeden Morgen in einem frischen Klon dieses Repositorys. Verwende fà¼r alle menschenlesbaren Texte Japanisch. Fà¼hre diese Schritte in der angegebenen Reihenfolge aus.
1. Fà¼hre zunà¤chst `git pull --rebase origin main` aus (der Checkout kann veraltet sein). Fà¼hre dann `python3 watch.py` aus dem Repository-Wurzelverzeichnis aus und lies `result.json`.
2. Wenn `changed` leer ist und `errors` leer ist: Hà¤nge eine Zeile `<date> no changes` an `log/<YYYY-MM>.md` an, committe, pushe zu `main` und sende EINE kurze Slack-Nachricht an den privaten Kanal #mail (channel_id C0BEY8JUCDR). Dann beende die Ausfà¼hrung.
3. Wenn es ànderungen gibt: Lies jede Datei, die unter `changed[].diff` aufgefà¼hrt ist. Ignoriere reine Formatierungsà¤nderungen.
Schreibe fà¼r die inhaltlichen ànderungen eine Zusammenfassung mit, pro Seite: dem Seitenschlà¼ssel, 1 bis 3 Sà¤tzen dazu, was sich geà¤ndert hat, und einer Einschà¤tzung, ob sie die verà¶ffentlichten Materialien des Autors betrifft (die Bà¼cher zur Claude 5 Migration und zu Managed Agents sowie die Artikel zu diesen Themen). Markiere jede Seite als affected / not affected / check. 4.
Schreibe diese Zusammenfassung in `log/<YYYY-MM>.md` unter einer àberschrift `## <date>` und poste dieselbe Zusammenfassung in den Slack-Kanal. Halte sie unter 2.000 Zeichen; verlinke jede Seiten-URL. 5.
Wenn mindestens eine Seite betroffen ist und die ànderung ein neues Modell, ein neuer Preis, eine neue Breaking Change, eine Deprecation/Abkà¼ndigung oder ein neues Managed-Agents-Feature ist: Schreibe EINEN Artikelentwurf in `drafts/<date>-<short-slug>.md` (Front Matter mit published: false), zitiere die exakten neuen Textstellen aus dem Diff, wo es relevant ist, verlinke die offizielle Seite und beende ihn mit einem Abschnitt âWhat I verifiedâ, der nur einen Platzhalter enthà¤lt, den der Autor nach einem Test gegen die Live-API ausfà¼llt. Erfinde kein Verhalten, das die Dokumentation nicht beschreibt. Behaupte nicht, etwas sei getestet worden.
6. `git add -A`, committe, pushe zu `main`. Wenn der Push fehlschlà¤gt, wiederhole ihn einmal nach `git pull --rebase`. 7.
Falls `errors` vorhanden sind, erwà¤hne sie am Ende der Slack-Nachricht. Verà¶ffentliche niemals etwas auàerhalb dieses Repositorys. àndere niemals Dateien unter `state/` von Hand.
Enter fullscreen mode Exit fullscreen mode Schritt 5 ist der entscheidende Punkt. Der Kollege entwirft; er verà¶ffentlicht nie. Der Entwurf endet mit einem leeren Abschnitt âWhat I verifiedâ, den ein Mensch ausfà¼llt, nachdem er die echte API ausgefà¼hrt hat.
Der Prompt sagt aus demselben Grund âbehaupte nicht, dass etwas getestet wurdeâ.
Lauf 1 (23 Sekunden, 8 Turns). Sandbox allokiert, Repository geklont, watch.py fand keine ànderungen, Log ergà¤nzt, Push erfolgreich, Slack-Post schlug fehl mit channel_not_found. Der Agent suchte nach dem Kanal, fand nichts und griff auf eine Mobile-Push-Benachrichtigung zurà¼ck. Ursache: Der Slack-Connector auf claude.ai war mit einem anderen Workspace verbunden. Ich habe ihn neu verbunden und die Kanal-ID in den Prompt aufgenommen.
Lauf 2 (51 Sekunden, 9 Turns). Der Slack-Post war erfolgreich. Dann wurde der Push abgelehnt: Der Checkout der Sandbox stammte von vor dem Commit von Lauf 1. Der Agent fà¼hrte git pull --rebase aus, erkannte, dass sein Commit eine doppelte Zeile war, verwarf ihn und beendete sich sauber. Nachvollziehbar, aber ich habe git pull --rebase als Schritt 1 ergà¤nzt, damit das nicht jeden Morgen passiert.
Das Laufprotokoll ist à¼ber die API mit Zeitstempeln fà¼r jeden Tool-Aufruf, jeden Fehler und die abschlieàende Nachricht verfà¼gbar. Man kann alles nachlesen, was der Kollege getan hat, wà¤hrend man geschlafen hat.
Ich nutze alle drei. Dieser Watcher ist eine Routine; meine Produktions-Agentenplattform ist Managed Agents; der wà¶chentliche Search-Console-Bericht, der lokale OAuth-Tokens benà¶tigt, là¤uft weiterhin auf launchd.
Die Anleitung zu 400-Fehlern bei der Migration, die dieser Watcher absichert, findet sich hier: Claude 5 Migration Guide (PDF, 19 $).
Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.
Original (Englisch) anzeigen
Claude Code has a feature called routines: a cloud session that starts on a cron schedule, clones a GitHub repository, uses the MCP connectors you've attached on claude.ai (Slack, Gmail), and exits. No server, no extra tooling.
I used it to build a watcher that, every morning at 09:00 JST, reads 12 pages of Anthropic's official docs, diffs them against yesterday, posts a Japanese summary to Slack, and, when a change affects my books, pushes a draft article to GitHub. The motivation was embarrassing: I write guides about the Claude API, and I missed the Haiku 5.5 launch for five days. A local script had been posting "changed" notices to Slack every day. Nobody was reading them.
Everything below is as of October 16, 2026. Routines are moving fast; check the official docs for the current shape.
volvox-ltd/claude-docs-watch (private) ├── pages.json # 12 official pages (the.md versions on platform.claude.com) ├── watch.py # fetch -> compare with state/ -> diffs/<date>/ + result.json (stdlib only) ├── state/ # yesterday's text ├── diffs/ # unified diffs per day ├── drafts/ # article drafts the routine writes when a change matters ├── log/ # daily summaries └── ROUTINE_PROMPT.md # the instructions the routine receives Enter fullscreen mode Exit fullscreen mode The design decision that matters: Python finds the diff; the model only judges and writes. Asking a model to "read these 12 pages and tell me what changed" means reading ~300k characters every morning and missing things. watch.py produces the diff files; the model reads only those.
{ "name": "claude-docs-watch 09:00 JST", "cron_expression": "0 0 * * *", "enabled": true, "job_config": { "ccr": { "environment_id": "env_…", "session_context": { "model": "claude-sonnet-5-5", "sources": [{ "git_repository": { "url": "https://github.com/volvox-ltd/claude-docs-watch" }}], "allowed_tools": [ "Bash", "Read", "Write", "Edit", "Glob", "Grep", "mcp__Slack__slack_send_message", "mcp__Slack__slack_search_channels" ]}, "events": [{ "data": { "uuid": "…", "session_id": "", "type": "user", "parent_tool_use_id": null, "message": { "role": "user", "content": "<the prompt below>" }}}]}}, "mcp_connections": [{ "connector_uuid": "…", "name": "Slack", "url": "https://mcp.slack.com/mcp" }] } Enter fullscreen mode Exit fullscreen mode Sonnet 5.5 is plenty: the daily job is "read a diff and summarize it".
The repository https://github.com/volvox-ltd/claude-docs-watch is already cloned in your working directory (branch main). Configure git with user.name 'docs-watch-bot' and user.email 'contact@volvox-ltd.com' before committing. You are the daily docs watcher for persimmoq, an author of Claude API guides.
You run inside a fresh clone of this repository every morning. Work in Japanese for all human-facing text. Do these steps in order.
1. Run `git pull --rebase origin main` first (the checkout can be stale). Then run `python3 watch.py` from the repository root and read `result.json`.
2. If `changed` is empty and `errors` is empty: append one line `<date> no changes` to `log/<YYYY-MM>.md`, commit it, push to `main`, and send ONE short Slack message to the private channel #mail (channel_id C0BEY8JUCDR). Then stop.
3. If there are changes: read every file listed under `changed[].diff`. Ignore pure formatting changes.
For the substantive changes, write a summary with, per page: the page key, 1–3 sentences on what changed, and a judgement on whether it affects the author's published material (the books on Claude 5 migration and on Managed Agents, and the articles on those topics). Mark each page as affected / not affected / check. 4.
Write that summary to `log/<YYYY-MM>.md` under a heading `## <date>` and post the same summary to the Slack channel. Keep it under 2,000 characters; link each page URL. 5.
If at least one page is affected and the change is a new model, a new price, a new breaking change, a deprecation/retirement, or a new Managed Agents feature: write ONE draft article in `drafts/<date>-<short-slug>.md` (front matter with published: false), quoting the exact new text from the diff where it matters, linking the official page, and ending with a section "What I verified" containing only a placeholder for the author to fill in after testing against the live API. Do not invent behavior that the documentation does not state. Do not claim anything was tested.
6. `git add -A`, commit, push to `main`. If the push fails, retry once after `git pull --rebase`. 7.
If any `errors` are present, mention them at the end of the Slack message. Never publish anything outside this repository. Never edit files under `state/` by hand.
Enter fullscreen mode Exit fullscreen mode Step 5 is the point. The coworker drafts; it never publishes. The draft ends with an empty "What I verified" section that a human fills in after running the real API.
The prompt says "do not claim anything was tested" for the same reason.
Run 1 (23 seconds, 8 turns). Sandbox allocated, repo cloned, watch.py found no changes, log appended, push succeeded, Slack post failed with channel_not_found. The agent searched for the channel, found nothing, and fell back to a mobile push notification. Cause: the Slack connector on claude.ai was attached to a different workspace. I reconnected it and put the channel ID in the prompt.
Run 2 (51 seconds, 9 turns). Slack post succeeded. Then the push was rejected: the sandbox's checkout predated run 1's commit. The agent ran git pull --rebase, saw its own commit was a duplicate line, discarded it, and exited cleanly. Reasonable, but I added git pull --rebase as step 1 so it doesn't happen every morning.
The run log is available from the API with timestamps for every tool call, error, and the final message. You can read everything the coworker did while you were asleep.
I use all three. This watcher is a routine; my production agent platform is Managed Agents; the weekly Search Console report, which needs local OAuth tokens, stays on launchd.
The 400-errors-when-migrating guide this watcher protects is here: Claude 5 Migration Guide (PDF, $19).