Record the mctl-telegram ChatGPT demo walkthrough on the reviewer/test Telegram account and auto-deploy the video to tg.mctl.ai/demo. Use when (re)recording the App Directory demo, refreshing the /demo clip, or when asked to "record the demo" / "redo the walkthrough video" for mctl-telegram.
Resources
1Install
npx skillscat add mctlhq/mctl-gitops/mctl-demo-walkthrough Install via the SkillsCat registry.
mctl-telegram demo walkthrough + auto-deploy
Produce the public demo video at https://tg.mctl.ai/demo by driving ChatGPT
Developer Mode through the mctl-telegram MCP tools on the reviewer/demo
Telegram account, recording it with gif_creator, converting to mp4, and
shipping it through the normal PR → release → gitops flow.
HARD SAFETY RULES (read first)
- Only the test/reviewer account
8745115872(@mctlhq). NEVER the
operator's personal account (the other connected identity — resolve it vialist_telegram_identitiesand treat every non-reviewer account as
off-limits). - Verify the surface is the reviewer account before recording: ask ChatGPT to
send any message; the tool result MUST containdry_reason: "reviewer/demo account — sending is preview-only; no message is delivered". If it sends for real, STOP — you are on the wrong account. - Sends are auto-dry-run on the reviewer account (0.36.0 reviewer-forced-dry-run,
[[project_mctl_telegram_demo_reviewer_rollout]]) — so clicking "Send Message" in
the confirm panel is safe and delivers nothing. - ChatGPT Developer Mode AUTO-EXECUTES tools — there is NO reliable deny-able
panel fordisconnect. Confirmed 2026-05-25: prompting "Disconnect my Telegram
account" randisconnect_telegram_accountimmediately ("Disconnected your
Telegram account") with no Deny button. So you CANNOT demonstrate disconnect by
"deny" — if you issue the prompt, it WILL disconnect for real. - Disconnect bricks reviewer re-login until restored.
disconnectsetsrevoked_aton the account row;CheckSessionValidonly looks at rowsrevoked_at IS NULL, so once the last row is revoked, demo_login (and all RPCs)
fail with no-active-session. It does NOT wipesession_encryptedand does NOT
log out Telegram-side, so it is recoverable. Preferred: do NOT issue a
disconnect prompt at all — narrate it / show the/demopage's disconnect
copy instead. If it does fire, RESTORE immediately (see Recovery). pinactually pins (benign + reversible on the demo account).delete/revoke
are destructive like disconnect — never prompt them.- Never put real operator chats / phone numbers / private content on screen.
Preconditions
- Chrome extension connected; a
chatgpt.comtab logged in, the MCTL Telegram
connector added, Developer Mode ON. - Connector authenticated as the reviewer account (the dry_reason check above).
ffmpegavailable locally (/opt/homebrew/bin/ffmpeg).
Recording sequence
- Load chrome tools via ToolSearch (
mcp__claude-in-chrome__*):tabs_context_mcp,computer,browser_batch,gif_creator,navigate,get_page_text,find.
Confirm/select the chatgpt.com tab. - Open a New chat (clean recording). Confirm "Developer mode" banner.
gif_creator start_recording, then screenshot (first frame).- Issue prompts ONE at a time via
browser_batch(click composer → type → Return →wait~8-10s → screenshot). Use English prompts. Cover all eight items:- Connect — "Show my connected Telegram accounts" →
list_telegram_identities
(demonstrates the connected account / how connection is established). Do NOT
do a destructive re-auth. - Search — "List my recent Telegram chats" →
list_dialogs. Dismiss any
"Is this conversation helpful?" popup. - Summarize — "Show the recent messages in my and summarize them" →
get_messages+ summary. - Draft — "Draft a reply to saying '...'. Don't send it yet." → draft
(prepare), shown with an Edit affordance, not sent. - Send with confirmation — "Now send it" → confirm panel "Send Telegram
message to ...?" → click Send Message → result issent:false/mode:"draft"/ preview-only (the highlight). - Pin — "Pin in " → confirm panel → Send Message
(actually pins on the demo account; benign). - Audit — "Show my recent audit log" →
get_my_audit_log(shows the
draft/sent/list entries — transparency). - Disconnect — do NOT prompt "Disconnect my Telegram account" (it
auto-executes — see safety rules). Either skip it, or capture the/demo
page's "Disconnect or revoke access" copy as the closing frame. If you DO
run it (or it fires accidentally), the video is still fine — but you MUST
run Recovery below before finishing.
- Connect — "Show my connected Telegram accounts" →
Recovery — if the reviewer account got disconnected
Symptom: ChatGPT says "Disconnected your Telegram account"; subsequent reads fail
with no-active-session. The session bytes survive in the revoked row. Restore withKUBECONFIG=...k3s-preview/kubeconfig.yaml, pod shared-pg-1 in ns platform-db,
db labs-mctl-telegram (reviewer = users.telegram_login_id=8745115872,user_id=6462):
- Find the newest revoked row that has the session + a real telegram_user_id:
SELECT id FROM telegram_accounts WHERE user_id=6462 AND telegram_user_id=8745115872 ORDER BY connected_at DESC LIMIT 1; - Un-revoke it and refresh TTLs so
CheckSessionValidaccepts it:UPDATE telegram_accounts SET revoked_at=NULL, last_used_at=now(), expires_at=now()+interval '24 hours', connected_at=now() WHERE id=<id>; - Verify: ask ChatGPT "List my recent Telegram chats" — it should return chats
(the pool re-loads the row and reconnects). Keepsend_enabled=false. gif_creator stop_recording(screenshot the final state first), thenexport
withdownload:true,showWatermark:false,quality:8,filename:mctl-telegram-demo-walkthrough.gif. Note: max ~50 frames; keep the run
tight so frames cover the key panels.
Auto-deploy (hand off to a background general-purpose agent)
Give the agent a self-contained prompt to:
- Convert the GIF → mp4:
ffmpeg -y -i <gif> -movflags +faststart -pix_fmt yuv420p -vf "scale=1280:-2:flags=lanczos" -c:v libx264 -crf 28 internal/web/walkthrough.mp4
(target < ~3MB). Replaceinternal/web/walkthrough.mp4in the local
mctl-telegram checkout in the mctlhq workspace; the route/demo/walkthrough.mp4+//go:embedalready exist (0.37.0). go build ./... && go vet ./... && go test ./internal/web/...; open a PR
(conventional commit, NOCo-Authored-By), post EXACTLY@claude review.- After merge: cut a release. If the only change is the embedded
.mp4it may
land aschore/docsand NOT bump — forceRelease-As: x.y.z
([[feedback_release_please_docs_no_bump]]). Release PRs merge with--admin. - Bump the gitops cache-buster: edit
DEMO_VIDEO_URLinmctl-gitops/platform-gitops/services/labs/mctl-telegram/values.yamlto...walkthrough.mp4?v=N(increment N) — hand-edit only, nevermctl_deploy_service([[feedback_mctl_env_colon_strip]]). Why the cache-buster:
Cloudflare caches.mp4404s/old copies; a fresh?v=Nkey dodges stale edge
cache ([[feedback_cloudflare_caches_404_static_paths]]). - Verify the new image live by polling in-pod (
kubectl exec ... wget localhost:8080/demo/walkthrough.mp4) or the deployed tag — NOT the public CF URL.
Then confirmtg.mctl.ai/demoplays the new clip.
Done = tg.mctl.ai/demo plays the refreshed walkthrough and the ?v=N asset
returns 200 through Cloudflare.