record-demo

โดย apify

บันทึกหรือสร้าง GIF สาธิต mcpc ใหม่ (README hero docs/images/mcpc-demo.gif และเทปที่เน้นใน docs/vhs/) ด้วย VHS ใช้เมื่อถูกขอให้สร้าง...

npx skills add https://github.com/apify/mcpc --skill record-demo

record-demo: VHS demo GIFs for mcpc

The tapes in docs/vhs/*.tape are 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:

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

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:

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

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) — --lossy drops imperceptible inter-frame detail and cuts ~60% off a text-terminal GIF with no visible quality loss:

# 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

TapeRecords
mcpc-demo.tapeHero basic-use flow (stdio + remote) → docs/images/mcpc-demo.gif
quickstart.tapeMinimal connect → list → call
tools.tapetools-list / tools-get / tools-call, inline JSON, stdin
scripting.tape--json piped through jq (code mode)
grep.tapeDynamic tool discovery with mcpc grep across two sessions (Apify + filesystem)
proxy.tapeMCP proxy / AI sandboxing (keeps a bearer token on purpose)
skills.tapeMCP Skills extension: skills-list / skills-get / resources-directory-read against the e2e test server served as mcp.example.com
security.tapeAuto-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).

Skills เพิ่มเติมจาก apify

apify-influencer-brand-collabs
apify
ค้นหาความร่วมมือระหว่างแบรนด์และครีเอเตอร์บน Instagram โดยการเชื่อมต่อ Apify Actors ใช้เมื่อผู้ใช้ถามว่าใครร่วมงานกับแบรนด์ แบรนด์ใดที่ครีเอเตอร์ได้รับค่าตอบแทน...
apify-actor-development
apify
สร้าง, ดีบัก, และปรับใช้โปรแกรมคลาวด์แบบไร้เซิร์ฟเวอร์สำหรับการขูดเว็บ, ระบบอัตโนมัติ, และการประมวลผลข้อมูล รองรับเทมเพลต JavaScript, TypeScript, และ Python พร้อมไลบรารี Crawlee, Playwright, และ Cheerio ในตัวสำหรับการรวบรวมข้อมูลผ่าน HTTP และเบราว์เซอร์ รวมถึงการทดสอบในเครื่องผ่าน apify run พร้อมพื้นที่จัดเก็บแบบแยกส่วน, การตรวจสอบความถูกต้องของสคีมาสำหรับอินพุต/เอาต์พุต, และการปรับใช้ไปยังแพลตฟอร์ม Apify ผ่าน apify push ต้องมีการรับรองความถูกต้องของ Apify CLI และข้อมูลเมตา generatedBy ที่จำเป็นใน .actor/actor.json สำหรับ AI...
apify-actorization
apify
แปลงโปรเจกต์ที่มีอยู่ให้เป็น Apify Actors แบบไร้เซิร์ฟเวอร์ พร้อมการผสานรวม SDK เฉพาะภาษา รองรับ JavaScript/TypeScript (ด้วย Actor.init() / Actor.exit()), Python (ตัวจัดการบริบทแบบอะซิงก์) และภาษาอื่นๆ ผ่าน CLI wrapper มีเวิร์กโฟลว์ที่มีโครงสร้าง: apify init เพื่อสร้างโครงร่าง, ใช้ SDK wrapping, กำหนดค่า schemas อินพุต/เอาต์พุต, ทดสอบในเครื่องด้วย apify run, จากนั้นปรับใช้ด้วย apify push รวมถึงการตรวจสอบความถูกต้องของ schema อินพุตและเอาต์พุต, การทำ Docker containerization, และตัวเลือกการจ่ายต่อเหตุการณ์...
apify-content-analytics
apify
การวิเคราะห์เนื้อหาหลายแพลตฟอร์มผ่าน Apify Actors สำหรับ Instagram, Facebook, YouTube และ TikTok รองรับ Actors เฉพาะทางมากกว่า 17 รายการครอบคลุมโพสต์ รีล สตอรี่ คอมเมนต์ แฮชแท็ก ผู้ติดตาม และโฆษณาทั่วทั้งสี่แพลตฟอร์ม ดึงข้อมูลสคีมาของ Actor แบบไดนามิกโดยใช้ mcpc CLI เพื่อกำหนดอินพุตที่จำเป็นและฟิลด์เอาต์พุตที่มีอยู่ แสดงผลลัพธ์ในสามรูปแบบ: การแสดงผลแชทด่วน การส่งออก CSV หรือการส่งออก JSON พร้อมจำนวนผลลัพธ์ที่ปรับแต่งได้ ต้องใช้โทเค็น Apoken ในไฟล์ .env และ Node.js 20.6+...
apify-ecommerce
apify
ดึงข้อมูลสินค้า ราคา รีวิว และข้อมูลผู้ขายจากตลาดอีคอมเมิร์ซกว่า 50 แห่ง มีโหมดการทำงานสามแบบ: สินค้าและราคา (ติดตามราคา วิเคราะห์คู่แข่ง), รีวิวลูกค้า (วิเคราะห์ความรู้สึก ปัญหาคุณภาพ), และข้อมูลผู้ขาย (ค้นหาผู้ขายผ่าน Google Shopping) รองรับ Amazon (กว่า 20 ภูมิภาค), Walmart, eBay, IKEA, Costco และร้านค้าปลีกในยุโรป; ป้อนข้อมูลผ่าน URL สินค้า, URL หมวดหมู่ หรือค้นหาด้วยคำสำคัญ มีการวิเคราะห์ด้วย AI แบบเสริมเพื่อสร้างข้อมูลเชิงลึกเกี่ยวกับราคา...
apify-generate-output-schema
apify
สร้างสคีมาเอาต์พุต (dataset_schema.json, output_schema.json, key_value_store_schema.json) สำหรับ Apify Actor โดยการวิเคราะห์ซอร์สโค้ดของมัน ใช้เมื่อ...
apify-influencer-discovery
apify
ค้นหาและประเมินอินฟลูเอนเซอร์บน Instagram, Facebook, YouTube และ TikTok โดยใช้ Apify Actors เส้นทางคำขอค้นหาไปยัง Actors เฉพาะทางมากกว่า 15 รายการที่ครอบคลุมการขูดข้อมูลโปรไฟล์ การค้นหาแฮชแท็ก การวิเคราะห์การมีส่วนร่วม และการค้นหากลุ่มเฉพาะบนแพลตฟอร์มหลักทั้งหมด ดึงข้อมูลสคีมาของ Actor แบบไดนามิกผ่าน mcpc เพื่อกำหนดอินพุตที่จำเป็นและฟิลด์เอาต์พุตที่มีก่อนดำเนินการ รองรับโหมดการส่งออกสามแบบ: แสดงผลในแชทแบบอินไลน์, ไฟล์ CSV หรือ JSON พร้อมกำหนดจำนวนผลลัพธ์ที่ปรับแต่งได้...
apify-ultimate-scraper
apify
เว็บสแครปเปอร์อัตโนมัติที่เลือก Actor ที่เหมาะสมที่สุดสำหรับ 55+ แพลตฟอร์ม รวมถึง Instagram, TikTok, YouTube, Facebook, Google Maps และอื่นๆ ครอบคลุม Actor ที่กำหนดค่าไว้ล่วงหน้ากว่า 55 ตัวใน 8 แพลตฟอร์มหลัก พร้อมคำแนะนำการเลือกตามกรณีการใช้งานเฉพาะ (การสร้างลีด, การค้นหาอินฟลูเอนเซอร์, การตรวจสอบแบรนด์, การวิเคราะห์คู่แข่ง, การวิจัยเทรนด์) รองรับรูปแบบเอาต์พุตสามแบบ: การแสดงผลแชทด่วน, การส่งออก CSV หรือการส่งออก JSON พร้อมขีดจำกัดผลลัพธ์ที่ปรับแต่งได้ รวมถึงรูปแบบเวิร์กโฟลว์แบบหลาย Actor สำหรับการทำงานที่ซับซ้อน...