# @clipy/mcp Give your AI agent access to your [Clipy](https://clipy.online) screen recordings. > Developed in the Clipy monorepo. A public mirror for browsing the source and filing > issues lives at **[github.com/manovagyanik1/clipy-mcp](https://github.com/manovagyanik1/clipy-mcp)** > (MIT), kept in sync with each npm release. This is a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server. It lets Claude, Cursor, Windsurf, and other MCP-capable agents **search your recordings and read their transcripts and AI summaries** — so you can do things like _"turn this bug-report recording into a Linear ticket"_ without leaving your agent — and, with the `record` tool, **record a web app headlessly** and get it back as a Clipy recording (_"build the feature, then record the outcome"_). The canonical cross-surface operating contract is **[clipy.online/agents.md](https://clipy.online/agents.md)**. For the exact connected MCP version and schemas, use the standard `tools/list` request. The read tools need the `recordings:read` scope, which every key gets by default. The write tools — `record`, the session tools (`start_recording`, `add_marker`, `add_chapter`, `stop_recording`, `abort_recording`), and `replace_transcript` — additionally need the key to carry the `ingest` scope ("Record & upload"), which the server enforces. A `recordings:read`-only key can read your recordings but cannot create, modify, or delete anything. ## Setup Log in once with the Clipy CLI: ```bash npx @clipy/cli@latest login ``` It opens your browser; click **Approve** once. The key is saved to `~/.config/clipy/config.json`, **and this server reads that file** — so there is no key to copy anywhere, and no secret ends up in your shell history or your MCP config. Then add the server to your MCP client. ### Claude Code The `--scope user` flag installs Clipy **globally** for every project. Without it, `claude mcp add` defaults to `local` scope (the current folder only): ```bash claude mcp add --scope user clipy -- npx -y @clipy/mcp ``` ### Codex This writes the server to your global `~/.codex/config.toml`, so it's available in every Codex session: ```bash codex mcp add clipy -- npx -y @clipy/mcp ``` Or add it to `~/.codex/config.toml` by hand: ```toml [mcp_servers.clipy] command = "npx" args = ["-y", "@clipy/mcp"] ``` ### Claude Desktop / Cursor / Windsurf Edit the matching **user-level** config (`claude_desktop_config.json`, `~/.cursor/mcp.json`, or the Windsurf MCP config) directly: ```json { "mcpServers": { "clipy": { "command": "npx", "args": ["-y", "@clipy/mcp"] } } } ``` Add an `"env": { "CLIPY_API_KEY": "clipy_sk_live_xxx" }` block only if you are not using `clipy login` on this machine. ### Setting the key explicitly Use `CLIPY_API_KEY` when there is no `clipy login` to read from — CI, a container — or when you deliberately want a different key than the logged-in one. An explicit env var always wins over the config file. Mint keys at **https://clipy.online/settings/api-keys** (shown only once). > **Never inline your key into the server's launch command** — e.g. > `"command": "sh", "args": ["-c", "CLIPY_API_KEY=… npx -y @clipy/mcp"]`. Command-line > arguments are visible to **every local process** via the process table (`ps`, `/proc`), > so a key placed there is effectively world-readable on the machine. Put it in the `env` > block instead. (`claude mcp add --env …` / `codex mcp add --env …` write that `env` block > for you — they expose the key only in the argv of that single setup command, never in the > long-running server's.) ## Tools | Tool | What it does | | --- | --- | | `search_memory` | **Search the whole Clipy memory at once** — every screen recording the user made *and* every video they imported — returning the matching moments with timestamps and a URL that opens at that point. Matching is semantic as well as literal, so "login flow" finds a moment where someone said "the authentication screen". Reach for this first when the user refers to something they showed, recorded, or watched; the per-library tools below each see only half the picture. Each hit carries `kind` (`recording` or `context`) to tell you which tool to read next, a `resolution` saying whether its timestamp is an exact moment or a ~50s span, and a `semantic.status` to check before treating an empty result as "nothing recorded". | | `search_recordings` | Search your recordings by keyword (title + description). | | `list_recordings` | List your most recent recordings. | | `get_recording` | Metadata for one recording (status, duration, transcript/summary status). | | `get_transcript` | The full timestamped transcript + plaintext. | | `get_summary` | The AI summary: TL;DR, key points, action items. | | `get_browser_diagnostics` | Privacy-redacted visited routes, console warnings/errors, page exceptions, and failed fetch/XHR metadata. The evidence is explicitly labelled page-reported; headers, bodies, cookies, tokens, typed values, and raw query values are never captured. | | `wait_for_artifacts` | Poll until a recording's transcript/summary finish processing. | | `download_recording` | Download the MP4 locally so you can clip it or extract frames yourself (e.g. with ffmpeg). | | `get_key_moments` | Key moments: timestamps, captions, and click coordinates. | | `get_agent_context` | The full agent-context bundle (summary + key moments + transcript + available browser diagnostics) as markdown. | | `record` | **Record a web app headlessly** and upload it as a Clipy recording; returns its share + agent-context URLs. Accepts a `type` (recording kind), `viewports` (sweep several screen sizes into one video), `storageState` / `userDataDir`+`profileDirectory` / `initScript` (record behind a login), and timestamped `notes` that become the (silent) recording's transcript. Needs Playwright in this server's environment and an `ingest`-scoped key (see below). | | `start_recording` | **Start a recording session** that keeps recording while you work (drive the page with your own browser tools, run commands, …). Accepts `type`, `storageState` / `userDataDir`+`profileDirectory` / `initScript`, and `exposeCdp` (get a CDP endpoint + in-page `window.__clipyMark`/`window.__clipyChapter` bridge to drive the recorded page). Auto-stops + uploads at `maxSeconds` (default 600) so it can never run away. | | `add_marker` | Drop a narration marker into the active session (live clock, or backdate with `atSeconds`) — markers become the recording's transcript chapters. Can carry evidence in one of two provenances: **clipy-verified** (`assertSelector` / `assertText` / `assertUrl`) where Clipy checks the page itself, or **driver-attested** (`observed` + `verdict`) where you report what your own tooling saw. Clipy-verified outcomes render with a verdict glyph (✓ pass, ✗ failure that can abort via `failMode`, ⚠ unverified — never a silent pass); driver-attested ones render with a weaker-looking **hedge glyph** (`≈`) so the two are never mistaken at a glance, and they are tallied in separate segments. Navigations + console errors are added automatically as `[auto]` marks. | | `add_chapter` | Drop a `=== CHAPTER: