Skip to main content

record-demo

Record or regenerate the mcpc demo GIFs (the README hero docs/images/mcpc-demo.gif and the focused tapes in docs/vhs/) with VHS. Use whenever asked to create, refresh, restyle, shorten, or fix a terminal demo/animation/GIF of mcpc. The tapes drive real mcpc commands; for the authenticated step this skill ALWAYS prompts for a short-lived, low-permission TEST token first (never production). Captures the VHS + mcpc gotchas learned the hard way — read it fully before editing a tape.

소스 정보

저장소
apify/mcpc
최근 소스 활동
2026년 9월 24일 12:50
감지된 SKILL.md 언어
영어
스타
982
포크
96

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
record-demo
description
Record or regenerate the mcpc demo GIFs (the README hero docs/images/mcpc-demo.gif and the focused tapes in docs/vhs/) with VHS. Use whenever asked to create, refresh, restyle, shorten, or fix a terminal demo/animation/GIF of mcpc. The tapes drive real mcpc commands; for the authenticated step this skill ALWAYS prompts for a short-lived, low-permission TEST token first (never production). Captures the VHS + mcpc gotchas learned the hard way — read it fully before editing a tape.
allowed-tools
Bash, Read, Write, Edit, AskUserQuestion
# record-demo: VHS demo GIFs for mcpc The tapes in `docs/vhs/*.tape` are [VHS](https://github.com/charmbracelet/vhs) scripts that drive a **real** shell session — VHS types each command, runs it against a live MCP server, captures the terminal, and renders a GIF. The README hero is `docs/images/mcpc-demo.gif`, built from `docs/vhs/mcpc-demo.tape`. This file is the accumulated know-how. **Read all of it before touching a tape** — most rules below were discovered by hitting the wall, and skipping them wastes whole render cycles (~1–2 min each). ## The hero flow (`mcpc-demo.tape`) A basic-use story across both transports: 1. `mcpc` — empty state (no sessions, no profiles) 2. `mcpc connect mcp.json:filesystem` — local **stdio** server (auto-names `@filesystem`) 3. `mcpc` — session list (now shows the live session) 4. `mcpc @filesystem tools-list` 5. `mcpc @filesystem tools-list --json` — JSON output, syntax-highlighted, no jq 6. `mcpc connect mcp.apify.com -H "Authorization: Bearer $APIFY_TOKEN"` — remote **HTTP** server (auto-names `@apify`) 7. `mcpc @apify tools-list` 8. `mcpc @apify tools-get search-actors` — inspect one tool's input schema 9. `mcpc @apify tools-call search-actors keywords:="web scraper" limit:=3` 10. `mcpc @apify close` Ten commands run ~45s; there is no hard 30s cap for this flow. ## Style conventions (the current standard — match these) - **No `# comments`** in the visible script. The commands are self-descriptive. - **No `| head`, no `2>/dev/null`** on visible commands. Show real output even if long — it scrolls naturally. (`connect` ≈ 86 lines incl. an "Available commands" list, `tools-call search-actors` ≈ 56, filesystem `tools-list --json` ≈ 300.) - **Continuous session — never `clear` between steps.** Put a single blank-line `Enter` before each command (after the first) so it's separated from the previous output, like a real terminal session. - **Colored prompt + bold-white typed commands.** In the hidden setup block: ``` Type 'export PS1="\[\e[1;38;2;25;230;77m\]$\[\e[0m\] \[\e[1;97m\]"' Enter Type "trap 'tput sgr0' DEBUG" Enter ``` - `PS1` is a bold bright-green `$`, then ends with `\[\e[1;97m\]` so the typed input renders bold bright-white. - The `DEBUG` trap runs `tput sgr0` before every command so the bold-white input does **not** bleed into command output. - **Empty state** needs a clean home — hidden: `Type 'export MCPC_HOME_DIR="$(mktemp -d)"'` so `mcpc` shows "No active MCP sessions / No OAuth profiles". - **Color is automatic for non-piped commands** — mcpc detects the TTY and emits color (256-color, plenty vivid). You only need `export FORCE_COLOR=3` (+ `COLORTERM=truecolor` for exact hex) when a command is **piped** (mcpc turns color off when stdout isn't a TTY). The current tapes avoid pipes, so they don't need it. (The CLI palette lives in `src/cli/output.ts`, `RAINBOW_SATURATION`, bumped to 78% for vividness — that's where the demo colors come from.) ## VHS gotchas (these will bite you) - **ASCII prompt symbols only.** Multibyte glyphs (`❯`, `»`, `▶`) break bash prompt rendering under VHS and show up as garbage like `92m]`. Use `$` (or `>`), styled with color + bold. - **`Type` quoting:** use **single quotes** around any command containing double quotes. A `\"` inside a double-quoted `Type` breaks VHS's parser. e.g. `Type 'mcpc @apify tools-call search-actors keywords:="web scraper" limit:=3'` and `Type 'export PS1="\[\e[…m\]$\[\e[0m\] "'`. - **Output/Screenshot paths:** must not start with a digit (`Output 1-foo.gif` fails to parse) and must not be long absolute paths (the parser chokes). Use short, letter-leading, **relative** names and run `vhs` from `docs/vhs/`. - **`Screenshot` is unreliable** (frequently exits 2 even though the GIF rendered fine). Don't depend on it — pull frames from the finished GIF instead: `ffmpeg -y -ss <seconds> -i x.gif -vframes 1 frame.png`, then Read the PNG. - **Renders are slow** (~1–2 min each: real-time timeline + Chromium + ffmpeg encode). Render tapes **one at a time** — a `for` loop over several blows the 5-minute command timeout. Extracted frames often land mid-typing; sample a few timestamps around when output should be on screen. - **Hidden connects leak into the recording if bash falls behind.** When a tape connects in the hidden setup (so the feature commands run against a ready session, e.g. tools/scripting/grep), a slow connect lets VHS type ahead; bash then echoes the buffered commands and runs the `clear` *after* `Show`, so the setup spills into frame. Pattern that works: type the connect(s), then **one generous `Sleep` (7–8s)** so they finish, then `clear`, then **another `Sleep` (~1.5s) before `Show`**. (Tapes that connect *visibly* as their first command don't need this — their hidden setup is just fast exports + `clear`.) ## Stdio servers in a headless / proxied box - **`npx`-launched stdio servers are too slow here.** `npx -y <pkg>`'s registry round-trip exceeds mcpc's 60s connect handshake, so `connect` times out (`MCP error -32001`). Fixes: pre-install the server (`npm i -g <pkg>`) and put the **direct binary** in `mcp.json` (e.g. `mcp-server-filesystem`, starts in ~0.3s — also a cleaner session header), or use `npx --prefer-offline -y <pkg>` once the npm cache is warm (~5s; plain `npx -y` still does the slow registry check even when cached). - **Puppeteer does NOT work for headless recording.** `@modelcontextprotocol/server-puppeteer` launches Chromium eagerly on startup and hangs/times out as root in the container. Use **`@modelcontextprotocol/server-filesystem`** instead (14 recognizable tools, instant). `docs/vhs/mcp.json` defines the `filesystem` entry via its global binary — install it first: `npm i -g @modelcontextprotocol/server-filesystem`. ## Auth token (the authenticated step) - **Always prompt for the token first.** Insist on a **short-lived, low-permission token from a TEST / throwaway account — never production.** Apify: <https://console.apify.com/settings/integrations>. Tell the user to **revoke it as soon as the recording is done.** - Pass it inline, for the render only: `APIFY_TOKEN=… vhs mcpc-demo.tape`. The tape references `$APIFY_TOKEN` (never the literal), typed inside **single quotes** so bash expands it at run time — the value is **never on screen, never in the GIF, never committed**. Always verify a connect frame shows `$APIFY_TOKEN`, not the value. - `connect` **auto-names** the session: `mcp.apify.com → @apify`, `mcp.json:filesystem → @filesystem`. No `@name` needed. - No-token alternative (public, anonymous): `mcpc connect "https://mcp.apify.com/?tools=search-actors,fetch-actor-details,docs"`. ## Skills demo server (`skills.tape`, `security.tape`) No public server serves the MCP Skills extension yet, so `skills.tape` records against the e2e test server (`test/e2e/server/index-v2.ts`, 2026-07-28, which serves the `git-workflow` / `refunds` / `daily` skill fixtures) under the name `mcp.example.com`. mcpc forces HTTPS for non-localhost hosts, so front it with TLS: ```bash WITH_SKILLS=true PORT=13456 pnpm exec tsx test/e2e/server/index-v2.ts & echo "127.0.0.1 mcp.example.com" >> /etc/hosts openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 2 \ -subj "/CN=mcp.example.com" -addext "subjectAltName=DNS:mcp.example.com" # then run any small HTTPS → http://127.0.0.1:13456 reverse proxy on 127.0.0.1:443 export NODE_EXTRA_CA_CERTS="$PWD/cert.pem" NO_PROXY="mcp.example.com,$NO_PROXY" cd docs/vhs && vhs skills.tape ``` The connect stays hidden: its output names the test server ("e2e-test-server"). ## Keychain warning (headless only) On a box with no keyring, the bearer-token `connect` prints `[keychain] OS keychain unavailable, falling back to file-based credential storage …`. It is **environment-specific** (won't appear on a normal desktop with a keyring) and there is **no env var to suppress it** — it's a `logger.warn` in `src/lib/auth/keychain.ts` gated only by keychain availability and JSON mode. A `dbus-run-session` + `gnome-keyring-daemon` wrapper does **not** fix it in this sandbox (raising the dbus fd limit is blocked). Options: leave it (honest), or add a targeted `2>/dev/null` to just that one connect command. ## Prerequisites ```bash mcpc --version # the CLI being demoed (npm i -g @apify/mcpc, or build + pnpm link this repo) vhs --version # brew install vhs (needs ttyd + ffmpeg on PATH) mcp-server-filesystem # npm i -g @modelcontextprotocol/server-filesystem (the stdio demo server) ``` Headless + **root**: VHS drives a Chromium (go-rod auto-downloads it to `~/.cache/rod`) that refuses to start without `--no-sandbox`. If renders fail to launch Chromium, wrap the binary once: ```bash CHROME=$(find ~/.cache/rod/browser -name chrome -type f | head -1) mv "$CHROME" "$CHROME-real" printf '#!/bin/sh\nexec "$(dirname "$0")/chrome-real" --no-sandbox --disable-gpu --disable-dev-shm-usage "$@"\n' > "$CHROME" chmod +x "$CHROME" ``` (Run `vhs` once first to trigger the Chromium download.) ## Render and verify ```bash cd docs/vhs APIFY_TOKEN=… vhs mcpc-demo.tape # real-time; be patient ffprobe -v error -show_entries format=duration -of csv=p=0 mcpc-demo.gif # check length ffmpeg -y -ss 12 -i mcpc-demo.gif -vframes 1 /tmp/f.png # spot-check a frame, then Read it cp mcpc-demo.gif ../images/mcpc-demo.gif # update the README hero ``` Check each frame class: empty state, stdio connect + session list, tools-list, JSON, remote connect (**token NOT visible**), tool-call result, close. Then **revoke the token.** ## Optimize the GIF size (do this before committing) VHS GIFs are large (the hero is ~5 MB raw). Shrink them losslessly-ish with `gifsicle` ([kornel.ski/lossygif](https://kornel.ski/lossygif)) — `--lossy` drops imperceptible inter-frame detail and **cuts ~60%** off a text-terminal GIF with no visible quality loss: ```bash # in place; lossy=200 ≈ 60% smaller, text stays crisp (verified by frame diff) for f in docs/images/mcpc-demo.gif docs/vhs/*.gif; do [ "$f" = docs/vhs/mcpc-demo.gif ] && continue # ignored raw hero gifsicle -O3 --lossy=200 -b "$f" done ``` After optimizing, re-extract a colored frame (`ffmpeg -ss 12 …`) and eyeball it — lossy=200 is the sweet spot; going much higher smears the antialiased text. When the optimized hero lands on `main`, **bump the README cache-buster** (`mcpc-demo.gif?v=N` → `?v=N+1`): GitHub's camo image proxy caches by full URL, so a new `?v=` is what makes it re-fetch the smaller file instead of serving the old cached copy. ## What's committed - `docs/images/mcpc-demo.gif` — the README hero (canonical copy). - `docs/vhs/*.gif` — the per-feature recordings are committed too, so they're easy to find and reuse. `.gitignore` ignores only `docs/vhs/mcpc-demo.gif` (the hero's raw output, since it's committed under `docs/images/`). - `proxy.gif` needs a token to record and isn't committed until recorded. ## The tapes | Tape | Records | | ---- | ------- | | `mcpc-demo.tape` | Hero basic-use flow (stdio + remote) → `docs/images/mcpc-demo.gif` | | `quickstart.tape` | Minimal connect → list → call | | `tools.tape` | `tools-list` / `tools-get` / `tools-call`, inline JSON, stdin | | `scripting.tape` | `--json` piped through `jq` (code mode) | | `grep.tape` | Dynamic tool discovery with `mcpc grep` across two sessions (Apify + filesystem) | | `proxy.tape` | MCP proxy / AI sandboxing (keeps a bearer token on purpose) | | `skills.tape` | MCP Skills extension: `skills-list` / `skills-get` / `resources-directory-read` against the e2e test server served as `mcp.example.com` | | `security.tape` | Auto-discovery skipping a checked-in `.mcp.json` entry that reads `${GITHUB_TOKEN}` (fixture: `security.mcp.json`, copied into a `mktemp -d` HOME so no real configs are discovered); needs `mcp.example.com` for the trusted entry | All focused tapes follow the same conventions as the hero (bold `$` prompt, bold-white commands, no comments, blank-line separation, `mktemp` home). `quickstart`/`tools`/`scripting`/`grep` are token-free (public `?tools=` URL); `grep` also connects a local filesystem stdio server so it can search across two sessions. `proxy.tape` keeps a bearer token because demonstrating that you can proxy a credentialed session without leaking the token is its entire point (it's the one focused tape that needs a token to record).
GitHub에서 보기