screen-recorder-mcp
README.md
# screen-recorder-mcp
> MCP server that gives Claude and AI agents start/stop control over full-screen recordings on macOS — powered by FFmpeg avfoundation.
[](https://github.com/jakubkrzysztofsikora/screen-recording/actions/workflows/ci.yml)
---
## What Is This?
This is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that wraps macOS screen recording via FFmpeg's avfoundation input. It lets Claude, or any MCP-compatible AI agent, start and stop full-desktop screen recordings with a simple tool call — no manual terminal commands needed.
Perfect for recording demos, bug reproductions, or documentation walkthroughs driven entirely by AI.
## Demo
```
You: "Record my screen to ~/Desktop/demo.mp4 in high quality"
Claude: calls start_recording(output_path: "~/Desktop/demo.mp4", quality: "high")
"Recording started! Screen index: 1, FPS: 30, Quality: high."
... you do the demo ...
You: "Stop the recording"
Claude: calls stop_recording()
"Recording stopped. Saved to ~/Desktop/demo.mp4 (34s, 12.8 MB)"
```
## Prerequisites
| Requirement | How to get it |
|-------------|---------------|
| **macOS 12+** | Monterey or later |
| **FFmpeg** | `brew install ffmpeg` |
| **Node.js 18+** | `brew install node` or [nodejs.org](https://nodejs.org) |
| **Screen Recording permission** | System Settings (see [Permissions Setup](#permissions-setup)) |
## Installation
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"screen-recorder": {
"command": "npx",
"args": ["screen-recorder-mcp"]
}
}
}
```
Then restart Claude Desktop.
### Claude Code
Add as an MCP server — works immediately without restart:
```bash
claude mcp add screen-recorder -- npx screen-recorder-mcp
```
Then in any Claude Code conversation:
```
You: "List my screen devices"
You: "Start recording my screen"
You: "Stop the recording"
```
To remove:
```bash
claude mcp remove screen-recorder
```
### Global Install
```bash
npm install -g screen-recorder-mcp
```
### Cursor / VS Code / Other MCP Clients
Add to your MCP client's configuration file (e.g., `.cursor/mcp.json`, `.vscode/mcp.json`):
```json
{
"mcpServers": {
"screen-recorder": {
"command": "npx",
"args": ["screen-recorder-mcp"]
}
}
}
```
### Smithery Registry
This server is listed on [Smithery](https://smithery.ai) for one-click installation in compatible MCP clients.
## Permissions Setup
Screen recording on macOS requires explicit user consent:
1. Open **System Settings**
2. Navigate to **Privacy & Security** > **Screen Recording**
3. Enable your terminal application (Terminal, iTerm2, Warp, VS Code, etc.)
4. **Restart** the terminal application after granting permission
> **Note:** If recording fails with a permission error, the tool returns a structured error with these exact instructions.
## Available Tools
| Tool | Description | Key Params |
|------|-------------|------------|
| [`start_recording`](#start_recording) | Start full-screen recording | `output_path`, `screen_index`, `audio_index`, `fps`, `quality`, `preset` |
| [`stop_recording`](#stop_recording) | Stop active recording | (none) |
| [`get_recording_status`](#get_recording_status) | Check if recording is active | (none) |
| [`list_recordings`](#list_recordings) | List all past recordings | `limit` |
| [`list_screen_devices`](#list_screen_devices) | Discover screens & audio devices | (none) |
---
### `start_recording`
Start recording the macOS desktop. Only one recording can be active at a time.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `output_path` | string | auto-generated | Output `.mp4` file path. Relative paths resolve to `~/Movies/screen-recordings/` |
| `screen_index` | number | primary display | avfoundation device index (use `list_screen_devices` to find) |
| `audio_index` | number | none | Audio device index. Omit for no audio, `-1` to explicitly disable |
| `fps` | number | `30` | Frames per second (1-60) |
| `quality` | string | `"medium"` | `"low"` (CRF 35), `"medium"` (CRF 28), `"high"` (CRF 18) |
| `preset` | string | `"ultrafast"` | FFmpeg preset: `ultrafast`, `superfast`, `veryfast`, `faster`, `fast` |
<details>
<summary>Example response</summary>
```json
{
"success": true,
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"output_path": "/Users/you/Movies/screen-recordings/recording-2025-03-22-143012.mp4",
"message": "Recording started. Screen index: 1, FPS: 30, Quality: medium. Use stop_recording to end."
}
```
</details>
### `stop_recording`
Stop the active recording. Sends a graceful `q` signal to FFmpeg and waits for the file to finalize.
<details>
<summary>Example response</summary>
```json
{
"success": true,
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"output_path": "/Users/you/Movies/screen-recordings/recording-2025-03-22-143012.mp4",
"duration_seconds": 47,
"file_size_bytes": 15234048,
"file_size_human": "14.5 MB",
"message": "Recording stopped. File saved to ... (47s, 14.5 MB)"
}
```
</details>
### `get_recording_status`
Check whether a recording is in progress, and get elapsed time.
<details>
<summary>Example response</summary>
```json
{
"status": "recording",
"is_recording": true,
"current_session": { "id": "...", "startedAt": "...", "outputPath": "..." },
"elapsed_seconds": 23,
"total_recordings": 5
}
```
</details>
### `list_recordings`
Returns past recordings sorted by most recent first.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | number | `20` | Max recordings to return |
### `list_screen_devices`
Discover available screens and audio devices. Run this first if you're unsure which `screen_index` or `audio_index` to use.
<details>
<summary>Example response (multi-monitor setup)</summary>
```json
{
"screen_devices": [
{ "index": 1, "name": "Capture screen 0", "type": "screen" },
{ "index": 2, "name": "Capture screen 1", "type": "screen" }
],
"audio_devices": [
{ "index": 0, "name": "Built-in Microphone", "type": "audio" },
{ "index": 1, "name": "BlackHole 2ch", "type": "audio" }
],
"recommended_screen_index": 1,
"ffmpeg_version": "6.1.2"
}
```
</details>
## Use Cases
### AI-Driven Demo Recording
Let Claude record polished product demos while you narrate and click through the UI. Ask it to start, pause at key moments, and stop — all through natural conversation.
### Automated Bug Reproduction
Have Claude record your screen while you reproduce a bug, then reference the recording when filing issues. Especially useful in QA workflows where evidence is required.
### Documentation Walkthroughs
Record step-by-step tutorials with Claude managing the recording lifecycle. Combine with voice narration for instant how-to videos.
### CI/CD Visual Testing
Integrate screen recordings into automated test pipelines to capture visual regressions or end-to-end test flows.
### Pair Programming Sessions
Record your coding sessions with Claude Code as a pair programming partner. Review recordings later to document architectural decisions.
## Usage Examples
**Record a demo:**
> "Start recording my screen to ~/Desktop/demo.mp4, high quality"
> *... do the demo ...*
> "Stop the recording and tell me the file size"
**Record with audio:**
> "List my screen devices, then start recording screen 1 with my built-in microphone"
**Multi-monitor:**
> "List screen devices, start recording the second monitor"
**Low-resource recording:**
> "Start a screen recording at 15 fps, low quality, ultrafast preset"
**Check what's recording:**
> "What's the current recording status? How long has it been going?"
**Review past recordings:**
> "List my last 5 recordings with their file sizes"
## Error Handling
All tools return structured errors with resolution hints — they never throw unhandled exceptions to the MCP client:
```json
{
"success": false,
"error_type": "ScreenRecordingPermissionError",
"error": "Screen Recording permission not granted.",
"resolution": "Open System Settings > Privacy & Security > Screen Recording > enable your terminal app."
}
```
| Error Type | Cause | Resolution |
|------------|-------|------------|
| `FfmpegNotFoundError` | ffmpeg not in PATH | `brew install ffmpeg` |
| `ScreenRecordingPermissionError` | macOS permission denied | Enable in System Settings |
| `RecordingAlreadyActiveError` | Tried to start while recording | Call `stop_recording` first |
| `NoActiveRecordingError` | Tried to stop with nothing active | Check `get_recording_status` |
| `InvalidOutputPathError` | Bad file path or extension | Use a path ending in `.mp4` |
## Troubleshooting
| Problem | Solution |
|---------|----------|
| "ffmpeg not found" | `brew install ffmpeg` |
| "Permission denied" / blank recording | Grant Screen Recording permission in System Settings |
| Recording starts but file is 0 bytes | Wrong avfoundation device index — use `list_screen_devices` |
| No audio in recording | Add `audio_index` param — use `list_screen_devices` to find device |
| High CPU during recording | Use `preset: "ultrafast"` and lower `fps` |
## How It Works
```
Claude (MCP Client) screen-recorder-mcp FFmpeg
| | |
|-- start_recording -------->| |
| |-- spawn ffmpeg ------->|
| | -f avfoundation |
| | -i "3:none" |
| | -vcodec libx264 |
|<-- session_id, path -------| recording... |
| | |
|-- stop_recording --------->| |
| |-- stdin: "q\n" ------->|
| | (graceful) |
| |<-- exit 0 -------------|
|<-- duration, size ---------| |
```
## Development
```bash
git clone https://github.com/jakubkrzysztofsikora/screen-recording.git
cd screen-recorder-mcp
npm install
npm run dev # Run server in dev mode (tsx)
npm test # Run unit tests
npm run test:coverage # Run tests with coverage report
npm run typecheck # TypeScript strict mode check
npm run build # Build to dist/
npm run check-deps # Verify ffmpeg + list devices
npm run inspect # Open MCP Inspector
```
### Project Structure
```
src/
index.ts # MCP server entry point & tool registration
recorder.ts # FFmpeg process management (start/stop/status)
devices.ts # avfoundation device discovery
storage.ts # Recording file registry (in-memory + disk manifest)
types.ts # All shared TypeScript types & error classes
tests/
recorder.test.ts
devices.test.ts
storage.test.ts
```
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding standards, and PR checklist.
## License
[MIT](LICENSE)
TDQS
A4.4/5.0
Scored across 5 tools
Disambiguation5/5
Each tool maps to a distinct lifecycle concern: starting, stopping, querying active status, listing recorded files, and enumerating capture devices. There is no functional overlap between any pair.
Naming Consistency5/5
All tool names follow a consistent snake_case verb_noun pattern with clear verbs: start, stop, get, list. The naming style is uniform and predictable.
Tool Count5/5
Five tools is well-scoped for a screen recorder: no redundant helpers or missing essentials. Each tool earns its place in the workflow.
Completeness5/5
The domain of screen recording is covered end-to-end: device discovery, start, stop, status, and listing past recordings. There are no obvious dead ends or missing operations for this use case.
Maintenance
ActivityInactive
ResponsivenessNo issues