Skip to main content
Glama
leaf76

lazy-media-mcp

by leaf76
README.md
# lazy-media-mcp

[![npm version](https://img.shields.io/npm/v/lazy-media-mcp)](https://www.npmjs.com/package/lazy-media-mcp)
[![license](https://img.shields.io/github/license/leaf76/lazy-media-mcp)](https://github.com/leaf76/lazy-media-mcp/blob/main/LICENSE)
[![Node.js](https://img.shields.io/node/v/lazy-media-mcp)](https://www.npmjs.com/package/lazy-media-mcp)

**Local Model Context Protocol (MCP) server** that **compresses images/videos** and **prepares media for AI vision agents**.

Designed for coding agents (Claude Code, Codex, Grok, and other MCP clients): returns **file paths only** (no inline base64), so large screenshots and demos stay within tool limits.

**Keywords:** MCP server, image compression, video compression, ffmpeg, sharp, AI vision prep, frame extraction, Claude, Codex.

## Why this exists

Large screenshots and long demos burn context and often fail tool limits. This server:

1. Shrinks images to a sensible size/quality
2. Turns videos into **frame packs** agents can actually open
3. Uses **JPEG by default** for widest agent compatibility

### WebP / WebM — do they help AI “read better”?

| Format | Role | Default here? |
|--------|------|----------------|
| **JPEG** | Best universal image input for local agents | **Yes** |
| **PNG** | Sharper for OCR / UI text / alpha | `ocr_text` profile |
| **WebP** | Smaller files when the host supports it | **Opt-in only** |
| **MP4** | Storage/sharing re-encode | Video compress default |
| **WebM** | Optional container | Opt-in via `video_compress` |

**Format does not improve model understanding by itself.** Resolution, blur, and compression artifacts matter more. Over-aggressive WebP/JPEG hurts OCR.

Local agents usually **do not natively watch WebM/MP4**. Prefer `prepare_for_ai` / `video_extract_frames` → JPEG paths.

## Requirements

- Node.js ≥ 20
- [ffmpeg](https://ffmpeg.org/) + ffprobe on `PATH` (video tools)

```bash
# macOS
brew install ffmpeg
```

## Install / run

### From npm

```bash
npx -y lazy-media-mcp
# or
npm install -g lazy-media-mcp
```

### From source

```bash
git clone https://github.com/leaf76/lazy-media-mcp.git
cd lazy-media-mcp
npm install
npm run build
npm test
node dist/cli.js   # stdio MCP
```

### MCP client config (example)

```json
{
  "mcpServers": {
    "lazy-media": {
      "command": "node",
      "args": ["/absolute/path/to/lazy-media-mcp/dist/cli.js"],
      "env": {
        "MEDIA_ALLOWED_ROOTS": "/Users/you,/Users/you/WorkSpace",
        "MEDIA_WORKDIR": "/Users/you/.cache/lazy-media-mcp/jobs"
      }
    }
  }
}
```

## Tools

| Tool | Purpose |
|------|---------|
| `media_inspect` | Metadata only |
| `image_compress` | Resize/compress image → workdir path |
| `video_compress` | Re-encode video (default MP4) |
| `video_extract_frames` | Extract frames for vision |
| `prepare_for_ai` | One-shot profile pipeline (**recommended**) |
| `media_cleanup` | Delete a job directory by `job_id` |

### `prepare_for_ai` profiles

| Profile | Behavior |
|---------|----------|
| `ai_vision` (default) | Image → JPEG ≤1536 edge; video → up to 10 JPEG frames |
| `ocr_text` | Prefer PNG / higher quality |
| `inline_small` | Smaller edges, fewer frames |
| `archive` | Higher quality + optional compressed MP4 |

## Environment

| Variable | Default |
|----------|---------|
| `MEDIA_ALLOWED_ROOTS` | `$HOME`, cwd, workdir |
| `MEDIA_WORKDIR` | `~/.cache/lazy-media-mcp/jobs` |
| `MEDIA_MAX_INPUT_BYTES` | 500MB |
| `MEDIA_MAX_OUTPUT_BYTES` | 200MB |
| `MEDIA_MAX_FRAMES` | 24 |
| `MEDIA_PROCESS_TIMEOUT_MS` | 120000 |
| `FFMPEG_BIN` / `FFPROBE_BIN` | `ffmpeg` / `ffprobe` |
| `LOG_LEVEL` | `info` |

## Security

- Path allowlist (realpath checks)
- Input/output size caps
- Process timeout
- ffmpeg/ffprobe invoked with argv arrays only (no shell interpolation)
- Outputs go to workdir; originals are not overwritten
- Cleanup only deletes direct children of workdir by `job_id`

## Typical agent flow

```text
1. prepare_for_ai({ path: "/path/to/demo.mp4", profile: "ai_vision" })
2. Read returned outputs[].path frame files in the next vision step
3. media_cleanup({ job_id }) when done (optional)
```

## Related

- [lazy-desktop-mcp](https://github.com/leaf76/lazy-desktop-mcp) — desktop computer-use MCP
- [lazy_mobile_mcp](https://github.com/leaf76/lazy_mobile_mcp) — Android/iOS mobile automation MCP
- [session-collab-mcp](https://github.com/leaf76/session-collab-mcp) — multi-session collaboration MCP

## License

[MIT](./LICENSE) © leaf76

TDQS

A3.5/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: AI preparation, metadata inspection, compression for images and videos separately, frame extraction, and cleanup. No overlapping functionality.

Naming Consistency4/5

Most tools follow a noun_verb pattern (media_inspect, image_compress, video_compress, video_extract_frames, media_cleanup), but prepare_for_ai breaks the pattern with a verb_preposition_noun structure. Still, all use snake_case and are readable.

Tool Count5/5

With 6 tools, the server is well-scoped for media processing and AI preparation. Each tool addresses a specific need without redundancy or excessive granularity.

Completeness4/5

Covers core operations (compression, inspection, frame extraction, cleanup, and one-shot AI prep). Missing a list_jobs tool to retrieve previous job IDs, but the main workflow is supported.

Maintenance

ActivityStale
ResponsivenessNo issues