quick-media-mcp
by Fowerld
README.md
# quick-media-mcp
MCP server and Chrome extensions for screen recording and screenshots, designed for [Claude Code](https://claude.com/claude-code).
## Architecture
```
Claude Code
↓ MCP protocol (stdio)
quick-media-mcp server (Node.js)
↓ WebSocket (localhost:9876)
Chrome Extensions (Quick Video / Quick Screenshot)
↓ getDisplayMedia / captureVisibleTab
Browser
```
The MCP server is the bridge between Claude Code and the Chrome extensions. Claude calls MCP tools (`video_start`, `screenshot_capture`, etc.), the server forwards them to the extensions via WebSocket, and the extensions use Chrome APIs to capture media.
## Packages
| Package | Description | npm |
|---------|-------------|-----|
| [`packages/server`](packages/server/) | MCP server — bridge between Claude Code and extensions | `quick-media-mcp` |
| [`packages/chrome-video`](packages/chrome-video/) | Chrome extension — screen/tab recording (WebM, MP4, GIF) | - |
| [`packages/chrome-screenshot`](packages/chrome-screenshot/) | Chrome extension — screenshots (PNG, JPEG, WebP, GIF) | - |
## Prerequisites
- **Node.js** >= 18
- **Google Chrome** (or Chromium)
- **Claude Code** (for MCP integration)
- **ffmpeg** (optional, for hardware-accelerated encoding detection)
## Installation
### 1. Clone and build
```bash
git clone https://github.com/Fowerld/quick-media-mcp.git
cd quick-media-mcp
npm install
npm run build
```
This builds all three packages:
- `packages/server/dist/` — compiled MCP server
- `packages/chrome-video/dist/` — video extension ready to load
- `packages/chrome-screenshot/dist/` — screenshot extension ready to load
### 2. Load extensions in Chrome
1. Open `chrome://extensions`
2. Enable **Developer mode** (toggle in the top right corner)
3. Click **Load unpacked** → navigate to `packages/chrome-video/dist/` → select the folder
4. Click **Load unpacked** → navigate to `packages/chrome-screenshot/dist/` → select the folder
Both extensions should appear in the extensions list. Pin them to the toolbar for easy access.
### 3. Configure the MCP server for Claude Code
**Option A — Local path (recommended for development):**
Add to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"quick-media": {
"command": "node",
"args": ["/absolute/path/to/quick-media-mcp/packages/server/dist/cli.js"]
}
}
}
```
**Option B — Global install:**
```bash
cd packages/server
npm install -g .
quick-media-mcp --install
```
This registers the server in `~/.claude/settings.json` automatically. You can verify with `quick-media-mcp --help`.
**Option C — Auto-install script:**
```bash
quick-media-mcp --install # adds to Claude Code config
quick-media-mcp --uninstall # removes from Claude Code config
```
### 4. Connect the extensions
1. Open a Chrome tab
2. Click the **Quick Video** (or **Quick Screenshot**) extension icon
3. Enable the **MCP** toggle in the popup
4. The extension badge turns **blue** when connected to the server
> The extensions auto-reconnect every 5 seconds if the server is not running. You can enable MCP mode once and it persists across browser restarts.
### 5. Verify
In Claude Code, check the connection:
```
Use the video_status tool to check if the video extension is connected.
```
Claude should report that the extension is connected and ready.
## Usage
### MCP tools (via Claude Code)
| Tool | Description | Parameters |
|------|-------------|------------|
| `video_start` | Start screen recording | `resolution` (auto/4k/.../240p), `format` (mp4/webm/gif) |
| `video_stop` | Stop recording and save | — |
| `video_status` | Check extension connection | — |
| `screenshot_capture` | Take a screenshot | `format` (png/jpeg/webp/gif), `quality` (1-100), `resolution` (auto/720p/1080p/4k) |
| `screenshot_status` | Check extension connection | — |
| `system_info` | Display GPU/encoder capabilities | — |
All parameters are optional and have sensible defaults.
### Keyboard shortcuts
| Shortcut | Action |
|----------|--------|
| `Alt+Shift+V` | Start/stop video recording |
| `Ctrl+Shift+S` | Take a screenshot (toggle preview) |
### Standalone usage (without MCP)
Both extensions work without the MCP server for manual capture:
- **Quick Video**: click the extension icon → configure format/resolution/FPS → hit record
- **Quick Screenshot**: press `Ctrl+Shift+S` or click the extension icon
Without the MCP server, audio capture is limited to microphone only (no system audio on Linux).
## Important notes
### First recording requires a user gesture
Chrome requires a **user gesture** to authorize screen capture (`getDisplayMedia`). On the first recording of a browser session:
1. Claude (or you) triggers `video_start`
2. Chrome shows a picker dialog — **you must click** to select the tab/window/screen to share
3. Subsequent recordings reuse the permission until the service worker resets
This is a Chrome security requirement and cannot be bypassed.
### Screen capture permissions (Linux)
On Wayland, you may need to grant screen capture permissions through your compositor. With PipeWire-based compositors (GNOME, KDE), Chrome typically handles this via the portal API.
### System audio (Linux)
Chrome's `getDisplayMedia` does **not** expose system audio on Linux (unlike Windows/macOS where tab audio is available). The MCP server bridges this gap using PipeWire:
- Requires `pw-record` and `ffmpeg` (native) on the host
- The server captures system audio with `pw-record --target=0`
- After recording, the server merges video + audio with `ffmpeg`
- The extension popup shows a "System Audio (PipeWire)" option when the server detects PipeWire
This feature is under active development on the `feat/pipewire-audio` branch.
### File output
Recordings and screenshots are saved to Chrome's **Downloads** folder. The file path is returned to Claude via the MCP response, so Claude knows exactly where the file is.
## GPU and encoder detection
The MCP server auto-detects your GPU at startup and selects the best encoder:
| GPU | Encoder | Max capability |
|-----|---------|---------------|
| NVIDIA | `h264_nvenc` | 4K @ 60fps |
| Intel | `h264_qsv` / `h264_vaapi` | Depends on model |
| AMD | `h264_vaapi` | Radeon RX: 4K, others: 1080p |
| None / fallback | `libx264` (software) | 720p @ 30fps |
Use `system_info` in Claude Code to see what was detected on your system.
## Development
```bash
npm run build # build everything
npm run build:server # build MCP server only
npm run build:video # build video extension only
npm run build:screenshot # build screenshot extension only
```
For watch mode during development:
```bash
# In separate terminals:
cd packages/server && npm run dev # tsc --watch
cd packages/chrome-video && npm run watch # esbuild --watch
```
After rebuilding an extension, go to `chrome://extensions` and click the **reload** button on the extension card (or press `Ctrl+R` on the card).
### Project structure
```
quick-media-mcp/
├── packages/
│ ├── server/ # MCP server (published to npm)
│ │ ├── src/
│ │ │ ├── server.ts # MCP tools + WebSocket bridge
│ │ │ ├── cli.ts # CLI entry point (start/install/uninstall)
│ │ │ ├── capabilities.ts # GPU detection + resolution presets
│ │ │ └── install.ts # Claude Code settings management
│ │ └── package.json
│ ├── chrome-video/ # Quick Video extension
│ │ ├── src/
│ │ │ ├── background.ts # Service worker, state, MCP WebSocket
│ │ │ ├── offscreen.ts # MediaRecorder (offscreen document)
│ │ │ ├── converter.ts # FFmpeg WASM (WebM → MP4/GIF)
│ │ │ ├── popup.ts/html # Extension popup UI
│ │ │ └── manifest.json
│ │ └── package.json
│ └── chrome-screenshot/ # Quick Screenshot extension
│ ├── src/
│ │ ├── background.ts # Service worker, capture logic, MCP WebSocket
│ │ ├── content.ts # Overlay UI, area selection
│ │ ├── popup.ts/html # Extension popup UI
│ │ └── manifest.json
│ └── package.json
├── docker/ # Docker setup for headless recording
├── package.json # Workspace root
└── README.md
```
## Troubleshooting
### Extension badge doesn't turn blue
- Is the MCP server running? Check with `quick-media-mcp --help`
- Is MCP mode enabled in the extension popup?
- Check Chrome DevTools console (right-click extension icon → Inspect popup → Console) for WebSocket errors
- Verify port 9876 is not in use: `lsof -i :9876`
### "Permission denied" on first recording
- This is normal — Chrome requires you to click the capture picker dialog at least once per session
- Make sure the browser window is focused when the dialog appears
### Build fails with "Missing dependencies"
- Run `npm install` from the repo root (not from a package subfolder)
- npm workspaces hoists dependencies to the root `node_modules/`
### screenshot_capture returns an error
- Make sure a Chrome tab is active and focused
- The `<all_urls>` host permission must be granted (check `chrome://extensions`)
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues