
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
@clipy/cli
Advanced tools
Command-line interface for Clipy — list, search, and read your screen recordings' transcripts, AI summaries, and key moments from the terminal.
The Clipy command line. List, search, and read your screen recordings — transcripts, AI summaries, key moments — from the terminal, download the MP4s, or export subtitles. No browser needed.
Clipy is a free screen recorder (Chrome extension and Mac app, plus a web recorder) that gives every recording an instant share link, an AI transcript and summary, and agent-readable context — so both humans and AI agents can act on what was recorded. This package is its terminal client. The canonical agent operating contract is clipy.online/agents.md.
The read commands are read-only with any key. The write commands —
proof, record, the session/mark
flow, and transcript --replace — create recordings or replace a transcript,
and work only with an ingest-scoped key.
npx @clipy/cli agents install claude # browser-approve login + install the Clipy skill
clipy login
clipy login opens your browser to approve this device — like gh auth login — and
stores the key in ~/.config/clipy/config.json (mode 0600). No copy-pasting a key.
Wiring up a coding agent? One command does both the browser login and the skill install:
npx @clipy/cli agents install claude # or: codex / cursor
Prefer to paste a key you minted yourself? Create one at
https://clipy.online/settings/api-keys (it looks like clipy_sk_live_…) and store it
without the browser:
clipy login --key clipy_sk_live_… # or: clipy login --paste to be prompted
On SSH or a display-less Linux box, clipy login automatically switches to a
copy-code flow (also available anywhere as clipy login --no-browser): it prints the
approval URL for you to open on any device — your laptop, your phone — and after you
click Approve the page shows a one-time code to paste back into the waiting terminal.
The code alone is useless without the PKCE verifier held by that terminal, so it's safe
to ferry by hand. Without a TTY at all (scripts, CI), use CLIPY_API_KEY or
clipy login --key.
clipy list [-n 20] [--page 2] [--status ready,processing] [--json]
clipy memory search <query> [--kind recording|context] [--json]
# hybrid search across recordings + imported context
clipy search <query> # full-text search titles + descriptions
clipy show <id|share-url> # metadata + share link
clipy transcript <id> [--marks-only] # one entry per line, timestamped (--srt/--vtt to export)
clipy summary <id> # TL;DR, key points, action items
clipy moments <id> # key moments: timestamps, captions, click coords
clipy context <id> # the full agent-context bundle as markdown
clipy context import <url|file> --sync # turn ANY video into an agent-readable bundle
clipy context read <bundle-path> # print a local bundle's recording.md
clipy download <id> [-o out.mp4] # download the MP4
clipy open <id> # open the share page in your browser
clipy wait <id> --for both # block until transcript/summary are ready
clipy proof --frame before.png --frame after.png # screenshots → proof video
clipy proof --video verification.webm # upload a tool-native recording
clipy record --url <app> [--for 15] # record a web app headlessly → a Clipy recording
clipy session start --url <app> # start recording in the background while you work
clipy mark "reproduced the bug" # drop a live-timestamped note into the session
clipy mark "on redemptions" --assert-url '**/redemptions' # assert what you claim
clipy chapter "AFTER — fix applied" # split the recording into before/after sections
clipy session run --url <app> -- npm run demo # start, run a command, auto stop/abort
clipy session stop # finish + upload; your marks become the transcript
clipy doctor # health check: key, Mac bridge, Playwright, install mode
clipy playwright-path # node_modules dir of the Playwright this CLI resolves
clipy mcp # run the Clipy MCP server (npx -y @clipy/mcp)
Every recording-reading command accepts either the bare public id (3kelcef8wo8h) or the
full share URL (https://clipy.online/video/3kelcef8wo8h).
clipy memory search uses the same hybrid semantic + keyword search as MCP
search_memory, across the owner's recordings and imported/watched context:
clipy memory search "authentication flow" --json
clipy memory search "checkout error" --kind recording --limit 10
Each result identifies its kind, title, timestamp or span, resolution, plain-text
snippet, and deep link. Inspect semantic.status before treating an empty result as
conclusive: unavailable or failed means the semantic index did not run and results
are keyword-only. lexical/refined are exact moments, window is a span to inspect,
and document has no exact timestamp. clipy search remains the legacy
recording-library search.
clipy context import turns a YouTube URL or a local video file into an agent-readable
bundle (recording.md + manifest.json + transcript.json), and optionally into private
Clipy memory.
clipy context import https://youtube.com/watch?v=… --sync --json
clipy context import ./demo.mov --transcript ./demo.vtt --sync
clipy context read ./clipy-context/<bundle>
Captions first, so it is fast — YouTube captions are fetched on your machine and no media
is downloaded unless it is needed. Local files carry no captions, so they need
--transcript <.vtt|.srt|.json>.
With --sync, the server classifies the bundle: what kind of video it is and whether the
words stand alone. Podcasts, interviews, and dictated content come back transcript-only; a
screen walkthrough comes back with the timestamps worth a picture, and those frames are then
extracted locally (needs ffmpeg — brew install ffmpeg). Without --sync the bundle stays
honestly transcript-only. --no-frames takes the verdict but never downloads media. Also:
--title, --tag (repeatable), --folder, --language, --output <dir>.
Synced documents are readable through the context-document API and the list_context_documents
/ get_context_document / read_context_document MCP tools. An imported transcript is
untrusted content, exactly like a recording's.
clipy proof is the dependency-light handoff for coding agents. The agent keeps
using whatever browser, computer-use, simulator, or test tool it already has;
Clipy only assembles and uploads the evidence.
Turn saved screenshots into one short proof video:
clipy proof \
--frame /tmp/01-before.png --caption "Before: Save is disabled" \
--frame /tmp/02-after.png --caption "After: Save is enabled" \
--frame /tmp/03-reload.png --caption "Reload: the value persists" \
--hold 3 --title "Settings fix proof" --type bug --wait --json
Or upload an existing recording without re-encoding:
clipy proof --video /tmp/verification.webm \
--note "0: opened settings" --note "6: saved successfully" \
--title "Settings fix proof" --type bug --wait --json
Frame mode accepts PNG, JPEG, or WebP (up to 50 frames, 5 minutes, 50 MiB per
image, and 250 MiB total), and requires ffmpeg to create the silent WebM.
--width/--height must be even integers from 320–3840. Video mode accepts
WebM or MP4 and does not require Playwright, Browser Use, Open Browser Use, or
any other browser automation dependency. Captions and notes become timestamped
agent narration; they are attestations from the driving agent, not claims
independently verified by Clipy.
clipy record captures a web app in a headless browser and uploads it as a Clipy
recording — no display needed, so it works in CI and cloud sandboxes. Made for agents:
build a feature, then record the running app so it can be shared or read back.
# Record a running app for 20s, wait for the transcript, print the links
clipy record --url http://localhost:3000 --for 20 --wait
It needs two things beyond a normal install:
npm install -g playwright && npx playwright install chromium
Flags: --for <sec> (record duration after load, default 15; per viewport), --title <t>
/ --description <d>, --type <kind> (what the recording IS — see below),
--viewports mobile,tablet,desktop (or 390x844,1440x900 — records every size sequentially
into ONE video with a transcript chapter per pass), --note "12: opened settings" (repeatable
timestamped narration notes), --width/--height (viewport + video size, default 1280×720),
--wait (block until the transcript is ready), --json (print {id, shareUrl, contextUrl, sizeBytes}).
--type <kind> declares what the recording is so the AI summary reads it correctly (a demo
isn't a bug report). Accepts bug_report, feature_request, product_demo,
walkthrough_tutorial, feedback_review, discussion_talk, other — and the short aliases
bug, feature, demo/product, walkthrough/tutorial/guide, feedback/review,
discussion/talk/meeting. An unrecognized value is a usage error. (Applied on the web path
today; --source mac-screen support is pending a Clipy app update.)
Note timestamps. A --note is absolute by default ("12: opened settings" → 12s).
With --viewports, anchor a note to a pass instead so it can't drift when load time
shifts the pass boundaries: --note "pass2: mobile layout" lands at the real start of
pass 2, and --note "pass2@5: after scrolling" lands 5s into it. Recording starts the
note clock on the first non-blank frame (up to a 10s wait), so "0: …" isn't pinned to a
still-compiling dev server's blank screen.
Narration = the transcript. Headless captures have no audio, so Clipy uses your notes (and session marks, below) as the recording's transcript, summary input, and agent-context — clearly marked as agent narration, never passed off as speech-to-text.
If something is driving the browser — prefer that. Clipy is a recorder, not a driver. When an agent (or you) drives a real, already-logged-in browser, don't hand Clipy the credentials at all: record the real screen and attach evidence as you go.
clipy session start --source mac-screen --window "Chrome" --title "PR-1234 verification"
clipy mark "redemptions tab active" --observed "tab=Redemptions, rows=14" --verdict pass
clipy chapter "AFTER — fix applied"
clipy session stop
No auth to reproduce, no credentials in flags, and the recording shows the real app.
The flags below are the agentless / CI fallback — for a one-shot clipy record in CI,
or a headless session nothing is steering, where Clipy needs its own logged-in context.
Seed the session before the browser navigates — Clipy applies all of these to the
Playwright context ahead of the first page load, so the app's route guard sees the auth
state on first paint (seeding localStorage after visiting a guarded route loses that
race and bounces you to /login). They apply to headless web capture on record and
session start; they're rejected on --source mac-screen (which records the real,
already-logged-in screen).
--storage-state <file> — a Playwright storageState
JSON (cookies + per-origin localStorage), passed straight to browser.newContext().
The easiest path: log in once with Playwright and save context.storageState({ path }),
then hand that file to Clipy. Its contents are never printed or logged.--cookie "name=value[; Domain=d; Path=p; Secure; HttpOnly; SameSite=Lax]" — set one
cookie (repeatable). Without a Domain it's scoped to the target URL; with one it's
domain-scoped.--local-storage "key=value" — set one localStorage pair for the target origin
(repeatable).--init-script <file> — run a JS file in every page before its own scripts (e.g. to
stub a feature flag or inject a token).--user-data-dir <dir> — launch a persistent Chromium profile from the user-data
root dir (launchPersistentContext), so the recording carries that profile's
whole logged-in identity. Web only; mutually exclusive with --storage-state (a
profile already carries its own storage). --cookie / --local-storage / --init-script
still compose. Pass the root, not a profile subdir — Clipy refuses a Default/Profile N
directory and tells you the parent dir + --profile-directory to use. In direct mode
(no --profile-directory) it also refuses a live-locked root (SingletonLock/SingletonSocket).--profile-directory "<name>" — with --user-data-dir, select a named profile
(e.g. Profile 12, from chrome://version → "Profile Path"). Because Playwright can't
select a named profile in place, Clipy copies that profile into a temporary recording
root and launches the copy — loudly (it prints what it's copying and the size). Your
real profile is never opened or written, and the copy is deleted after upload. No need to
quit Chrome (Clipy warns if it's running, since in-use databases may copy inconsistently —
quit it for a guaranteed-clean copy).⚠ macOS: a copied Chrome profile can open silently signed out. Chrome encrypts its cookies with a Keychain key scoped to Chrome Safe Storage; the recorder runs Playwright's Chromium, which reads Chromium Safe Storage. So a copied real-Chrome profile may open looking like you — bookmarks, preferences,
localStorageall intact — while every cookie-based login is gone.localStorage/Preferences-based sessions survive; cookie sessions may not. Clipy prints this warning before recording whenever copy mode runs on macOS. If the recording lands logged out, this is why — use--source mac-screenwith your real browser, or the agent-driven path (drive your own browser and attach evidence with--observed/--verdict).
# Reuse a saved Playwright login
clipy record --url https://app.example.com/dashboard --for 20 \
--storage-state ./auth.json
# Or seed a token directly
clipy record --url https://app.example.com/dashboard \
--local-storage "authToken=eyJ…" --cookie "sid=abc; Domain=app.example.com; Secure"
# Or record your real logged-in Chrome profile (copied, never modified)
clipy record --url https://app.example.com/dashboard --for 20 \
--user-data-dir "$HOME/Library/Application Support/Google/Chrome" \
--profile-directory "Profile 12"
--storage-state seeds only the cookies and localStorage the file contains — it
can't conjure a whole browser identity, so an app that also needs cross-origin or
auth-host cookies (SSO, a separate API domain) can still bounce to /login. Three
reliable ways to get a real logged-in recording:
npx playwright open --save-storage=auth.json https://login.example.com
# sign in, close the window, then:
clipy record --url https://app.example.com/dashboard --storage-state auth.json
--user-data-dir "<chrome user-data root>" --profile-directory "<name>" (name from chrome://version). Clipy copies that profile
to a temp root and records the copy — no manual export, and your real profile is untouched.--source mac-screen --window "Chrome" — record your real, already-logged-in
Chrome window through the Mac app; there's no headless auth to reproduce at all.For recordings where an agent (or you) drives the app live, don't script the capture: start a session, work normally, and narrate with marks as you go.
clipy session start --url http://localhost:3000 --title "Settings overflow fix"
# … drive the app with your own tools …
clipy mark "reproduced the overflow on the settings page"
clipy mark "after the fix: the sidebar wraps correctly"
clipy session stop # closes the browser, uploads, prints the share link
The session records in a detached background daemon, so every command returns
immediately. clipy mark stamps notes against the live recording clock; navigations and
console errors are added automatically as [auto] marks. One session per directory.
Drive the recorded browser (opt-in). Pass --expose-cdp to session start and the
daemon's headless Chromium opens a CDP endpoint you can attach to and drive navigation, clicks,
and viewport while Clipy records the same page. It's off by default — while it's open, any
local process can attach to and control that browser, so only enable it when you intend to drive
the session. clipy session start --expose-cdp prints the endpoint (and session start --json
/ session status --json return it as cdpHttpUrl / cdpUrl, also written to the 0600
session state file). The env var CLIPY_DISABLE_CDP=1 is a hard kill switch that overrides the
flag.
clipy session start --url http://localhost:3000 --expose-cdp --title "Overflow fix"
const { chromium } = require("playwright");
const browser = await chromium.connectOverCDP(cdpHttpUrl); // from `clipy session status --json`
const page = browser.contexts()[0].pages()[0]; // the page being recorded (a NEW context is not captured)
await page.goto("http://localhost:3000/settings"); // navigate / click / fill as usual
// page.viewportSize() is null over a CDP attach — resize via the device-metrics override:
const cdp = await browser.newCDPSession(page);
await cdp.send("Emulation.setDeviceMetricsOverride", { width: 1280, height: 720, deviceScaleFactor: 1, mobile: false });
await browser.close(); // detaches; the recording keeps going
Four things that otherwise cost a debugging round: attach with connectOverCDP; the
recorded page is browser.contexts()[0].pages()[0] (a brand-new context/page you open
won't be captured); page.viewportSize() is null on a CDP attach; and a resize needs a
CDP Emulation.setDeviceMetricsOverride, not setViewportSize. Your driver script
resolves Playwright from its own directory — if require("playwright") can't find it,
run the script with NODE_PATH=$(clipy playwright-path) node driver.js.
In-page marks (zero spawn latency). While --expose-cdp is on, the daemon also exposes
window.__clipyMark("text", opts?) and window.__clipyChapter("label") in the recorded
page. Calling them from your driver emits a mark/chapter without spawning a clipy mark
process, so it lands exactly when your code runs, and it runs daemon-side with the page in
hand. __clipyMark's second argument takes the same assertions as the CLI flags —
evaluated and annotated ✓/✗ identically:
await page.evaluate(() => window.__clipyMark("clicked Export"));
await page.evaluate(() =>
window.__clipyMark("status is Active", {
assertSelector: ".status-badge",
assertText: "Active", // needs assertSelector — otherwise the call rejects
assertUrl: "**/redemptions", // optional
failMode: "abort", // optional; "warn" is the default
}),
);
It returns the annotated { tMs, text, assert }; failMode: "abort" discards the session
just like the flag. These marks land in the same transcript and count toward the same
200-mark cap. Note: while CDP is exposed the page's own scripts can call these too —
the same trust boundary as --expose-cdp itself (any local process can already drive the
browser), so only enable it when you intend to drive the session.
session start also accepts the same auth flags as record
(--storage-state / --cookie / --local-storage / --init-script) to record a
logged-in app; see Recording a logged-in app.
Safety rails are built in: the session auto-stops and uploads at --max <sec>
(default 600, hard cap 1800) so a forgotten session can never run away; clipy session abort discards everything; a crashed daemon is detected and cleared on the next command;
corrupt captures are refused before upload, and a failed upload keeps the local file.
A plain mark is an unverified claim: an agent can write clipy mark "the Redemptions tab is active" whether or not it is, and the transcript reads as authoritative either
way. Evidence marks fix that — in one of two ways, and Clipy labels which, so a
claim you attested can never be read as something Clipy checked.
Driver-attested — you brought the browser. Clipy is a recorder, not a driver: when you're driving a real browser with your own tooling (or recording the screen), attach the values you observed and your verdict.
clipy mark "redemptions tab active" --observed "tab=Redemptions, rows=14" --verdict pass
clipy mark "totals still stale" --observed "total=\$0.00 (expected \$412.50)" --verdict fail
Stored as redemptions tab active [≈ ASSERT driver-attested; observed=tab=Redemptions, rows=14]
(or ✗). Both flags are required together, a mark carries exactly one provenance
(mixing with --assert-* is a usage error), and this works in every session type —
including --source mac-screen.
The honesty rule: driver-attested means Clipy vouches that the agent said it, not that Clipy verified it. Put real observed values in
--observed— the point of the ledger is that a reviewer can check the attestation against the video.
Clipy-verified — Clipy owns the page. In a headless web session the daemon owns the live Playwright page, so it can check the claim against the real DOM itself:
# Assert a URL (globs: ** = anything, * = any non-slash segment, no * = substring)
clipy mark "opened the redemptions tab" --assert-url "**/redemptions"
# Assert an element exists and contains text
clipy mark "status flipped to Active" --assert-selector ".status-badge" --assert-text "Active"
status flipped to Active [assert ✓ verified-by-clipy; .status-badge="Active"]
and the CLI prints a green ✓.status flipped to Active [ASSERT ✗ verified-by-clipy; expected "Active"; observed .status-badge="Pending"]
and the CLI prints a red ✗. The wrong claim is preserved as a failed assertion, not
as a fact.--assert-selector <css> checks an element matches (its trimmed text becomes the
observed value); --assert-text <substr> requires that element's text to contain a
substring (it needs a selector); --assert-url <glob> matches the page URL. Combine them
freely — all provided checks must pass. These need a Clipy-owned page, so they're rejected
on --source mac-screen (use --observed/--verdict there).
--fail-mode decides what a failed assertion does: warn (default) records the ✗ and
keeps recording; abort discards the whole session — nothing is uploaded and the CLI
exits non-zero, so a driver that asserts its way to a broken state doesn't ship a misleading
clip.
The leading [verification] note reports the two provenances as separate segments and
never pools them:
[verification] 3 clipy-verified: 1 passed, 1 failed, 1 unverified · 3 driver-attested: 2 passed, 1 failed
An empty segment is omitted; with only clipy-verified marks the rendering stays the legacy
N assertion(s): P passed, F failed[, K unverified].
A mark is never dropped, and a late verdict never rewrites it. If the daemon can't be
reached to evaluate an assertion — its event loop briefly starved during a heavy dev-server
recompile, say — clipy mark doesn't fail and lose the note. It records the narration
anyway, tags it [ASSERT ⚠ clipy could not evaluate — <reason>], prints a loud ⚠, and exits 0.
An unverified claim is flagged as unverified (the K in the tally), never silently promoted
to a ✓. That ⚠ is the mark of record: if the daemon was only slow (not gone) and
evaluates the same claim a moment later, that verdict judged a later page state, so it does
not overwrite the ⚠. It's recorded as a separate, honestly-timestamped
[late check of "…" — evaluated Ns after the claim: …] note at the moment it actually ran,
and it counts toward neither passed, failed, nor unverified. (Plain, non-asserted marks that
the daemon later processes are simply deduped — they appear exactly once.)
Assertions evaluate against a real page, so they need a web session (they're rejected on
--source mac-screen, which records the real screen with no page to probe).
clipy chapterclipy chapter "<label>" drops a section boundary so a single video can carry both a
BEFORE and an AFTER state — exactly the shape of a PR-review recording:
clipy session start --url http://localhost:3000/settings --title "Sidebar overflow fix"
# … demo the bug on the base branch …
clipy mark "sidebar overflows on mobile" --assert-selector ".sidebar.is-overflowing"
clipy chapter "AFTER — fix applied"
# … git switch fix-branch, restart the dev server, reload …
clipy mark "sidebar wraps correctly" --assert-selector ".sidebar:not(.is-overflowing)"
clipy session stop
session run — crash-safe wrappingIf a driver script crashes mid-session, a plain session start keeps recording dead air
up to --max and then uploads it. session run wraps a command so cleanup is guaranteed:
clipy session run --url http://localhost:3000 --expose-cdp -- node driver.js
It starts the session, runs everything after -- with inherited stdio, and then: exit 0
→ session stop (upload + share link); any non-zero exit or a signal → session abort
(discard) and the child's exit code is propagated. The command runs with CLIPY_SESSION=1,
CLIPY_SESSION_FILE=<path>, and (when --expose-cdp) CLIPY_CDP_URL=<cdpHttpUrl> in its
environment. Ctrl-C is forwarded to the child, then the session is discarded. All the
session start flags (--url, --title, --max, --type, --expose-cdp, auth flags)
apply before the --.
clipy mark / clipy chapter resolve the session from CLIPY_SESSION_FILE first and the
current directory second — so a driver you launch with session run can shell out
clipy mark … from any working directory and still hit the right session, instead of
failing with "no recording session in this workspace".
Each clipy mark is a short process spawn (~100–300 ms), so a mark can land slightly after
the state it describes. Backdate it onto the recording clock:
clipy mark "the toast appeared" --ago 2 # 2 seconds before now
clipy mark "page finished loading" --at 4 # at an absolute 4s on the recording clock
Backdating an asserted mark is a subtlety: the mark lands at the backdated time, but the
assertion still judges the live page (the daemon can't rewind). When the verdict was
observed more than 2 s from the backdated position, the mark stays where you put it and the
text gains (assertion observed Ns after this backdated mark — the verdict describes the page at observation time), with a signed assert.driftSec in --json — so a ✓/✗ is never read
as describing the earlier moment. Live-clock asserted marks and backdated plain marks are
unaffected.
--source mac-screen on record / session start records through the running Clipy
Mac app (ScreenCaptureKit — real screen, real logged-in browser, not a headless page).
First use shows a consent dialog in the app; the recording indicator is always visible.
By default it captures the primary display. Target one window instead:
clipy sources # list displays + windows with ids
clipy session start --source mac-screen --window "Chrome" --title "Fix walkthrough"
# … the agent drives the real, logged-in Chrome while Clipy records that window …
clipy mark "reproduced the bug"
clipy mark "fix applied — retesting"
clipy session stop # uploads, prints the share link
Agent recordings don't take your microphone. On --source mac-screen the default is
system audio on, mic off — an agent recording on your behalf isn't the same consent as
you clicking Record, and nobody asked for the room (or whatever call you're on) to be
captured; agent narration rides on marks, not speech. --mic opts in; --no-system-audio
opts out of system audio. Both are mac-screen only — headless web captures are silent, so
passing them on the web path is a usage error. The resolved config is printed
(audio: system on, mic off) and returned as a sibling audio field in --json.
Two things can go wrong, and both fail closed toward "assume the mic is live". If your Clipy app is too old to control audio at all, the CLI says so before recording starts — the timing is the point, since a warning printed after the fact is an autopsy on a mic that was already open. If a new-enough app never confirms what it applied, you get the same warning after start. Either way the message means we do not know that the mic is off: believe it and update the app rather than trusting the flag you passed.
--window takes a window id from clipy sources, or an app/title substring
(case-insensitive; ambiguous matches list the candidates instead of guessing).
--display <id> records a specific display. Both also work on one-shot
clipy record --source mac-screen --for 30.
On start Clipy prints the surface it actually resolved, read live from the app:
recording window: "Redemptions · Admin — Chrome" (id 157)
session start --json and record --json carry the same as source: {kind, id, title},
in the same shape as each entry's source in clipy sources --json, so you can
compare what you picked against what the camera reports without transforming either.
Check it against the surface you're driving, and abort on a mismatch. Driver-attested marks prove what you observed — they say nothing about what the camera saw. If you drive a background tab of the recorded window, you get a truthful "10 passed" tally over footage of a different tab: worse than no evidence, because the tally vouches for the wrong footage.
Clipy will never bring a window or tab to the front for you. It can't know which
tab/page/simulator you mean, and on --source mac-screen it may not be recording a browser
at all — focusing the right surface is the caller's job. Do it before session start, then
confirm with the reported title. (That title is read at start time; the camera follows the
window, so switching tabs mid-recording changes what's filmed without changing the title.)
Every command has machine-readable output. --json is supported on list, memory search, search,
show, transcript, summary, moments, wait, record, session start/stop/status,
mark, chapter, doctor, and playwright-path — stdout is the JSON payload, stderr is progress
and hints, and errors exit non-zero with a message on stderr prefixed error:. For the
full capability manifest (every command, flag, env var, and exit code) run
clipy guide --json.
# Newest recording's id
clipy list -n 1 --json | jq -r '.recordings[0].id'
# Export subtitles for a recording
clipy transcript 3kelcef8wo8h --srt > recording.srt
# Record headlessly and capture the share link
clipy record --url http://localhost:3000 --for 20 --json | jq -r '.shareUrl'
# Record with anything, then block until Clipy finished transcribing
clipy wait 3kelcef8wo8h --for both && clipy summary 3kelcef8wo8h
Exit codes: 0 ok · 1 error · 2 usage · 3 artifact not ready yet.
| Setting | Flag | Env | Stored (via clipy login) |
|---|---|---|---|
| API key | --key | CLIPY_API_KEY | ~/.config/clipy/config.json |
| API base | --api-url | CLIPY_API_URL | ~/.config/clipy/config.json |
Precedence: flag → env → stored config.
If you're wiring Clipy into an MCP-capable agent (Claude Code, Cursor, Codex, …),
use the @clipy/mcp server instead — same
API, but with agent-native tools and inline key-moment frames
(source ·
setup docs). clipy mcp is a shortcut that runs it.
Also: every public Clipy watch link is agent-readable without any install — append
.md to it (https://clipy.online/video/<id>.md) and it serves a markdown context
document with the summary, key moments, and transcript. Details at
clipy.online/for-agents.
@clipy/mcp · docs · sourceMIT © Codersera
FAQs
Command-line interface for Clipy — list, search, and read your screen recordings' transcripts, AI summaries, and key moments from the terminal.
The npm package @clipy/cli receives a total of 119 weekly downloads. As such, @clipy/cli popularity was classified as not popular.
We found that @clipy/cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.