Skip to main content
Glama
README.md
# vision-mcp

MCP server that gives **text-only AI coding agents** the ability to understand images and videos. Works with OpenCode, Claude Desktop, Claude Code, Cursor, VS Code, and any MCP-compatible client — including agents running on models without native vision.

```
agent (text-only) → vision-mcp → Gemini / Grok / OpenRouter → text description
```

## Why

Most coding agents run on strong text models (DeepSeek, Claude, etc.) that can't see images. When you paste a screenshot, a UI mockup, or an error screenshot, they say *"I can't view images"*. vision-mcp fixes that: it takes the file, sends it to a vision-capable model, and returns a plain-text description the agent can reason over.

## Features

- **2 tools**: `analyze_image` and `analyze_video`
- **3 backends, automatic fallback**: Gemini → Grok (xAI) → OpenRouter — tried in priority order, first success wins
- **Zero config file**: keys come from environment variables only
- **Image preprocessing**: auto-rotate (EXIF), downscale to ≤1024px, JPEG re-encode — small payloads, fast responses
- **Video support**: ffmpeg keyframe extraction (up to 8 frames) with timestamps
- **Typed & tested**: TypeScript, 21 unit/integration tests, MCP protocol verified over real stdio
- **No Python**: pure Node.js (sharp for images, ffmpeg binary for video)

## Requirements

- Node.js ≥ 18
- ffmpeg (for video analysis only; images work without it)
- At least **one** of these API keys:

| Backend | Env var | Get it |
|---|---|---|
| Gemini (default) | `GEMINI_API_KEY` | https://aistudio.google.com/app/apikey |
| Grok (xAI) | `XAI_API_KEY` | https://console.x.ai |
| OpenRouter | `OPENROUTER_API_KEY` | https://openrouter.ai/keys |

## Install

### npx from GitHub (recommended — no npm publish needed)

```bash
# Run directly (no install)
npx -y github:pongsakornp/vision-mcp
```

> npx clones the repo, installs deps, auto-builds via the `prepare` script, and runs the server over stdio.

### From source

```bash
git clone https://github.com/pongsakornp/vision-mcp.git
cd vision-mcp
pnpm install
pnpm run build
```

## Usage

### MCP client config

**OpenCode** (`opencode.jsonc`):

```jsonc
{
  "mcp": {
    "vision-mcp": {
      "type": "local",
      "command": ["npx", "-y", "github:pongsakornp/vision-mcp"],
      "environment": {
        "GEMINI_API_KEY": "AIza...",
        "XAI_API_KEY": "xai-...",
        "OPENROUTER_API_KEY": "sk-or-..."
      },
      "enabled": true
    }
  }
}
```

**Claude Desktop** (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "vision-mcp": {
      "command": "npx",
      "args": ["-y", "github:pongsakornp/vision-mcp"],
      "env": {
        "GEMINI_API_KEY": "AIza..."
      }
    }
  }
}
```

**VS Code / Cursor** (`.vscode/mcp.json` or workspace):

```json
{
  "servers": {
    "vision-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "github:pongsakornp/vision-mcp"],
      "environment": {
        "GEMINI_API_KEY": "AIza..."
      }
    }
  }
}
```

> Keys live in the MCP config — no shell profile edits needed. Keep the config out of git if it contains keys.

### CLI (for scripting / debugging)

```bash
# Spawn the server and talk JSON-RPC over stdio
GEMINI_API_KEY=AIza... node dist/index.js
```

## Tools

### `analyze_image(path, prompt?)`

Analyze an image file (png, jpg, jpeg, webp, bmp, gif, avif, tiff). Path can be absolute, relative, or `~/...`.

### `analyze_video(path, prompt?)`

Analyze a video (mp4, webm, mov, avi, mkv, flv, wmv, m4v). Extracts up to 8 evenly-spaced keyframes with ffmpeg, then describes the sequence.

## Configuration

| Env var | Default | Description |
|---|---|---|
| `GEMINI_API_KEY` | — | Gemini API key (tried first) |
| `XAI_API_KEY` | — | Grok/xAI API key (tried second) |
| `OPENROUTER_API_KEY` | — | OpenRouter key (tried last) |
| `VISION_GEMINI_MODEL` | `gemini-flash-latest` | Gemini model override |
| `VISION_GROK_MODEL` | `grok-4.5` | Grok model override |
| `VISION_OPENROUTER_MODEL` | `google/gemini-flash-latest` | OpenRouter model override |
| `VISION_TIMEOUT_MS` | `20000` | Per-backend request timeout |

## Backend behavior

- Only backends with keys configured are tried.
- Backends are tried **sequentially** in priority order (Gemini → Grok → OpenRouter); the first success wins and later backends are never called.
- If all fail, the error reports every backend's failure for diagnosis.

## Development

```bash
pnpm run build        # compile TypeScript → dist/
pnpm test             # run the 21 tests (vitest)
pnpm run typecheck    # tsc --noEmit
```

Test coverage: config parsing, backend fallback logic, path resolution, image preprocessing (sharp), video keyframe extraction (real ffmpeg), and the full MCP stdio protocol.

## License

MIT — see [LICENSE](LICENSE).

TDQS

A4.1/5.0

Scored across 2 tools

Disambiguation5/5

The two tools are clearly separated by media type: images versus videos. An agent can easily select the right tool based on the file extension or input format, with no meaningful overlap.

Naming Consistency5/5

Both tools follow the exact same verb_noun snake_case pattern: analyze_image and analyze_video. The naming is clean, predictable, and immediately signals what each tool does.

Tool Count4/5

Two tools is minimal but reasonable for a vision server focused on content description of static and moving media. Each tool earns its place, though the set feels slightly thin compared to broader vision-capable servers.

Completeness4/5

The core workflow of analyzing visual media is covered: images and videos both have a dedicated tool. Minor gaps exist, such as no URL-based input and no specialized vision capabilities like OCR or object detection, but these are not clearly implied by the server's stated scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues