ScreenCraft MCP server
Overview
screencraft-mcp is a Model Context Protocol server that lets an AI agent control the ScreenCraft desktop app: start and stop screen recordings, and export finished MP4 videos. It runs over stdio and talks to the app through a local Unix socket.
Why use it
- Recordings capture the full screen (browser, terminal, native apps) with system-level cursor and click telemetry — not a browser viewport.
- Export produces a finished video: auto-zoom targeted at the recorded clicks, rendered cursor with smoothing, background canvas. No manual editing step.
- Typical uses: regenerating demo videos in CI/on release, agents recording walkthroughs of changes they made, on-screen bug reproductions.
Requirements
- macOS 14+ on Apple Silicon
- ScreenCraft 1.1.1 or newer, installed in /Applications
- Screen Recording permission granted to ScreenCraft
- Node.js 18+
Setup
1. Grant Screen Recording permission
Open ScreenCraft once. System Settings → Privacy & Security → Screen Recording → enable ScreenCraft → relaunch the app. Recording fails without this.
2. Register the server in your MCP client
The server is the npm package screencraft-mcp, run via npx. Generic configuration (any MCP client):
{
"mcpServers": {
"screencraft": { "command": "npx", "args": ["-y", "screencraft-mcp"] }
}
}Claude Code
claude mcp add -s user screencraft -- npx -y screencraft-mcp-s user registers the server for all projects. Without it, the server is only available in the directory where the command was run.
Claude Desktop
Add the generic configuration block to ~/Library/Application Support/Claude/claude_desktop_config.json, then quit and reopen Claude Desktop. Claude Desktop does not share configuration with Claude Code.
Cursor
Add the generic configuration block to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json in a repository (that project only), then reload Cursor.
Antigravity / other MCP clients
Use the client's MCP server settings and supply the generic configuration block (command npx, args -y screencraft-mcp). Any client that supports stdio MCP servers works.
3. Verify
Start a new session — MCP servers connect at session start. In Claude Code, run /mcp; screencraft should be listed as connected. Then ask the agent to call get_status: expect app_running: true and screen_permission: true.
Workflow
1. start_recording {"project": "Docs Demos"} → { recording_id }
2. drive the demo (browser automation, CLI, any UI interaction)
3. stop_recording → { recording_id }
4. export_recording {"recording_id": "..."} → { export_id }
5. get_status (poll) → { export: { progress, output } }Timing contract
- start_recording returns only after frames are being written. Actions performed after it returns are in the recording.
- stop_recording returns only after the take is finalized on disk (5–15 s).
- export_recording is asynchronous. Poll get_status; the export object reports progress (0–1) and, when done, output (absolute path) or error.
Tool reference
| param | type | description |
|---|---|---|
| project | string | Project folder to record into. Created if missing. Default: active project. |
| display_id | int | Display to capture. Valid ids: get_status → displays. Default: main display. |
| mic | bool | Capture microphone. Default false. |
| system_audio | bool | Capture system audio. Mutually exclusive with mic (mic wins). Default false. |
| webcam | bool | Record webcam as a separate picture-in-picture track. Default false. |
| fps | int | Capture frame rate, 1–120. Default 60. |
| max_duration_seconds | int | Auto-stop cap, 10–7200. Default 1800. |
| param | type | description |
|---|---|---|
| recording_id | string | From stop_recording or list_recordings. Default: most recent recording. |
| path | string | Screen-video path. Must be inside the ScreenCraft library. recording_id is preferred. |
| param | type | description |
|---|---|---|
| limit | int | Max entries. Default 10. |
Behavior
- State machine. idle → starting → recording → stopping → idle; exports run in the exporting state. Conflicting commands are rejected with an error naming the active recording_id / export_id.
- App launch. Only start_recording and export_recording launch ScreenCraft. Read-only tools report app_running: false instead.
- Timeouts. A client timeout does not cancel the server-side command. After a timeout, call get_status to reconcile before retrying.
- Auto-stop. Recordings stop automatically after max_duration_seconds (default 1800, max 7200).
- Human coexistence. Agent recordings are refused while the user records from the UI (ui_busy), and vice versa.
Security
- Transport is a Unix domain socket at ~/Library/Application Support/ScreenCraft/control.sock, mode 0600 (same user only). Nothing listens on the network.
- While an agent recording runs, the ScreenCraft menu bar shows “Agent is recording” with a Stop item. Recordings are never invisible to the user.
- export_recording only accepts files inside the ScreenCraft library; paths are canonicalized (symlinks resolved) before the check.
- The MCP server itself holds no credentials and stores no data; the app enforces all state.
Output files
| artifact | location |
|---|---|
| Recordings (screen, webcam, audio, session manifest) | ~/Movies/ScreenCraft/<project>/ |
| Exported MP4s | next to the recording; absolute path in get_status → export.output |
Recordings are normal ScreenCraft projects: they can be opened and edited in the app afterwards. The installed copy's trial or license applies; the MCP server requires nothing separate.
Troubleshooting
| symptom | cause / fix |
|---|---|
| Agent reports it has no ScreenCraft tools | Server not registered in this client/scope, or the session predates registration. Register per Setup (use -s user in Claude Code; Claude Desktop has its own config file) and start a new session. |
| "Screen Recording permission is missing" | System Settings → Privacy & Security → Screen Recording → enable ScreenCraft → relaunch the app. |
| npx cannot find screencraft-mcp | Node 18+ required. Use npx -y screencraft-mcp@latest to bypass a stale npx cache. |
| "Busy: a recording is already running" | A previous take is active (a timed-out start may still have succeeded). Call get_status, then stop_recording or cancel_recording; or use the menu bar's Stop Agent Recording. |
| Export never finishes | Poll get_status → export. If error is set, the render failed; the message contains the cause. Long takes render for several minutes. |
Support: [email protected]